stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

commit d474076e41d73412b8a06ecfcc031c8a92ac1685
parent b8e8125c6eaee35ff6799433920e960f2b100613
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 25 Apr 2024 16:34:52 +0200

Merge branch 'release_0.10'

Diffstat:
M.gitignore | 17++++++++++-------
AMakefile | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MREADME.md | 255++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Dcmake/CMakeLists.txt | 247-------------------------------------------------------------------------------
Dcmake/doc/CMakeLists.txt | 149-------------------------------------------------------------------------------
Dcmake/stardis-green-types/CMakeLists.txt | 53-----------------------------------------------------
Dcmake/stardis-prog-properties/CMakeLists.txt | 53-----------------------------------------------------
Aconfig.mk | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/stardis-input.5.in | 382+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/stardis-input.5.txt | 337-------------------------------------------------------------------------------
Ddoc/stardis-man.css | 96-------------------------------------------------------------------------------
Adoc/stardis-output.5 | 908+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/stardis-output.5.txt | 902-------------------------------------------------------------------------------
Adoc/stardis.1.in | 619+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/stardis.1.txt.in | 367-------------------------------------------------------------------------------
Amake.sh | 39+++++++++++++++++++++++++++++++++++++++
Msrc/stardis-app.c | 130++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/stardis-app.h | 18++++++++++++++----
Msrc/stardis-args.c | 460++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Dsrc/stardis-args.h | 140-------------------------------------------------------------------------------
Asrc/stardis-args.h.in | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-compute-probe-boundary.c | 994+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-compute.c | 550++++++++++++++++---------------------------------------------------------------
Msrc/stardis-compute.h | 15++++++++++-----
Msrc/stardis-description.c | 2+-
Msrc/stardis-description.h | 2+-
Asrc/stardis-extern-source.c | 239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-extern-source.h | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-fbound-prog.c | 2+-
Msrc/stardis-fbound-prog.h | 2+-
Msrc/stardis-fbound.c | 4++--
Msrc/stardis-fbound.h | 2+-
Msrc/stardis-fluid-prog.c | 4+++-
Msrc/stardis-fluid-prog.h | 2+-
Msrc/stardis-fluid.c | 17+++++++++--------
Msrc/stardis-fluid.h | 2+-
Msrc/stardis-green-types.h.in | 4++--
Msrc/stardis-hbound-prog.c | 2+-
Msrc/stardis-hbound-prog.h | 8+++++---
Msrc/stardis-hbound.c | 4++--
Msrc/stardis-hbound.h | 2+-
Msrc/stardis-hfbound-prog.c | 2+-
Msrc/stardis-hfbound-prog.h | 8+++++---
Msrc/stardis-hfbound.c | 4++--
Msrc/stardis-hfbound.h | 2+-
Msrc/stardis-intface.c | 31++++++++++++++++++++-----------
Msrc/stardis-intface.h | 19+++++++++++--------
Msrc/stardis-main.c | 45+++++++++++++++++++++++++++++++++------------
Msrc/stardis-output.c | 427++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/stardis-output.h | 48++++++++++++++++++++++++++++++------------------
Msrc/stardis-parsing.c | 476++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/stardis-parsing.h | 2+-
Msrc/stardis-prog-properties.h.in | 201++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/stardis-program.c | 2+-
Msrc/stardis-program.h | 5++---
Asrc/stardis-radiative-env.c | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-radiative-env.h | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-sfconnect-prog.c | 2+-
Msrc/stardis-sfconnect-prog.h | 8+++++---
Msrc/stardis-sfconnect.c | 2+-
Msrc/stardis-sfconnect.h | 2+-
Msrc/stardis-solid-prog.c | 3++-
Msrc/stardis-solid-prog.h | 2+-
Msrc/stardis-solid.c | 17+++++++++--------
Msrc/stardis-solid.h | 4++--
Msrc/stardis-ssconnect-prog.c | 2+-
Msrc/stardis-ssconnect-prog.h | 2+-
Msrc/stardis-ssconnect.c | 2+-
Msrc/stardis-ssconnect.h | 2+-
Msrc/stardis-tbound-prog.c | 2+-
Msrc/stardis-tbound-prog.h | 2+-
Msrc/stardis-tbound.c | 4++--
Msrc/stardis-tbound.h | 2+-
Msrc/stardis-version.h.in | 6+++---
Dstardis-green-types/stardis-green-types-config-version.cmake.in | 22----------------------
Dstardis-green-types/stardis-green-types-config.cmake | 28----------------------------
Dstardis-prog-properties/stardis-prog-properties-config-version.cmake.in | 22----------------------
Dstardis-prog-properties/stardis-prog-properties-config.cmake | 28----------------------------
78 files changed, 5849 insertions(+), 3611 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,12 +1,15 @@ .gitignore -CMakeCache.txt -CMakeFiles -Makefile -tmp [Bb]uild* *.sw[po] -*.[ao] +*.[aod] *~ tags -*.orig - +.config +src/stardis-args.h +src/stardis-default.h +src/stardis-green-types.h +src/stardis-prog-properties.h +src/stardis-version.h +stardis +doc/stardis.1 +doc/stardis-input.5 diff --git a/Makefile b/Makefile @@ -0,0 +1,205 @@ +# 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 + +MPI_DEF = -DSTARDIS_ENABLE_MPI + +# Default target +all: build_executable man + +################################################################################ +# Program building +################################################################################ +SRC =\ + src/stardis-app.c\ + src/stardis-args.c\ + src/stardis-compute.c\ + src/stardis-compute-probe-boundary.c\ + src/stardis-description.c\ + src/stardis-extern-source.c\ + src/stardis-fluid.c\ + src/stardis-fluid-prog.c\ + src/stardis-fbound.c\ + src/stardis-fbound-prog.c\ + src/stardis-hbound.c\ + src/stardis-hbound-prog.c\ + src/stardis-hfbound.c\ + src/stardis-hfbound-prog.c\ + src/stardis-intface.c\ + src/stardis-main.c\ + src/stardis-output.c\ + src/stardis-parsing.c\ + src/stardis-program.c\ + src/stardis-radiative-env.c\ + src/stardis-sfconnect.c\ + src/stardis-sfconnect-prog.c\ + src/stardis-ssconnect.c\ + src/stardis-ssconnect-prog.c\ + src/stardis-solid.c\ + src/stardis-solid-prog.c\ + src/stardis-tbound.c\ + src/stardis-tbound-prog.c + +# Headers to configure +HDR=\ + src/stardis-args.h\ + src/stardis-default.h\ + src/stardis-green-types.h\ + src/stardis-prog-properties.h\ + src/stardis-version.h + +OBJ = $(SRC:.c=.o) +DEP = $(SRC:.c=.d) + +build_executable: .config $(HDR) $(DEP) + @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) stardis + +$(DEP) $(OBJ): config.mk + +stardis: $(OBJ) + $(CC) $(CFLAGS) $(DPDC_CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(DPDC_LIBS) + +.config: config.mk + @if [ "$(DISTRIB_PARALLELISM)" = "MPI" ]; then \ + if ! $(PKG_CONFIG) --atleast-version $(MPI_VERSION) $(MPI_PC); then \ + echo "$(MPI_PC) $(MPI_VERSION) not found" >&2; exit 1; fi; fi + @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ + echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d; then \ + echo "s3d $(S3D_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SDIS_VERSION) sdis; then \ + echo "sdis $(SDIS_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SENC3D_VERSION) senc3d; then \ + echo "senc3d $(SENC3D_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SG3D_VERSION) sg3d; then \ + echo "sg3d $(SG3D_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ + echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi + @if ! $(PKG_CONFIG) --atleast-version $(SSTL_VERSION) sstl; then \ + echo "sstl $(SSTL_VERSION) not found" >&2; exit 1; fi + @echo "config done" > $@ + +src/stardis-default.h: config.mk src/stardis-default.h.in + sed -e 's/@STARDIS_ARGS_DEFAULT_TRAD@/$(STARDIS_ARGS_DEFAULT_TRAD)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_TRAD_REFERENCE@/$(STARDIS_ARGS_DEFAULT_TRAD_REFERENCE)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_COMPUTE_TIME@/$(STARDIS_ARGS_DEFAULT_COMPUTE_TIME)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_PICARD_ORDER@/$(STARDIS_ARGS_DEFAULT_PICARD_ORDER)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_FOV@/$(STARDIS_ARGS_DEFAULT_RENDERING_FOV)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT@/$(STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH@/$(STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT@/$(STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_POS@/$(STARDIS_ARGS_DEFAULT_RENDERING_POS)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_SPP@/$(STARDIS_ARGS_DEFAULT_RENDERING_SPP)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_TGT@/$(STARDIS_ARGS_DEFAULT_RENDERING_TGT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_TIME@/$(STARDIS_ARGS_DEFAULT_RENDERING_TIME)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_UP@/$(STARDIS_ARGS_DEFAULT_RENDERING_UP)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_SAMPLES_COUNT@/$(STARDIS_ARGS_DEFAULT_SAMPLES_COUNT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_SCALE_FACTOR@/$(STARDIS_ARGS_DEFAULT_SCALE_FACTOR)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL@/$(STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL)/' \ + $@.in > $@ + +src/stardis-args.h: config.mk src/stardis-args.h.in + sed -e 's/@STARDIS_MAX_NAME_LENGTH@/$(STARDIS_MAX_NAME_LENGTH)/' \ + $@.in > $@ + +src/stardis-version.h: config.mk src/stardis-version.h.in + sed -e 's/@STARDIS_APP_VERSION_MAJOR@/$(VERSION_MAJOR)/' \ + -e 's/@STARDIS_APP_VERSION_MINOR@/$(VERSION_MINOR)/' \ + -e 's/@STARDIS_APP_VERSION_PATCH@/$(VERSION_PATCH)/' \ + $@.in > $@ + +src/stardis-green-types.h: config.mk src/stardis-green-types.h.in + sed -e 's/@STARDIS_GREEN_TYPES_VERSION@/$(GREEN_TYPES_VERSION)/' \ + -e "s/@STARDIS_MAX_NAME_LENGTH@/$$(($(STARDIS_MAX_NAME_LENGTH)-1))/" \ + $@.in > $@ + +src/stardis-prog-properties.h: config.mk src/stardis-prog-properties.h.in + sed -e 's/@STARDIS_PROG_PROPERTIES_VERSION@/$(PROG_PROPERTIES_VERSION)/' \ + $@.in > $@ + +.SUFFIXES: .c .d .o +.c.d: + @$(CC) $(CFLAGS) $(DPDC_CFLAGS) $($(DISTRIB_PARALLELISM)_DEF) -MM -MT \ + "$(@:.d=.o) $@" $< -MF $@ + +.c.o: + $(CC) $(CFLAGS) $(DPDC_CFLAGS) $($(DISTRIB_PARALLELISM)_DEF) -c $< -o $@ + +################################################################################ +# Man pages +################################################################################ +man: doc/stardis.1 doc/stardis-input.5 + +doc/stardis.1: doc/stardis.1.in + sed -e 's/@STARDIS_ARGS_DEFAULT_COMPUTE_TIME@/$(STARDIS_ARGS_DEFAULT_COMPUTE_TIME)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_PICARD_ORDER@/$(STARDIS_ARGS_DEFAULT_PICARD_ORDER)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_FOV@/$(STARDIS_ARGS_DEFAULT_RENDERING_FOV)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT@/$(STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH@/$(STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT@/$(STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_POS@/$(STARDIS_ARGS_DEFAULT_RENDERING_POS)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_SPP@/$(STARDIS_ARGS_DEFAULT_RENDERING_SPP)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_TGT@/$(STARDIS_ARGS_DEFAULT_RENDERING_TGT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_TIME@/$(STARDIS_ARGS_DEFAULT_RENDERING_TIME)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_RENDERING_UP@/$(STARDIS_ARGS_DEFAULT_RENDERING_UP)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_SAMPLES_COUNT@/$(STARDIS_ARGS_DEFAULT_SAMPLES_COUNT)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_SCALE_FACTOR@/$(STARDIS_ARGS_DEFAULT_SCALE_FACTOR)/' \ + -e 's/@STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL@/$(STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL)/' \ + $@.in > $@ + +doc/stardis-input.5: doc/stardis-input.5.in + sed -e "s/@STARDIS_MAX_NAME_LENGTH@/$$(($(STARDIS_MAX_NAME_LENGTH)-1))/" \ + $@.in > $@ + +################################################################################ +# Installation +################################################################################ +install: all + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/bin" stardis + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include/stardis" src/stardis-green-types.h + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include/stardis" src/stardis-prog-properties.h + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/stardis" COPYING README.md + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man1" doc/stardis.1 + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/stardis-input.5 + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/stardis-output.5 + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)/bin/stardis" + rm -f "$(DESTDIR)$(PREFIX)/include/stardis/stardis-green-types.h" + rm -f "$(DESTDIR)$(PREFIX)/include/stardis/stardis-prog-properties.h" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/stardis/COPYING" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/stardis/README.md" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/stardis.1" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/stardis-input.5" + rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/stardis-output.5" + +################################################################################ +# Miscellaneous targets +################################################################################ +clean: + rm -f $(HDR) $(OBJ) .config stardis doc/stardis.1 doc/stardis-input.5 + +distclean: clean + rm -f $(DEP) + +lint: man + shellcheck -o all make.sh + mandoc -Tlint -Wall doc/stardis.1 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/stardis-input.5 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/stardis-output.5 || [ $$? -le 1 ] diff --git a/README.md b/README.md @@ -4,83 +4,199 @@ Stardis is a software dedicated to the resolution of coupled convective-conductive-radiative thermal problems in 3D environments. -It is based on [stardis-solver](https://gitlab.com/meso-star/stardis-solver) -and exposes some of the main features of the solver in an easy to use way. -Using stardis is a practical way of carrying out thermal studies on CAD +It is based on +[Stardis Solver](https://gitlab.com/meso-star/stardis-solver) and +exposes some of the main features of the solver in an easy to use way. +Using Stardis is a practical way of carrying out thermal studies on CAD models which can be exported from Salomé or other similar software. -## How to build - -Stardis relies on the [CMake](http://www.cmake.org) and the -[RCMake](https://gitlab.com/vaplv/rcmake/) package to build. -It also depends on the -[RSys](https://gitlab.com/vaplv/rsys/), -[star-3d](https://gitlab.com/meso-star/star-3d/), -[star-enclosures-3d](https://gitlab.com/meso-star/star-enclosures-3d/), -[star-geometry-3d](https://gitlab.com/meso-star/star-geometry-3d/), -[star-stl](https://gitlab.com/meso-star/star-stl) and -[stardis-solver](https://gitlab.com/meso-star/stardis-solver) libraries -as well as on the [OpenMP](http://www.openmp.org) 2.0 specification to -parallelize its computations. It may depend on -[OpenMPI](https://www.open-mpi.org/) 2.0 if distributed memory parallelism -is enabled via the `ENABLE_MPI` variable of the CMake file. - -First ensure that CMake and a C compiler are installed on your system. -Then install the RCMake package as well as all 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. +## Requirements + +- C compiler +- POSIX make +- pkg-config +- Message Passing Interface (optional) +- [mandoc](https://mandoc.bsd.lv) +- [RSys](https://gitlab.com/vaplv/rsys) +- [Star 3D](https://gitlab.com/meso-star/star-3d) +- [Stardis Solver](https://gitlab.com/meso-star/stardis-solver) +- [Star Enclosure 3D](https://gitlab.com/meso-star/star-enclosures-3d) +- [Star Geometry 3D](https://gitlab.com/meso-star/star-geometry-3d) +- [Star SamPling](https://gitlab.com/meso-star/star-sp) +- [Star StL](https://gitlab.com/meso-star/star-stl) + +## Installation + +Edit config.mk as needed, then run: + + make clean install ## Release notes +### Version 0.10 + +#### New conduction algorithm + +Addition of a new algorithm for sampling a potentially unsteady +conductive path. The new `-a` option lets you select the algorithm to be +used, i.e. either the sphere delta algorithm used until now (which is +still the default algorithm), or the new Walk on Sphere algorithm (WoS). + +This new algorithm samples an unbiased diffuse trajectory in a solid +with Dirichlet boundary conditions, unbiased with respect to what +numerical accuracy can account for. Its coupling with other boundary or +connection conditions behaves as with the delta sphere algorithm, i.e. +the solution is exact when the length of the trajectory used as a +first-order approximation tends towards 0. + +Currently, when using WoS, the initial condition must be constant for +the solid. The power density is also taken into account, but cannot +vary in time and space. + +#### External spherical source + +An external spherical source can be added to the scene using the new +stardis-input keyword `SPHERICAL_SOURCE`. Once defined, it is considered +as a new boundary condition whose contribution is calculated at the +solid/fluid interfaces in the form of an external net flux. + +The external net flux is calculated by evaluating the direct and diffuse +part of the incident flux due to the external source. The diffuse part +of the flux manages not only the radiation from the external source that +reaches the interface after one or more reflections, but also the +external radiation scattered in the environment, here simply represented +by a `diffuse-radiance` parameter. + +An external spherical source is defined by its position, radius, power +and diffuse radiance. While the radius is constant, all other parameters +can be programmed using the `SPHERICAL_SOURCE_PROG` keyword. In doing +so, the user can provide a shared object as input, enabling him to +define a time-dependent power and position, and a diffuse radiance that +also depends on the direction along which the sampled trajectory reaches +the environment. + +#### Making surface radiative properties source-dependent + +Emissivity and specular fraction can now be varied according to the type +of source (internal or external). This is only possible using +programmable properties (`H_BOUNDARY_FOR_FLUID_PROG`, +`HF_BOUNDARY_FOR_SOLID_PROG` and `SOLID_FLUID_PROG`). Properties are +otherwise assumed to be the same for all sources. + +#### Make the radiative environment programmable + +Addition of the `TRAD_PROG` keyword, which allows the user to define a +radiative temperature and a reference radiative temperature that depend +on a direction. + +#### Parallelize the resolutions of multiple boundary probes + +Add the `-L` option to calculate multiple boundary probes at once. +Stardis will then parallelize the probe list calculations, rather than +each probe calculation one after the other. Using this option is +therefore more advantageous in terms of load distribution when the +number of boundary probes to be evaluated is large compared to the cost +of calculating a single probe (option `-P`). + +#### Allow relative temperatures + +Allow to perform calculations relative to a given temperature T. In this +case, the temperatures managed by Stardis would be relative to T and +could therefore be negative, since they would express a deviation from +T. It should be noted that reference temperatures must always be +positive, i.e. expressed in the absolute domain. Finally, we emphasize +that relative calculations only make sense in linear situations, i.e. +negative temperatures are not valid for systems with non-linear +radiative exchanges (i.e. option `-o` whose argument is greater than +one). + +This is a file format break that users *must* take into account. Until +now, negative temperatures were considered unknown, whereas they are now +valid. For example, an interface with a negative temperature could be +considered adiabatic, whereas it is now a Dirichlet boundary condition. +In other words, the same data could define completely different systems +before and after this version. + +#### Use POSIX make as a build system + +The build procedure is now written in POSIX make instead of CMake. +In addition to the features already provided by its CMake alternative, +the Makefile supports the use of static libraries and provides an +uninstall target. In any case, the main motivation behind its writing is +to use a good old well-established standard with simple features, +available on all UNIX systems, thus simplifying its portability and +support while being much 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. + ### Version 0.9 #### Programmable properties -Until now, physical properties as well as boundary and connection conditions -were constant in time and space. In this version, they can be programmed, i.e. -they are variables returned by functions implemented in user-defined libraries -and submitted as dynamically loaded input libraries when Stardis starts. User -libraries must also provide create/release functions that are invoked at -start-up to allow users to load their data and build the internal data -structures required by their libraries at run-time. +Until now, physical properties as well as boundary and connection +conditions were constant in time and space. In this version, they can be +programmed, i.e. they are variables returned by functions implemented +in user-defined libraries and submitted as dynamically loaded input +libraries when Stardis starts. User libraries must also provide +create/release functions that are invoked at start-up to allow users to +load their data and build the internal data structures required by their +libraries at run-time. The `stardis-input` file format has been updated to provide a set of new `_PROG` suffixed keywords used to define these programmed properties and -conditions (e.g. `T_BOUNDARY_FOR_SOLID_PROG` or `H_BOUNDARY_FOR_FLUID_PROG`) +conditions (e.g. `T_BOUNDARY_FOR_SOLID_PROG` or +`H_BOUNDARY_FOR_FLUID_PROG`) #### Miscellaneous -- Addition of the keyword `HF_BOUNDARY_FOR_SOLID` which allows to impose a flux - on a boundary with another condition. For example, a net flux can be defined - in addition to a convective exchange and a radiative transfer. -- Correct the definition of a net flux as a boundary condition: it might not be - defined on the right side of the interface. -- Correct the "subpath type" data of the output paths: as we attach the segment - type to the vertices, we need to locate the type changes along the path on - zero length segments, otherwise the colouring will show a misleading colour - gradient. -- Replace the Mersenne Twister random number generator with Threefry: the - former is much less efficient at rejecting random numbers than the latter, - which is designed for this purpose, a feature on which parallel random number - generations depend heavily +- Addition of the keyword `HF_BOUNDARY_FOR_SOLID` which allows to impose + a flux on a boundary with another condition. For example, a net flux + can be defined in addition to a convective exchange and a radiative + transfer. +- Correct the definition of a net flux as a boundary condition: it might + not be defined on the right side of the interface. +- Correct the "subpath type" data of the output paths: as we attach the + segment type to the vertices, we need to locate the type changes along + the path on zero length segments, otherwise the colouring will show a + misleading colour gradient. +- Replace the Mersenne Twister random number generator with Threefry: + the former is much less efficient at rejecting random numbers than the + latter, which is designed for this purpose, a feature on which + parallel random number generations depend heavily ### Version 0.8 -- Add a new option to support non-linear radiative transfer computations. -- Changes in input file's format to support non-linear radiative transfer by - adding reference temperatures on interfaces. -- Add optional support for MPI (must be enabled at compile time, default is OFF). +- Add a new option to support non-linear radiative transfer + computations. +- Changes in input file's format to support non-linear radiative + transfer by adding reference temperatures on interfaces. +- Add optional support for MPI (must be enabled at compile time, default + is OFF). - Change random number generator type to use Threefry. -- Change the format of binary Green files. A new public header file is now - installed that describes all types involved in binary Green files. +- Change the format of binary Green files. A new public header file is + now installed that describes all types involved in binary Green files. - Fix a crash on an exit-on-error execution path. - Fix parsing of command-line options. ### Version 0.7.2 -Fix the binary file format of the green function: the fileformat has been -updated without incrementing the version of the serialised data. +Fix the binary file format of the green function: the fileformat has +been updated without incrementing the version of the serialised data. ### Version 0.7.1 @@ -88,10 +204,10 @@ Fix debug build. ### Version 0.7 -- Remove the boundary condition `T_BOUNDARY_FOR_FLUID`: it was exactly the same - than `H_BOUNDARY_FOR_FLUID` that should now be used instead. -- Sets the required version of Star-SampPling to 0.12. This version fixes - compilation errors with gcc 11 but introduces API breaks. +- Remove the boundary condition `T_BOUNDARY_FOR_FLUID`: it was exactly + the same than `H_BOUNDARY_FOR_FLUID` that should now be used instead. +- Sets the required version of Star-SampPling to 0.12. This version + fixes compilation errors with gcc 11 but introduces API breaks. ### Version 0.6 @@ -126,14 +242,15 @@ Fix debug build. ### Version 0.3.2 - Add the `solve_probe_boundary` feature. The `solve_probe_boundary` VS - `solve_probe` selection is automated according the probe-geometry distance. - `solve_probe_boundary` is called for probe points closer than 2.1 delta - from geometry. + `solve_probe` selection is automated according the probe-geometry + distance. `solve_probe_boundary` is called for probe points closer + than 2.1 delta from geometry. - Add flux boundary conditions. ### Version 0.3.1 -Add radiative transfer computations. To achieve this, media gain 2 new parameters: +Add radiative transfer computations. To achieve this, media gain 2 new +parameters: - emissivity; - `specular_fraction`. @@ -142,10 +259,11 @@ Add radiative transfer computations. To achieve this, media gain 2 new parameter - Upgrade stardis-solver to v0.3. - Add volumic power sources on solids; -- Allow to use the `fp_to_meter` parameter of the stardis-solver solve function; +- Allow to use the `fp_to_meter` parameter of the stardis-solver solve + function; - Add a dump geometry feature. It outputs the geometry as it is sent to - stardis-solver in VTK format, together with the front and back media and - boundary conditions information. + stardis-solver in VTK format, together with the front and back media + and boundary conditions information. ### Version 0.1 @@ -155,8 +273,9 @@ Add radiative transfer computations. To achieve this, media gain 2 new parameter ## License -Copyright (C) 2018-2023 |Méso|Star> (<contact@meso-star.com>). Stardis is free -software released under the GPL v3+ license: GNU GPL version 3 or later. You -are welcome to redistribute it under certain conditions; refer to the COPYING -file for details. +Copyright (C) 2018-2024 |Méso|Star> (<contact@meso-star.com>) + +Stardis is free software released under the GPL v3+ license: GNU GPL +version 3 or later. You are welcome to redistribute it under certain +conditions; refer to the COPYING file for details. diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -1,247 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.0) -project(stardis C) - -set(SDIS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src) -set(SDIS_SGT_DIR ${PROJECT_SOURCE_DIR}/../stardis-green-types) -set(SDIS_PRG_DIR ${PROJECT_SOURCE_DIR}/../stardis-prog-properties) - - -option(ENABLE_MPI - "Enable the support of distributed parallelism \ -using the Message Passing Interface specification." OFF) - -if(CMAKE_HOST_UNIX) - set(STARDIS_DOC "TROFF" CACHE STRING - "Type of documentation to generate and install.") -else() - set(STARDIS_DOC "HTML" CACHE STRING - "Type of documentation to generate and install.") -endif() - -set_property(CACHE STARDIS_DOC PROPERTY STRINGS - "HTML" - "TROFF" - "TROFF & HTML" - "NONE") - -############################################################################### -# Generate files -############################################################################### -set(STARDIS_ARGS_DEFAULT_TRAD "300") -set(STARDIS_ARGS_DEFAULT_TRAD_REFERENCE "300") -set(STARDIS_ARGS_DEFAULT_COMPUTE_TIME "INF") -set(STARDIS_ARGS_DEFAULT_PICARD_ORDER "1") -set(STARDIS_ARGS_DEFAULT_RENDERING_FOV "70") # degrees -set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT "480") -set(STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH "640") -set(STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT "HT") # VTK or HT -set(STARDIS_ARGS_DEFAULT_RENDERING_POS "1, 1, 1") -set(STARDIS_ARGS_DEFAULT_RENDERING_SPP "4") -set(STARDIS_ARGS_DEFAULT_RENDERING_TGT "0, 0, 0") -set(STARDIS_ARGS_DEFAULT_RENDERING_TIME "INF, INF") -set(STARDIS_ARGS_DEFAULT_RENDERING_UP "0, 0, 1") -set(STARDIS_ARGS_DEFAULT_SAMPLES_COUNT "10000") -set(STARDIS_ARGS_DEFAULT_SCALE_FACTOR "1") -set(STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL "1") - -configure_file(${SDIS_SOURCE_DIR}/../doc/stardis.1.txt.in - ${CMAKE_CURRENT_BINARY_DIR}/doc/stardis.1.txt @ONLY) - -set(SDIS_VERSION_MAJOR 0) -set(SDIS_VERSION_MINOR 9) -set(SDIS_VERSION_PATCH 0) -set(SDIS_VERSION ${SDIS_VERSION_MAJOR}.${SDIS_VERSION_MINOR}.${SDIS_VERSION_PATCH}) - -configure_file(${SDIS_SOURCE_DIR}/stardis-default.h.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-default.h @ONLY) - -configure_file(${SDIS_SOURCE_DIR}/stardis-version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-version.h @ONLY) - -set(STARDIS_GREEN_TYPES_VERSION "4") -set(STARDIS_PROG_PROPERTIES_VERSION "1") - -configure_file(${SDIS_SOURCE_DIR}/stardis-green-types.h.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types/stardis-green-types.h @ONLY) -configure_file(${SDIS_SOURCE_DIR}/stardis-prog-properties.h.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties/stardis-prog-properties.h @ONLY) - -configure_file(${SDIS_SGT_DIR}/stardis-green-types-config-version.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types/stardis-green-types-config-version.cmake @ONLY) -configure_file(${SDIS_PRG_DIR}/stardis-prog-properties-config-version.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties/stardis-prog-properties-config-version.cmake @ONLY) - -############################################################################### -# Check dependencies -############################################################################### -find_package(RCMake 0.4 REQUIRED) -find_package(RSys 0.12 REQUIRED) -find_package(StarGeom3D 0.1 REQUIRED) -find_package(Star3D 0.8 REQUIRED) -find_package(StarEnc3D 0.5 REQUIRED) -find_package(Stardis 0.14 REQUIRED) -find_package(StarSTL 0.3 REQUIRED) -find_package(StarSP 0.13 REQUIRED) -if(MSVC) - find_package(MuslGetopt REQUIRED) -endif() -if(ENABLE_MPI) - find_package(MPI 2 REQUIRED) - set(CMAKE_C_COMPILER ${MPI_C_COMPILER}) - include_directories(${MPI_INCLUDE_PATH}) -endif() - - -include_directories( - ${RSys_INCLUDE_DIR} - ${Star3D_INCLUDE_DIR} - ${StarGeom3D_INCLUDE_DIR} - ${StarEnc3D_INCLUDE_DIR} - ${Stardis_INCLUDE_DIR} - ${StarSTL_INCLUDE_DIR} - ${StarSP_INCLUDE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types - ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties) -if(MSVC) - include_directories(${MuslGetopt_INCLUDE_DIR}) -endif() - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) -include(rcmake) -include(rcmake_runtime) - -if(CMAKE_COMPILER_IS_GNUCC) - rcmake_append_runtime_dirs(_runtime_dirs - RSys Stardis Star3D StarGeom3D StarEnc3D StarSTL StarSP) -endif() -if(MSVC) - rcmake_append_runtime_dirs(_runtime_dirs - RSys MuslGetopt Stardis Star3D StarGeom3D StarEnc3D StarSTL StarSP) -endif() - -############################################################################### -# Build subprojects -############################################################################### -if(NOT STARDIS_DOC STREQUAL "NONE") - add_subdirectory(doc) -endif() - -add_subdirectory(stardis-green-types) -add_subdirectory(stardis-prog-properties) - -############################################################################### -# Configure and define targets -############################################################################### -set(SDIS_FILES_SRC - stardis-app.c - stardis-args.c - stardis-compute.c - stardis-description.c - stardis-fluid.c - stardis-fluid-prog.c - stardis-fbound.c - stardis-fbound-prog.c - stardis-hbound.c - stardis-hbound-prog.c - stardis-hfbound.c - stardis-hfbound-prog.c - stardis-intface.c - stardis-main.c - stardis-output.c - stardis-parsing.c - stardis-program.c - stardis-sfconnect.c - stardis-sfconnect-prog.c - stardis-ssconnect.c - stardis-ssconnect-prog.c - stardis-solid.c - stardis-solid-prog.c - stardis-tbound.c - stardis-tbound-prog.c) - -set(SDIS_FILES_INC - stardis-app.h - stardis-args.h - stardis-compute.h - stardis-description.h - stardis-default.h.in - stardis-fluid.h - stardis-fluid-prog.h - stardis-fbound.h - stardis-fbound-prog.h - stardis-green-types.h.in - stardis-hbound.h - stardis-hbound-prog.h - stardis-hfbound.h - stardis-hfbound-prog.h - stardis-intface.h - stardis-output.h - stardis-parsing.h - stardis-program.h - stardis-prog-properties.h.in - stardis-sfconnect.h - stardis-sfconnect-prog.h - stardis-ssconnect.h - stardis-ssconnect-prog.h - stardis-solid.h - stardis-solid-prog.h - stardis-tbound.h - stardis-tbound-prog.h - stardis-version.h.in) - -set(SDIS_FILES_DOC COPYING README.md) - -# Prepend each file by `SDIS_SOURCE_DIR' -rcmake_prepend_path(SDIS_FILES_SRC ${SDIS_SOURCE_DIR}) -rcmake_prepend_path(SDIS_FILES_INC ${SDIS_SOURCE_DIR}) -rcmake_prepend_path(SDIS_FILES_DOC ${PROJECT_SOURCE_DIR}/../) - -add_executable(stardis - ${SDIS_FILES_SRC} - ${SDIS_FILES_INC}) - -if(CMAKE_COMPILER_IS_GNUCC) - set(MATH_LIB m) -elseif(MSVC) - set(GETOPT_LIB MuslGetopt) -endif() - -set_target_properties(stardis - PROPERTIES VERSION ${SDIS_VERSION}) - -target_link_libraries(stardis - Stardis Star3D StarGeom3D StarEnc3D StarSTL StarSP RSys ${GETOPT_LIB} ${MATH_LIB}) - -if(ENABLE_MPI) - set_target_properties(stardis PROPERTIES COMPILE_DEFINITIONS "STARDIS_ENABLE_MPI") -endif() - -############################################################################### -# Define output & install directories -############################################################################### -install(TARGETS stardis - ARCHIVE DESTINATION bin - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin) - -install(FILES ${SDIS_FILES_DOC} DESTINATION share/doc/stardis) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/stardis-version.h - DESTINATION include/stardis) - -rcmake_copy_runtime_libraries(stardis) diff --git a/cmake/doc/CMakeLists.txt b/cmake/doc/CMakeLists.txt @@ -1,149 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.0) - -string(REGEX MATCH ".*HTML.*" _html ${STARDIS_DOC}) -string(REGEX MATCH ".*ROFF.*" _roff ${STARDIS_DOC}) - -set(STARDIS_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 stardis 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 stardis man pages cannot be generated.") - endif() -endif() - -################################################################################ -# Copy doc files -################################################################################ -set(MAN_NAMES - stardis-input.5 - stardis-output.5) - -if(_roff OR _html) - set(MAN_FILES) - foreach(_name IN LISTS MAN_NAMES) - set(_src ${STARDIS_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 stardis.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=${STARDIS_DOC_DIR} - --theme=stardis-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} ${STARDIS_DOC_DIR}/stardis-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/stardis/html) - install(FILES ${MAN5_FILES} DESTINATION share/doc/stardis/html) -endif() - diff --git a/cmake/stardis-green-types/CMakeLists.txt b/cmake/stardis-green-types/CMakeLists.txt @@ -1,53 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.0) - -set(STARDIS_SGT_DIR ${PROJECT_SOURCE_DIR}/../stardis-green-types) - -################################################################################ -# Copy stardis-green-types CMake files -################################################################################ -set(SGT_NAMES - stardis-green-types-config) - -set(SGT_FILES) -foreach(_name IN LISTS SGT_NAMES) - set(_src ${STARDIS_SGT_DIR}/${_name}.cmake) - set(_dst ${CMAKE_CURRENT_BINARY_DIR}/${_name}.cmake) - add_custom_command( - OUTPUT ${_dst} - COMMAND ${CMAKE_COMMAND} -E copy ${_src} ${_dst} - DEPENDS ${_src} - COMMENT "Copy the CMake file ${_src}" - VERBATIM) - list(APPEND SGT_FILES ${_dst}) -endforeach() -add_custom_target(sgt-cmake ALL DEPENDS ${SGT_FILES}) - -################################################################################ -# Install stardis-green-types CMake Files -################################################################################ -list(APPEND SGT_FILES ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types-config-version.cmake) - -install(FILES ${SGT_FILES} - DESTINATION lib/cmake/stardis-green-types) - -################################################################################ -# Install stardis-green-types header Files -################################################################################ -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types.h - DESTINATION include/stardis/) diff --git a/cmake/stardis-prog-properties/CMakeLists.txt b/cmake/stardis-prog-properties/CMakeLists.txt @@ -1,53 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.0) - -set(STARDIS_SPROG_DIR ${PROJECT_SOURCE_DIR}/../stardis-prog-properties) - -################################################################################ -# Copy stardis-prog-properties CMake files -################################################################################ -set(SPROG_NAMES - stardis-prog-properties-config) - -set(SPROG_FILES) -foreach(_name IN LISTS SPROG_NAMES) - set(_src ${STARDIS_SPROG_DIR}/${_name}.cmake) - set(_dst ${CMAKE_CURRENT_BINARY_DIR}/${_name}.cmake) - add_custom_command( - OUTPUT ${_dst} - COMMAND ${CMAKE_COMMAND} -E copy ${_src} ${_dst} - DEPENDS ${_src} - COMMENT "Copy the CMake file ${_src}" - VERBATIM) - list(APPEND SPROG_FILES ${_dst}) -endforeach() -add_custom_target(stardis-prog-cmake ALL DEPENDS ${SPROG_FILES}) - -################################################################################ -# Install stardis-prog-properties CMake Files -################################################################################ -list(APPEND SPROG_FILES ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties-config-version.cmake) - -install(FILES ${SPROG_FILES} - DESTINATION lib/cmake/stardis-prog-properties) - -################################################################################ -# Install stardis-prog-properties header Files -################################################################################ -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties.h - DESTINATION include/stardis/) diff --git a/config.mk b/config.mk @@ -0,0 +1,157 @@ +VERSION_MAJOR = 0 +VERSION_MINOR = 10 +VERSION_PATCH = 0 +VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) +PREFIX = /usr/local + +GREEN_TYPES_VERSION = 4 +PROG_PROPERTIES_VERSION = 2 + +LIB_TYPE = SHARED +#LIB_TYPE = STATIC + +BUILD_TYPE = RELEASE +#BUILD_TYPE = DEBUG + +# Defines whether distributed parallelism is supported. Any value other +# than MPI disables its supports. So, simply comment the macro to +# deactivate it. +DISTRIB_PARALLELISM = MPI + +# MPI pkg-config file +MPI_PC = ompi + +################################################################################ +# Configuration values +################################################################################ +STARDIS_ARGS_DEFAULT_TRAD = 300 +STARDIS_ARGS_DEFAULT_TRAD_REFERENCE = 300 +STARDIS_ARGS_DEFAULT_COMPUTE_TIME = INF +STARDIS_ARGS_DEFAULT_PICARD_ORDER = 1 +STARDIS_ARGS_DEFAULT_RENDERING_FOV = 70# Degrees +STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT = 480 +STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH = 640 +STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT = HT +#STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT = VTK +STARDIS_ARGS_DEFAULT_RENDERING_POS = 1,1,1 +STARDIS_ARGS_DEFAULT_RENDERING_SPP = 4 +STARDIS_ARGS_DEFAULT_RENDERING_TGT = 0,0,0 +STARDIS_ARGS_DEFAULT_RENDERING_TIME = INF,INF +STARDIS_ARGS_DEFAULT_RENDERING_UP = 0,0,1 +STARDIS_ARGS_DEFAULT_SAMPLES_COUNT = 10000 +STARDIS_ARGS_DEFAULT_SCALE_FACTOR = 1 +STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL = 1 + +# Including NULL char +STARDIS_MAX_NAME_LENGTH = 64 + +################################################################################ +# 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)) + +MPI_VERSION = 2 +MPI_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags $(MPI_PC)) +MPI_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs $(MPI_PC)) + +RSYS_VERSION = 0.14 +RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys) +RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys) + +S3D_VERSION = 0.10 +S3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags s3d) +S3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs s3d) + +SDIS_VERSION = 0.15.1 +SDIS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sdis) +SDIS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sdis) + +SENC3D_VERSION = 0.5 +SENC3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags senc3d) +SENC3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs senc3d) + +SG3D_VERSION = 0.2 +SG3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sg3d) +SG3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sg3d) + +SSP_VERSION = 0.14 +SSP_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags star-sp) +SSP_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs star-sp) + +SSTL_VERSION = 0.5 +SSTL_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sstl) +SSTL_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sstl) + +DPDC_CFLAGS =\ + $(RSYS_CFLAGS)\ + $(S3D_CFLAGS)\ + $(SDIS_CFLAGS)\ + $(SENC3D_CFLAGS)\ + $(SG3D_CFLAGS)\ + $(SSP_CFLAGS)\ + $(SSTL_CFLAGS)\ + $($(DISTRIB_PARALLELISM)_CFLAGS) +DPDC_LIBS =\ + $(RSYS_LIBS)\ + $(S3D_LIBS)\ + $(SDIS_LIBS)\ + $(SENC3D_LIBS)\ + $(SG3D_LIBS)\ + $(SSP_LIBS)\ + $(SSTL_LIBS)\ + $($(DISTRIB_PARALLELISM)_LIBS)\ + -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 = -O3 -DNDEBUG $(CFLAGS_COMMON) +CFLAGS_DEBUG = -g $(CFLAGS_COMMON) +CFLAGS = $(CFLAGS_$(BUILD_TYPE)) -fPIE + +################################################################################ +# Linker options +################################################################################ +LDFLAGS_HARDENED = -Wl,-z,relro,-z,now +LDFLAGS_DEBUG = $(LDFLAGS_HARDENED) +LDFLAGS_RELEASE = -s $(LDFLAGS_HARDENED) +LDFLAGS = $(LDFLAGS_$(BUILD_TYPE)) -pie + +OCPFLAGS_DEBUG = --localize-hidden +OCPFLAGS_RELEASE = --localize-hidden --strip-unneeded +OCPFLAGS = $(OCPFLAGS_$(BUILD_TYPE)) diff --git a/doc/stardis-input.5.in b/doc/stardis-input.5.in @@ -0,0 +1,382 @@ +.\" 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/>. +.Dd April 18, 2024 +.Dt STARDIS-INPUT 5 +.Os +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Name and short description +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh NAME +.Nm stardis-input +.Nd thermal system description for +.Xr stardis 1 +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Detailed description +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh DESCRIPTION +.Nm +is the format used by the +.Xr stardis 1 +program to describe a thermal system. +It is a line-by-line ASCII syntax. +.Pp +A thermal system is composed of lines of text, each one describing +either a program +.Pq an user-provided shared object , +a medium frontier +.Pq solid or fluid , +a boundary condition, a connection between two media, the scale of the +whole geometry, or the radiative temperature around the system. +In the medium, boundary and connection cases, description lines include +a list of file names that constitute the limit, boundary or connection. +.Xr stardis 1 +only accepts triangle mesh geometry files in STL format. +If a scale is specified, it defines the scaling factor to apply to the +geometry to have it expressed in meters +.Pq e.g. 1e-3 if the geometry is in mm . +.Pp +Any physical quantity involved in descriptions is expected in the +International System of Units +.Pq second, meter, kilogram, kelvin, watt, joule . +However, the geometry provided to +.Xr stardis 1 +can be described in any unit, multiple of meters or not, as long as the +scaling factor is provided. +.Pp +Properties are defined directly as constants in the input file. +Several properties can also be defined by programs, i.e. shared objects +provided by the user +.Pq compiled libraries . +The latter allow user-defined variable properties to be supplied to +.Xr stardis 1 . +Depending on the type of description they use, programs must +export a given list of mandatory functions. +They can also export some other optional functions. +The exact list with names and types can be found in the public header +.Pa stardis-prog-properties.h , +which is installed together with +.Xr stardis 1 +binary. +.Pp +A medium limit, a boundary or a connection description can be split +across files and a single file or description line can describe more +than one frontier +.Pq more than one connex region . +The main semantic constraint on descriptions is that enclosures must be +defined by a single description line, to ensure that every constitutive +part of the system is made from a single medium. +.Pp +Description lines can be submitted to +.Xr stardis 1 +in any order, with the exception of programs that must be +defined before use, and can be split across more than one file, through +multiple use of option +.Fl M . +.Pp +When a description line is parsed, the first step is to split it in +different parts. +.Xr stardis 1 +relies on the +.Xr wordexp 3 +POSIX function for this step. +As a consequence the rules that apply at this stage all come from +the wordexp rules: environment variables can be used and are +substituted, including inside arithmetic expressions, text inside quote +pairs is considered a single item, whitespace characters can be escaped +so that the current item continues past it +.Po see +.Xr wordexp 3 +for details +.Pc . +Note however that both the use of undefined environment variables and +the use of command substitution will be reported as an error as these +features are not enabled in +.Xr stardis 1 . +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Grammar in Backus-Naur form +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh GRAMMAR +In what follows, some lines end with a backslash +.Pq Li \e . +This is used as a convenience to continue a description next line. +However, this trick cannot be used in actual description files and +actual description lines must be kept single-line. +Text introduced by the sharp character +.Pq Li # +in descriptions is a comment and is not part of the description. +.Pp +The file format is as follows: +.Bl -column (description-line) (::) () +.It Ao Va thermal-system Ac Ta ::= Ta Ao Va description-line Ac +.It Ta Ta ... +.It Ao Va description-line Ac Ta ::= Ta Ao Va comment Ac +.It Ta \& \& | Ta Ao Va program Ac Op Ao Va comment Ac +.It Ta \& \& | Ta Ao Va medium Ac Op Ao Va comment Ac +.It Ta \& \& | Ta Ao Va connection Ac Op Ao Va comment Ac +.It Ta \& \& | Ta Ao Va boundary-condition Ac Op Ao Va comment Ac +.It Ta \& \& | Ta Ao Va scaling Ac Op Ao Va comment Ac +# At most once +.It \ Ta Ta +.It Ao Va comment Ac Ta ::= Ta Li # Vt string +.It Ao Va program Ac Ta ::= Ta Li PROGRAM Ao Va prog-name Ac Ao Va lib-path Ac Op Ao Va args Ac +.It Ao Va scaling Ac Ta ::= Ta Li SCALE Vt real +# Geometry scaling in ]0, INF) +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Media +.Bl -column (description-line) (::) () +.It Ao Va medium Ac Ta ::= Ta Ao Va fluid Ac | Ao Va solid Ac +.It \ Ta Ta +.It Ao Va fluid Ac Ta ::= Ta Ao Va fluid-const Ac | Ao Va fluid-prog Ac +.It Ao Va fluid-const Ac Ta ::= Ta +.Li FLUID Ao Va medium-name Ac Ao Va rho Ac Ao Va cp Ac \e +.It Ta Ta Ao Va initial-temp Ac Ao Va imposed-temp Ac \e +.It Ta Ta Ao Va triangle-sides Ac ... +.It Ao Va fluid-prog Ac Ta ::= Ta Li FLUID_PROG Ao Va medium-name Ac Ao Va prog-desc-sides Ac +.It \ Ta Ta +.It Ao Va solid Ac Ta ::= Ta Ao Va solid-const Ac | Ao Va solid-prog Ac +.It Ao Va solid-const Ac Ta ::= Ta +.Li SOLID Ao Va medium-name Ac Ao Va lambda Ac Ao Va rho Ac Ao Va cp Ac \e +.It Ta Ta Ao Va delta Ac Ao Va initial-temp Ac Ao Va imposed-temp Ac \e +.It Ta Ta Ao Va volumic-power Ac Ao Va triangle-sides Ac No ... +.It Ao Va solid-prog Ac Ta ::= Ta Li SOLID_PROG Ao Va medium-name Ac Ao Va prog-desc-sides Ac +.It \ Ta Ta +.It Ao Va lambda Ac Ta ::= Ta Vt real No # Conductivity > 0 [W/m/K] +.It Ao Va rho Ac Ta ::= Ta Vt real No # Volumic mass > 0 [kg/m^3] +.It Ao Va cp Ac Ta ::= Ta Vt real No # Capacity > 0 [J/K/kg] +.It Ao Va volumic-power Ac Ta ::= Ta Vt real No # [W/m^3] +.El +.Pp +Delta is the numerical parameter that defines the length of a conductive +random walk step. +The user can define it manually or let Stardis calculate it +automatically from the volume of the solid. +In the latter case, delta is set to V/(6*A), V and A being the solid's +volume and surface respectively: +.Bl -column (description-line) (::) () +.It Ao Va delta Ac Ta ::= Ta Li AUTO | Vt real +.El +.Pp +Media's descriptions, either solids or fluids, include two possible +temperatures: initial and imposed. +If imposed temperature is set +.Pq that is not Li UNKNOWN , +initial temperature must be defined at the same value. +In other words, one cannot define a medium with an imposed temperature +that changes at +.Li t= Ns Ar 0 : +.Bl -column (description-line) (::) () +.It Ao Va initial-temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K] +.It Ao Va imposed-temp Ac Ta ::= Ta Li UNKNOWN No # Temperature has to be solved +.It Ta \& \& | Ta Vt real No # Temperature > 0 [K] +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Connection +.Bl -column (description-line) (::) () +.It Ao Va connection Ac Ta ::= Ta Ao Va solid-fluid Ac | Ao Va solid-solid Ac +.It \ Ta Ta +.It Ao Va solid-fluid Ac Ta ::= Ta Ao Va solid-fluid-const Ac | Ao Va solid-fluid-prog Ac +.It Ao Va solid-fluid-const Ac Ta ::= Ta Li SOLID_FLUID_CONNECTION Ao Va connect-name Ac \e +.It Ta Ta Ao Va Tref Ac Ao Va emissivity Ac Ao Va specular-fraction Ac \e +.It Ta Ta Ao Va hc Ac Ao Va triangles Ac ... +.It Ao Va solid-fluid-prog Ac Ta ::= Ta Li SOLID_FLUID_CONNECTION_PROG \e +.It Ta Ta Ao Va connect-name Ac Ao Va prog-desc Ac +.It \ Ta Ta +.It Ao Va solid-solid Ac Ta ::= Ta Ao Va solid-solid-const Ac | Ao Va solid-solid-prog Ac +.It Ao Va solid-solid-const Ac Ta ::= Ta Li SOLID_SOLID_CONNECTION Ao Va connect-name Ac \e +.It Ta Ta Ao Va contact-resistance Ac Ao Va triangles Ac ... +.It Ao Va solid-solid-prog Ac Ta ::= Ta Li SOLID_SOLID_CONNECTION_PROG \e +.It Ta Ta Ao Va connect-name Ac Ao Va prog-desc Ac +.It \ Ta Ta +.It Ao Va emissivity Ac Ta ::= Ta Vt real No # \&In [0,1] +.It Ao Va specular-fraction Ac Ta ::= Ta Vt real No # \&In [0,1] +.It Ao Va hc Ac Ta ::= Ta Vt real No # Convective coefficient > 0 [W/m^2/K] +.It Ao Va contact-resistance Ac Ta ::= Ta Vt real No # > 0 [K/m^-2/W] +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Boundary conditions +.Bl -column (description-line) (::) () +.It Ao Va boundary-condition Ac Ta ::= Ta +.Aq Va dirichlet +.It Ta \& \& | Ta Aq Va robin +.It Ta \& \& | Ta Aq Va neumann +.It Ta \& \& | Ta Aq Va robin-neumann +.It Ta \& \& | Ta Ao Va rad-env Ac No # \&At most once +.It Ta \& \& | Ta Ao Va ext-source Ac No # \&At most once +.It \ Ta Ta +.\" Dirichlet +.It Ao Va dirichlet Ac Ta ::= Ta Ao Va dirichlet-const Ac | Ao Va dirichlet-prog Ac +.It Ao Va dirichlet-const Ac Ta ::= Ta Li T_BOUNDARY_FOR_SOLID Ao Va bound-name Ac \e +.It Ta Ta Ao Va temp Ac Ao Va triangles Ac ... +.It Ao Va dirichlet-prog Ac Ta ::= Ta Li T_BOUNDARY_FOR_SOLID_PROG Ao Va bound-name Ac \e +.It Ta Ta Ao Va prog-desc Ac +.It \ Ta Ta +.\" Robin +.It Ao Va robin Ac Ta ::= Ta Ao Va robin-fluid Ac | Ao Va robin-solid Ac +.It Ao Va robin-fluid Ac Ta ::= Ta Ao Va robin-fluid-const Ac | Ao Va robin-fluid-prog Ac +.It Ao Va robin-solid Ac Ta ::= Ta Ao Va robin-solid-const Ac | Ao Va robin-solid-prog Ac +.It Ao Va robin-fluid-const Ac Ta ::= Ta Li H_BOUNDARY_FOR_FLUID Ao Va bound-name Ac \e +.It Ta Ta Ao Va robin-const-desc Ac +.It Ao Va robin-solid-const Ac Ta ::= Ta Li H_BOUNDARY_FOR_SOLID Ao Va bound-name Ac \e +.It Ta Ta Ao Va robin-const-desc Ac +.It Ao Va robin-const-desc Ac Ta ::= Ta Ao Va Tref Ac Ao Va emissivity Ac Ao Va specular-fraction Ac +.It Ta Ta Ao Va hc Ac Ao Va outside-temp Ac Ao Va triangles Ac ... +.It Ao Va robin-fluid-prog Ac Ta ::= Ta Li H_BOUNDARY_FOR_FLUID_PROG Ao Va bound-name Ac \e +.It Ta Ta Ao Va prog-desc Ac +.It Ao Va robin-solid-prog Ac Ta ::= Ta Li H_BOUNDARY_FOR_SOLID_PROG Ao Va bound-name Ac \e +.It Ta Ta Ao Va prog-desc Ac +.It \ Ta Ta +.\" Neumann +.It Ao Va neumann Ac Ta ::= Ta Ao Va neumann-const Ac | Ao Va neumann-prog Ac +.It Ao Va neumann-const Ac Ta ::= Ta Li F_BOUNDARY_FOR_SOLID Ao Va bound-name Ac \e +.It Ta Ta Ao Va flux Ac Ao Va triangles Ac ... +.It Ao Va neumann-prog Ac Ta ::= Ta Li F_BOUNDARY_FOR_SOLID_PROG Ao Va bound-name Ac \e +.It Ta Ta Ao Va prog-desc Ac +.It \ Ta Ta +.\" Robin & Neumann +.It Ao Va robin-neumann Ac Ta ::= Ta Ao Va robin-neumann-const Ac +.It Ta \& \& | Ta Ao Va robin-neumann-prog Ac +.It Ao Va robin-neumann-const Ac Ta ::= Ta Li HF_BOUNDARY_FOR_SOLID Ao Va bound-name Ac \e +.It Ta Ta Ao Va Tref Ac Ao Va emissivity Ac Ao Va specular-fraction Ac \e +.It Ta Ta Ao Va hc Ac Ao Va outside-temp Ac Ao Va flux Ac Ao Va triangles Ac ... +.It Ao Va robin-neumann-prog Ac Ta ::= Ta Li HF_BOUNDARY_FOR_SOLID_PROG Ao Va bound-name Ac \e +.It Ta Ta Ao Va prog-desc Ac +.It \ Ta Ta +.\" Radiative temperature +.It Ao Va rad-env Ac Ta ::= Ta Ao Va rad-env-const Ac | Ao Va rad-env-prog Ac +.It Ao Va rad-env-const Ac Ta ::= Ta Li TRAD Ao Va temp Ac Ao Va Tref Ac +.It Ao Va rad-env-prog Ac Ta ::= Ta Li TRAD_PROG Ao Va prog-name Ac \e +.It Ta Ta Op Li PROG_PARAMS Op Ao Va args Ac +.It \ Ta Ta +.\" External source +.It Ao Va ext-source Ac Ta ::= Ta Ao Va ext-source-const Ac | Ao Va ext-source-prog Ac +.It Ao Va ext-source-const Ac Ta ::= Ta Li SPHERICAL_SOURCE Ao Va radius Ac Ao Va position Ac \e +.It Ta Ta Ao Va power Ac Ao Va diffuse-radiance Ac +.It Ao Va ext-source-prog Ac Ta ::= Ta Li SPHERICAL_SOURCE_PROG Ao Va radius Ac \e +.It Ta Ta Ao Va prog-name Ac Op Li PROG_PARAMS Op Ao Va args Ac +.It \ Ta Ta +.\" Miscellaneous +.It Ao Va temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K] +.It Ao Va Tref Ac Ta ::= Ta Vt real No # Reference temperature > 0 [K] +.It Ao Va outside-temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K] +.It Ao Va flux Ac Ta ::= Ta Vt real No # [W/m^2] +.It Ao Va power Ac Ta ::= Ta Vt real No # [W] +.It Ao Va diffuse-radiance Ac Ta ::= Ta Vt real No # [W/m^2/sr] +.It Ao Va position Ac Ta ::= Ta Vt real real real +.It Ao Va radius Ac Ta ::= Ta Vt real +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Miscellaneous +Names, either file names or description names +.Pq boundary names, medium names, program names, or connection names , +are a sequence of one or more ASCII characters, including +numbers and special characters like +.Ql \&. , +.Ql _ , +or +.Ql - +as one may consider using in standard file names. +Description names are case-sensitive and two different description +lines, either in the same description file or from different description +files, cannot use the same name. +Additionally, description names cannot be a number, nor be one of the +keywords defined by the present grammar and their lowercase +counterparts. +Finally, description names cannot be longer than +@STARDIS_MAX_NAME_LENGTH@ characters. +.Bl -column (description-line) (::) () +.It Ao Va bound-name Ac Ta ::= Ta Vt string +.It Ao Va medium-name Ac Ta ::= Ta Vt string +.It Ao Va prog-name Ac Ta ::= Ta Vt string +.It Ao Va connect-name Ac Ta ::= Ta Vt string +.It \ Ta Ta +.It Ao Va stl-path Ac Ta ::= Ta Pa path +.It Ao Va lib-path Ac Ta ::= Ta Pa path +.It \ Ta Ta +.It Ao Va args Ac Ta ::= Ta Vt string No ... +.It \ Ta Ta +.It Ao Va prog-desc Ac Ta ::= Ta Ao Va prog-name Ac Ao Va triangles Ac ... \e +.It Ta Ta Op Li PROG_PARAMS Op Ao Va args Ac +.It Ao Va prog-desc-sides Ac Ta ::= Ta Ao Va prog-name Ac Ao Va triangles-sides Ac ... \e +.It Ta Ta Op Li PROG_PARAMS Op Ao Va args Ac +.It \ Ta Ta +.It Ao Va triangles Ac Ta ::= Ta Ao Va stl-path Ac +.It Ao Va triangle-sides Ac Ta ::= Ta Ao Va side-specifier Ac Ao Va triangles Ac +.El +.Pp +Side descriptions in side specifiers rely on the following convention: +we first consider the direct triangle's normal (right-hand rule), then +we define the +.Li BACK +side of a triangle to be the side this normal comes out from. +That means that a closed set of triangles with normals pointing outside +should be used with the +.Li FRONT +side specifier to describe inside medium: +.Bl -column (description-line) (::) () +.It Ao Va side-specifier Ac Ta ::= Ta Li FRONT | Li BACK | Li BOTH +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" File examples +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh EXAMPLES +Define a system consisting of a solid cube named +.Ql Cube 1 , +with a Robin-type boundary condition and radiative exchange with the +environment. +The cube geometry is read from the file +.Pa cube.stl +and the solid medium properties are +.No lambda= Ns Ar 0.1 No W/m/K , +.No rho= Ns Ar 25 No kg/m^3 , +.No cp= Ns Ar 2 No J/K/kg . +The numerical parameter delta, that is used for solid conductive walks, is +.Ar 0.05 . +The initial temperature of the cube is +.Ar 0 No K , its temperature is unknown +.Pq it has to be solved , +and its volumic power is +.Ar 2.5 No W/m^3 . +The boundary properties are +.No emissivity= Ns Ar 0 , +.No specular-fraction= Ns Ar 0 , +.No hc= Ns Ar 10 No W/m^2/K +and +.No external-temperature= Ns Ar 100 No K . +The radiative environment is at +.Ar 300 No K . +Finally, the linearization of radiative transfer involving Robin's +boundary condition uses +.Ar 310 No K +as reference temperature and is set to +.Ar 330 No K +when linearisation involves the radiative environment: +.Bd -literal -offset Ds +SOLID Cube\ 1 0.1 25 2 0.05 0 UNKNOWN 2.5 FRONT cube.stl +H_BOUNDARY_FOR_SOLID HdT 310 0 0 10 100 cube.stl +TRAD 300 330 +.Ed +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" External references +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh SEE ALSO +.Xr stardis 1 , +.Xr wordexp 3 +.Rs +.%T The StL Format: Standard Data Format for Fabbers +.%A Marshall Burns +.%D 1993 +.%U https://www.fabbers.com/tech/STL_Format +.Re diff --git a/doc/stardis-input.5.txt b/doc/stardis-input.5.txt @@ -1,337 +0,0 @@ -// Copyright (C) 2018-2023 |Méso|Star> -// -// 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/>. - -:sharp: # - -:toc: - -stardis-input(5) -================= - -NAME ----- -stardis-input - thermal system description for stardis(1) - -DESCRIPTION ------------ -*stardis-input* is the format used by the *stardis*(1) program to describe a -thermal system. It relies on a line-based ad-hoc syntax. - -A thermal system is composed of lines of text, each one describing either a -program (an user-provided shared object), a -medium (solid or fluid) frontier, a boundary (limit condition or connection -between two media), the scale of the whole geometry, or the radiative -temperature around the system. In the medium or boundary -cases, description lines include a list of file names that constitute the -limit or boundary. The current version of *stardis(1)* only accepts triangle -mesh geometry files in *STL* format. If a scale is specified, it defines the -scaling factor to apply to the geometry to have it expressed in meters (e.g. -1e-3 if the geometry is in mm). - -A medium limit or a boundary description can be split across files and a -single file or description line can describe more than one frontier (more than -one connex region). The main semantic constraint on descriptions is that -enclosures must be defined by a single description line, to ensure that every -constitutive part of the system is made from a single medium. - -Finally, description lines can be submitted to the *stardis*(1) program in -any order, with the exception of programs that must be defined before use, -and can be split across more than one file, through multiple use -of option *-M*. - -LINE SPLITTING --------------- -When a description line is parsed, the first step is to split it in different -parts. *stardis(1)* relies on the wordexp POSIX library for this step. As a -consequence the very rules that apply at this stage all come from the wordexp -rules: environment variables can be used and are substituted, including inside -arithmetic expressions, text inside quote pairs is considered a single item, -whitespace characters can be escaped so that the current item continues past it -(see *wordexp(3)* for details). - -Note however that both the use of undefined environment variables and the use -of command substitution will be reported as an error as these features are not -enabled in *stardis(1)*. - -GRAMMAR -------- -In what follows, some lines end in *\*. This is used as a convenience to -continue a description next line. However, this trick cannot be used in -actual description files and actual description lines must be kept single-line. -Also, text appearing between quote marks has to be used verbatim in the input, -except the quote characters. Finally, text introduced by the *{sharp}* character -in descriptions, when not verbatim, is a comment and is not part of the -description. - -[verse] -_______ -<thermal-system> ::= <description-lines> - -<description-lines> ::= <description-line> - [ <description-lines> ] - -<description-line> ::= [ <program> ] [ <comment> ] - | [ <medium-frontier> ] [ <comment> ] - | [ <medium-boundary> ] [ <comment> ] - | [ <media-connection> ] [ <comment> ] - | [ <scaling-factor> ] [ <comment> ] {sharp} at most once - | [ <radiative-temps> ] [ <comment > ] {sharp} at most once - -------------------------------------- - -<program> ::= "PROGRAM" <prog-name> <library-path> [ <lib-arguments> ] - -<medium-frontier> ::= <solid-frontier> - | <fluid-frontier> - | <prog-solid-frontier> - | <prog-fluid-frontier> - -<medium-boundary> ::= <t-bound-for-solid> - | <h-bound-for-solid> - | <h-bound-for-fluid> - | <f-bound-for-solid> - | <hf-bound-for-solid> - | <prog-t-bound-for-solid> - | <prog-h-bound-for-solid> - | <prog-h-bound-for-fluid> - | <prog-hf-bound-for-fluid> - | <prog-f-bound-for-solid> - -<media-connection> ::= <solid-fluid-connect> - | <solid-solid-connect> - | <prog-solid-fluid-connect> - | <prog-solid-solid-connect> - -<comment> ::= "{sharp}" Any text introduced by the {sharp} character - -<solid-frontier> ::= "SOLID" <medium-name> <lambda> <rho> <cp> <delta> \ - <initial-temperature> <imposed-temperature> \ - <volumic-power> <triangle-sides> - -<fluid-frontier> ::= "FLUID" <medium-name> <rho> <cp> \ - <initial-temperature> <imposed-temperature> \ - <triangle-sides> - -<t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID" <bound-name> <temperature> \ - <triangles> - -<h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \ - <specular-fraction> <hc> <outside-temperature> \ - <triangles> - -<hf-bound-for-solid> ::= "HF_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \ - <specular-fraction> <hc> <outside-temperature> <flux> \ - <triangles> - -<h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID" <bound-name> <Tref> <emissivity> \ - <specular-fraction> <hc> <outside-temperature> \ - <triangles> - -<f-bound-for-solid> ::= "F_BOUNDARY_FOR_SOLID" <bound-name> <flux> <triangles> - -<solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION" <connect-name> <Tref>\ - <emissivity> <specular-fraction> <hc> <triangles> - -<solid-solid-connect> ::= "SOLID_SOLID_CONNECTION" <connect-name> \ - <contact-resistance> <triangles> - -<prog-solid-frontier> ::= "SOLID_PROG" <medium-name> <prog-name> <triangle-sides> \ - [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-fluid-frontier> ::= "FLUID_PROG" <medium-name> <prog-name> <triangle-sides> \ - [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ - <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ - <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-hf-bound-for-solid> ::= "HF_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ - <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID_PROG" <bound-name> <prog-name> \ - <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-f-bound-for-solid> ::= "F_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ - <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION_PROG" <connect-name> \ - <prog-name> <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<prog-solid-solid-connect> ::= "SOLID_SOLID_CONNECTION_PROG" <connect-name> \ - <prog-name> <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - -<scaling-factor> ::= "SCALE" <scale> [ <comment> ] - -<radiative-temps> ::= "TRAD" <radiative-temp> <radiative-temp-ref> - -------------------------------------- - -<prog-name> ::= STRING {sharp} must not be a keyword nor a number, - {sharp} including INF and others - -<library-path> ::= FILEPATH {sharp} the path can be absolute - {sharp} or relative to the running directory and must be valid - -<lib-arguments> ::= STRING {sharp} if not empty, the whole string is send to the - {sharp} stardis_create_library_data() optional function - {sharp} it is an error to provide arguments to a program if - {sharp} the associated library doesn't define this function - {sharp} note that the {sharp} character consistently ends - {sharp} arguments by starting a comment - -<medium-name> ::= STRING {sharp} must not be a keyword nor a number, - {sharp} including INF and others - -<lambda> ::= REAL {sharp} conductivity in W/(m.K), in ]0, INF) - -<rho> ::= REAL {sharp} volumic mass,in kg/m3, in ]0, INF) - -<cp> ::= REAL {sharp} capacity, in J/(kg.K) or kg.m2/(s2.K) - {sharp} in ]0, INF) - -<delta> ::= "AUTO" {sharp} delta is automatically set to V/6A (V and A - {sharp} being respectively the solid volume and its - {sharp} boundary area) - | REAL {sharp} delta*scaling_factor in m, in [0, INF) - -<initial-temperature> ::= REAL {sharp} in K, in [0, INF) - -<imposed-temperature> ::= "UNKNOWN" {sharp} temperature has to be solved - | REAL {sharp} in K, in [0, INF) - -<outside-temperature> ::= REAL {sharp} in K, in [0, INF) - -<volumic-power> ::= REAL {sharp} in W/m3, in (-INF , INF) - -<triangle-sides> ::= <side-specifier> <file-name> [ <triangle-sides> ] - -<bound-name> ::= STRING {sharp} must not be a keyword nor a number, - {sharp} including INF and others - -<connect-name> ::= STRING {sharp} must not be a keyword nor a number, - {sharp} including INF and others - -<Tref> ::= REAL {sharp} in K, in [0, inf) - -<emissivity> ::= REAL {sharp} in [0, 1] - -<specular-fraction> ::= REAL {sharp} in [0, 1] - -<hc> ::= REAL {sharp} in W/(m2.K), in [0, INF) - -<contact-resistance> ::= REAL {sharp} in m2.K/W, in [0, INF) - -<flux> ::= REAL {sharp} in W/m2, in (-INF , INF) - -<triangles> ::= <file-name> [ <triangles> ] - -<scale> ::= REAL {sharp} scaling factor to apply to the geometry - {sharp} in ]0 INF) - -<desc-arguments> ::= STRING {sharp} the whole string is send to the stardis_create_data() - {sharp} function when the description is created - {sharp} note that the '{sharp}' character consistently ends - {sharp} arguments by starting a comment - -<radiative-temp> ::= REAL {sharp} in K, in [0, inf) - -<radiative-temp-ref> ::= REAL {sharp} in K, in [0, inf) - -------------------------------------- - -<side-specifier> ::= "FRONT" | "BACK" | "BOTH" - -<file-name> ::= STRING - -______________ - -PROGRAMS --------- -Programs are user-provided shared objects (compiled libraries). They allow to -provide *stardis(1)* with user defined properties. Depending on the type of -description they are used with, programs must export a given list of -mandatory functions. They can also export some other optional functions. -The exact list with names and types can be found in the stardis-prog.h public -header file that is installed at the same time as the *stardis(1)* binary. - -UNITS ------ -Any physical quantity involved in descriptions is expected in the -International System of Units (second, metre, kilogram, kelvin, watt, joule); -the same applies to *stardis(1)* outputs as described in *stardis-output(5)*. - -However, the geometry provided to *stardis*(1) can be described in any unit, -multiple of meters or not, as long as the scaling factor is provided. - -TINIT VS TIMPOSED ------------------ -Media's descriptions, either solids or fluids, include two possible -temperatures: initial and imposed. If imposed temperature is set (that is not -"UNKNOWN"), initial temperature must be defined at the same value. In other -words, one cannot define a medium with an imposed temperature that changes at -t=0. - -TRIANGLE SIDES --------------- -Side descriptions in side specifiers rely on the following convention: we -first consider the direct triangle's normal (right-hand rule), then we define -the BACK side of a triangle to be the side this normal comes out from. That -means that a closed set of triangles with normals pointing outside should be -used with the FRONT side specifier to describe inside medium. - -NAMES ------ -Names, either file names or description names (program names, medium names or -boundary names), are a sequence of one or ore ASCII characters, including -numbers and special characters like *.* *_* *-* as one may consider using in -standard file names. Description -names are case-sensitive and two different description lines, either in the -same description file or from different description files, cannot use the same -name. Additionally, description names cannot be parsable as a number, nor be one -of the keywords defined by the present grammar (AUTO, BACK, BOTH, FLUID, -FLUID_PROG, FRONT, F_BOUNDARY_FOR_SOLID, F_BOUNDARY_FOR_SOLID_PROG, -H_BOUNDARY_FOR_FLUID, H_BOUNDARY_FOR_FLUID_PROG, H_BOUNDARY_FOR_SOLID, -H_BOUNDARY_FOR_SOLID_PROG, PROGRAM, PROG_PARAMS, SCALE, SOLID, SOLID_PROG, -SOLID_FLUID_CONNECTION, SOLID_FLUID_CONNECTION_PROG, SOLID_SOLID_CONNECTION, -SOLID_SOLID_CONNECTION_PROG, TRAD, T_BOUNDARY_FOR_SOLID, -T_BOUNDARY_FOR_SOLID_PROG, UNKNOWN) or their lowercase counterparts. -Finally, description names cannot be longer than 63 characters. - -EXAMPLES --------- -Define a solid named *Cube 1*, a h boundary, and their radiative environment. -The cube geometry is read from -the file cube.stl and the solid medium properties are lambda=0.1, rho=25, cp=2. -The numerical parameter delta, that is used for solid conductive walks, is -0.05. The initial temperature of the cube is 0°K, its temperature is unknown -(*stardis(1)* needs to solve it), and its volumic power is 2.5 W/m3. -The boundary properties are emissivity=0, specular-fraction=0, h=10 and -external-temperature = 100°K. -The cube radiative environment is at 300°K. -Finally, when the Picard method linearises radiative transfer involving the HdT -boundary, the reference temperature is set to 310°K, while it is set to 330°K -when linearisation involves the radiative environment. -....... -SOLID Cube\ 1 0.1 25 2 0.05 0 UNKNOWN 2.5 FRONT cube.stl -H_BOUNDARY_FOR_SOLID HdT 310 0 0 10 100 cube.stl -TRAD 300 330 -....... - -SEE ALSO --------- -*stardis*(1) -*wordexp*(3) diff --git a/doc/stardis-man.css b/doc/stardis-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/stardis-output.5 b/doc/stardis-output.5 @@ -0,0 +1,908 @@ +.\" 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/>. +.Dd April 12, 2024 +.Dt STARDIS-INPUT 5 +.Os +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Name and short description +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh NAME +.Nm stardis-output +.Nd output format of +.Xr stardis 1 +results +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Detailed description +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh DESCRIPTION +.Nm +describes the output format of the +.Xr stardis 1 +program. +Any +.Xr stardis 1 +result is written to standard output, even though some additional +informations can be written in files. +.Pp +The type of the data that are generated depends on the options used when +.Xr stardis 1 is invoked. +When invoked with one of the basic computation options +.Pq Fl p , Fl P , Fl m , Fl s No or Fl F , +.Xr stardis 1 +outputs a single Monte Carlo result. +On the opposite, +.Xr stardis 1 +ouputs compound results when invoked with +option +.Fl S +or +.Fl R . +Additionally, options +.Fl g +and +.Fl G +make +.Xr stardis 1 +compute and output a Green function and possibly information on heat +paths' ends. +Most of the complex data output is in VTK format. +.Pp +Note that some special options +.Pq Fl v , Fl h No or Fl d +that does not involve any computation produce output including +information on the +.Xr stardis 1 +software +.Pq their ouputs will not be described thereafter +or the provided thermal system. +.Pp +Any physical quantity in output is in the International System of Units +.Pq second, metre, kilogram, kelvin +except the coordinates that are in same system as the geometry. +.Pp +In what follows, some lines end with a backslash +.Pq Li \e . +This is used as a convenience to continue a description next line. +However, this trick cannot be used in actual description files and +actual description lines must be kept single-line. +Text introduced by the sharp character +.Pq Li # +in descriptions is a comment and is not part of the description. +.Pp +The output format is as follows: +.Bl -column (******************) (::=) () +.It Ao Va output Ac Ta ::= Ta Aq Va mc-estimate +.It Ta \& \& | Ta Aq Va green-function +.It Ta \& \& | Ta Aq Va geometry-dump +.It Ta \& \& | Ta Aq Va infrared-image +.It Ta \& \& | Ta Aq Va heat-paths +.El +.Pp +The following sections describe in detail each of these possible +outputs. +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Single Monte Carlo estimate +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh MONTE CARLO ESTIMATE +When +.Xr stardis 1 +is used to calculate a single Monte Carlo estimate, either a temperature +or a flux, the estimate is output first to standard output, possibly +followed by some of the heat paths involved in the computation if option +.Fl D +was used too. +Two different formats are possible: a raw, numbers only format +.Pq the default +or an extended format that mixes numbers and their descriptions +.Pq if option Fl e No is used . +.Bl -column (******************) (::=) () +.It Ao Va mc-estimate Ac Ta ::= Ta Ao Va probe-temp Ac # Options Fl P No or Fl p +.It Ta \& \& | Ta Ao Va medium-temp Ac # Option Fl m +.It Ta \& \& | Ta Ao Va mean-temp Ac # Option Fl s +.It Ta \& \& | Ta Ao Va mean-flux Ac # Option Fl F +.El +.\" Probe temperature +.Bl -column (******************) (::=) () +.It Ao Va probe-temp Ac Ta ::= Ta Ao Va probe-temp-raw Ac | Ao Va probe-temp-ext Ac +.It Ao Va probe-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac +.It Ao Va probe-temp-ext Ac Ta ::= Ta Li Temperature at Ao Va position Ac Ao Va time Ac \e +.It Ta Ta Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac +.El +.\" Medium temperature +.Bl -column (******************) (::=) () +.It Ao Va medium-temp Ac Ta ::= Ta Ao Va medium-temp-raw Ac | Ao Va medium-temp-ext Ac +.It Ao Va medium-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac +.It Ao Va medium-temp-ext Ac Ta ::= Ta Li Temperature in medium Ao Va medium-name Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac +.El +.\" Mean temperature +.Bl -column (******************) (::=) () +.It Ao Va mean-temp Ac Ta ::= Ta Ao Va mean-temp-raw Ac | Ao Va mean-temp-ext Ac +.It Ao Va mean-temp-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va failures Ac +.It Ao Va mean-temp-ext Ac Ta ::= Ta Li Temperature at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-temp-ext Ac Ao Va failures-ext Ac +.El +.\" Mean flux +.Bl -column (******************) (::=) () +.It Ao Va mean-flux Ac Ta ::= Ta Ao Va mean-flux-raw Ac | Ao Va mean-flux-ext Ac +.It Ao Va mean-flux-raw Ac Ta ::= Ta Ao Va estimate Ac Ao Va estimate Ac Ao Va estimate Ac \e +.It Ta Ta Ao Va estimate Ac Ao Va estimate Ac Ao Va failures Ac +.It Ao Va mean-flux-ext Ac Ta ::= Ta Li Temperature at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-temp-ext Ac +.It Ta Ta Li Convective flux at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-flux-ext Ac +.It Ta Ta Li Radiative flux at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-flux-ext Ac +.It Ta Ta Li Imposed flux at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-flux-ext Ac +.It Ta Ta Li Total flux at boundary Ao Va stl-path Ac \e +.It Ta Ta Ao Va time Ac Ao Va estimate-flux-ext Ac +.It Ta Ta Ao Va failures-ext Ac +.El +.\" Miscellaneous +.Bl -column (******************) (::=) () +.It Ao Va estimate Ac Ta ::= Ta Ao Va expected-value Ac Ao Va standard-error Ac +.It Ao Va estimate-temp-ext Ac Ta ::= Ta Ao Va expected-value Ac Li K +/- Ao Va standard-error Ac +.It Ao Va estimate-flux-ext Ac Ta ::= Ta Ao Va expected-value Ac Li W +/- Ao Va standard-error Ac +.It Ao Va expected-value Ac Ta ::= Ta Vt real +.It Ao Va standard-error Ac Ta ::= Ta Vt real +.El +.Bl -column (******************) (::=) () +.It Ao Va failures Ac Ta ::= Ta Ao Va error-count Ac Ao Va success-count Ac +.It Ao Va error-count Ac Ta ::= Ta Vt integer +.It Ao Va success-count Ac Ta ::= Ta Vt integer +.El +.Bl -column (******************) (::=) () +.It Ao Va position Ac Ta ::= Ta [ Vt real , Vt real , Vt real ] +.It Ao Va time Ac Ta ::= Ta Li at t= Ns Vt real +.It Ta \& \& | Ta Li with t in [ Vt real , Vt real ] +.It Ao Va medium-name Ac Ta ::= Ta Vt string +.It Ao Va stl-path Ac Ta ::= Ta Pa path +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Green function +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh GREEN FUNCTION +The Green function is generated, either in binary or ascii format, when +a green-compatible +.Xr stardis 1 +simulation option is used in conjuction with option +.Fl G +for a binary output, or option +.Fl g +for an ascii output. +For every successful heat path sampled carrying out the simulation, the +solver records all the elements of the path history relevant to link the +various imposed temperature, flux and volumic power values to the +simulation result. +The output is made of tables containing the different media and +boundaries and their imposed temperature, flux and volumic power values, +followed by the heat paths' history. +Also, option +.Fl G +make it possible to output heat paths' end information on an ascii, csv +formated file. +.Bl -column (******************) (::=) () +.It Ao Va green-function Ac Ta ::= Ta Ao Va green-ascii Ac No # Option Fl g +.It Ta \& \& | Ta Ao Va green-binary Ac Oo Ao Va paths Ac Oc No # Option Fl G +.El +.Pp +The Monte Carlo estimate and standard deviation for a given set of settings can +be computed as the mean and standard deviation of the samples of the Green +function computed using these settings. +Each sample can be computed as follows: +.Bl -bullet -compact -offset indent +.It +get the temperature of the ending boundary, medium or Trad +.It +add the temperature gain of each power term +.It +add the temperature gain of each flux term +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss ASCII format +Beyond the file format described below, +.Xr stardis 1 +could write comments +.Pq characters behind the hash mark Pq Li # +or blank lines +.Pq lines without any characters or composed only of spaces and tabs . +These are not part of the file format and should be ignored. +.Pp +The ASCII file format of a Green function is as follows: +.Bl -column (******************) (::=) () +.It Ao Va green-ascii Ac Ta ::= Ta Li ---BEGIN GREEN--- +.It Ta Ta Aq Va time-range +.It Ta Ta Ao Va #solids Ac Ao Va #fluids Ac \e +.It Ta Ta Ao Va #dirichlet-boundaries Ac \e +.It Ta Ta Ao Va #robin-boundaries Ac \e +.It Ta Ta Ao Va #neumann-boundaries Ac \e +.It Ta Ta Ao Va #successes Ac Ao Va #failures Ac +.It Ta Ta Aq Va solid +.It Ta Ta ... +.It Ta Ta Aq Va fluid +.It Ta Ta ... +.It Ta Ta Aq Va dirichlet-boundary +.It Ta Ta ... +.It Ta Ta Aq Va robin-boundary +.It Ta Ta ... +.It Ta Ta Aq Va neumann-boundary +.It Ta Ta ... +.It Ta Ta Aq Va rad-temp +.It Ta Ta Aq Va samples +.It \ Ta Ta +.It Ao Va time-rad Ac Ta ::= Ta Vt real Vt real +.It Ao Va #solids Ac Ta ::= Ta Vt integer +.It Ao Va #fluids Ac Ta ::= Ta Vt integer +.It Ao Va #dirichlet-boundaries Ac Ta ::= Ta Vt integer +.It Ao Va #robin-boundaries Ac Ta ::= Ta Vt integer +.It Ao Va #neumann-boundaries Ac Ta ::= Ta Vt integer +.It Ao Va #successes Ac Ta ::= Ta Vt integer +.It Ao Va #failures Ac Ta ::= Ta Vt integer +.It \ Ta Ta +.It Ao Va solid Ac Ta ::= Ta Ao Va green-id Ac Ao Va name Ac Ao Va lambda Ac Ao Va rho Ac Ao Va cp Ac \e +.It Ta Ta Ao Va power Ac Ao Va initial-temp Ac Ao Va imposed-temp Ac +.It Ao Va fluid Ac Ta ::= Ta Ao Va green-id Ac Ao Va name Ac Ao Va rho Ac Ao Va cp Ac \e +.It Ta Ta Ao Va initial-temp Ac Ao Va imposed-temp Ac +.It Ao Va lambda Ac Ta ::= Ta Vt real No # Conductivity > 0 [W/m/K] +.It Ao Va rho Ac Ta ::= Ta Vt real No # Volumic mass > 0 [kg/m^3] +.It Ao Va cp Ac Ta ::= Ta Vt real No # Capacity > 0 [J/K/kg] +.It Ao Va power Ac Ta ::= Ta Vt real No # Volumic power [W/m^3] +.It Ao Va initial-temp Ac Ta ::= Ta Vt real No # Temperature [K] +.It Ao Va imposed-temp Ac Ta ::= Ta Vt real No # Temperature [K] +.It \ Ta Ta +.It Ao Va dirichlet-boundary Ac Ta ::= Ta Ao Va green-id Ac Ao Va name Ac Ao Va temp Ac +.It Ao Va robin-boundary Ac Ta ::= Ta Ao Va green-id Ac Ao Va name Ac Ao Va temp-ref Ac \e +.It Ta Ta Ao Va emissivity Ac Ao Va specular-fraction Ac Ao Va hc Ac \e +.It Ta Ta Ao Va temp Ac +.It Ao Va neumann-boundary Ac Ta ::= Ta Ao Va green-id Ac Ao Va name Ac Ao Va flux Ac +.It Ao Va emissivity Ac Ta ::= Ta Vt real No # \&In [0,1] +.It Ao Va specular-fraction Ac Ta ::= Ta Vt real No # \&In [0,1] +.It Ao Va hc Ac Ta ::= Ta Vt real No # Convective coefficient [W/m^2/K] +.It Ao Va temp Ac Ta ::= Ta Vt real No # Temperature [K] +.It Ao Va temp-ref Ac Ta ::= Ta Vt real No # Reference temperature [K] +.It Ao Va flux Ac Ta ::= Ta Vt real No # [W/m^2] +.It \ Ta Ta +.It Ao Va rad-temp Ac Ta ::= Ta Ao Va green-id Ac Ao Va Trad Ac Ao Va Trad-ref Ac +.It Ao Va Trad Ac Ta ::= Ta Vt real No # Radiative temperature [K] +.It Ao Va Trad-ref Ac Ta ::= Ta Vt real No # Reference temperature [K] +.It \ Ta Ta +.It Ao Va sample Ac Ta ::= Ta Ao Va end-type Ac Ao Va green-id Ac \e +.It Ta Ta Ao Va #power-terms Ac Ao Va #flux-terms Ac \e +.It Ta Ta Ao Va power-term Ac ... Ao Va flux-term Ac ... +.It Ao Va end-type Ac Ta ::= Ta Aq Va end-dirichlet +.It Ta \& \& | Ta Aq Va end-robin +.It Ta \& \& | Ta Aq Va end-Trad +.It Ta \& \& | Ta Ao Va end-fluid Ac No # Fluid temperature +.It Ta \& \& | Ta Ao Va end-solid Ac No # Solid temperature +.It Ao Va end-dirichlet Ac Ta ::= Ta Li T +.It Ao Va end-robin Ac Ta ::= Ta Li H +.It Ao Va end-Trad Ac Ta ::= Ta Li R +.It Ao Va end-fluid Ac Ta ::= Ta Li F +.It Ao Va end-solid Ac Ta ::= Ta Li S +.It Ao Va #power-terms Ac Ta ::= Ta Vt integer +.It Ao Va #flux-terms Ac Ta ::= Ta Vt integer +.It Ao Va power-term Ac Ta ::= Ta Ao Va green-id Ac Ao Va factor Ac +.It Ao Va flux-term Ac Ta ::= Ta Ao Va green-id Ac Ao Va factor Ac +.It Ao Va factor Ac Ta ::= Ta Vt real +.It \ Ta Ta +.It Ao Va green-id Ac Ta ::= Ta Vt integer +.It Ao Va name Ac Ta ::= Ta Vt string +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Binary format +Binary Green outputs are formated according to the various C types from the +.Pa stardis-green.h +header file. +The output begins with a header +.Pq of type Vt struct green_file_header +that includes counts, followed by descriptions +.Pq of type Vt struct green_description +and samples. +Thereafter is the format of binary Green outputs. +This output is produced by +.Sy fwrite +calls and does not take care of endianness. +.Pp +The binary file format of a Green function is as follows: +.Bl -column (******************) (::=) () +.It Ao Va green-binary Ac Ta ::= Ta Li GREEN_BIN_FILE\&: +.It Ta Ta Aq Va file_format_version +.It Ta Ta Aq Va #descriptions +.It Ta Ta Aq Va #solids +.It Ta Ta Aq Va #fluids +.It Ta Ta Aq Va #robin-boundaries +.It Ta Ta Aq Va #dirichlet-boundaries +.It Ta Ta Aq Va #neumann-boundaries +.It Ta Ta Aq Va #solid-fluid-connects +.It Ta Ta Aq Va #solid-solid-connects +.It Ta Ta Aq Va #successes +.It Ta Ta Aq Va #failures +.It Ta Ta Aq Va Trad +.It Ta Ta Aq Va Trad-ref +.It Ta Ta Aq Va time-range +.It Ta Ta Ao Va description Ac ... +.It Ta Ta Ao Va sample Ac ... +.It \ Ta Ta +.It Ao Va file_format_version Ac Ta ::= Ta Vt unsigned +.It Ao Va #descriptions Ac Ta ::= Ta Vt unsigned +.It Ao Va #solids Ac Ta ::= Ta Vt unsigned +.It Ao Va #fluids Ac Ta ::= Ta Vt unsigned +.It Ao Va #robin-boundaries Ac Ta ::= Ta Vt unsigned +.It Ao Va #dirichlet-boundaries Ac Ta ::= Ta Vt unsigned +.It Ao Va #neumann-boundaries Ac Ta ::= Ta Vt unsigned +.It Ao Va #solid-fluid-connects Ac Ta ::= Ta Vt unsigned +.It Ao Va #solid-solid-connects Ac Ta ::= Ta Vt unsigned +.It Ao Va #successes Ac Ta ::= Ta Vt size_t +.It Ao Va #failures Ac Ta ::= Ta Vt size_t +.It Ao Va Trad Ac Ta ::= Ta Vt double No # Radiative temperature +.It Ao Va Trad-ref Ac Ta ::= Ta Vt double No # Reference radiative temperature +.It Ao Va time-range Ac Ta ::= Ta Vt double[2] +.It \ Ta Ta +.It Ao Va description Ac Ta ::= Ta Vt struct green_description +.It \ Ta Ta +.It Ao Va sample Ac Ta ::= Ta Ao Va sample-header Ac +.It Ta Ta Ao Va power-id Ac ... +.It Ta Ta Ao Va flux-id Ac ... +.It Ta Ta Ao Va power-weight Ac ... +.It Ta Ta Ao Va flux-weight Ac ... +.It Ao Va sample-header Ac Ta ::= Ta Vt struct green_sample_header +.It Ao Va power-id Ac Ta ::= Ta Vt unsigned +.It Ao Va flux-id Ac Ta ::= Ta Vt unsigned +.It Ao Va power-weight Ac Ta ::= Ta Vt double +.It Ao Va flux-weight Ac Ta ::= Ta Vt double +.El +.Pp +Binary Green function can be followed by partial information on the +sampled paths. +The output data are restricted to paths' ends. +.Bl -column (******************) (::=) () +.It Ao Va paths Ac Ta ::= Ta Li \&"End\&"\&, \&"End ID\&"\&, \&"X\&"\&, \&"Y\&"\&, \&"Z\&"\&, \e +.It Ta Ta Li \&"Elapsed Time\&" +.It Ta Ta Ao Va path-end Ac +.It Ta Ta ... +.It \ Ta Ta +.It Ao Va path-end Ac Ta ::= Ta \ +Ao Va end-name Ac Ns Li \&, \ +Ao Va end-id Ac Ns Li \&, \ +Ao Va x Ac Ns Li \&, \ +Ao Va y Ac Ns Li \&, \ +Ao Va z Ac Ns Li \&, \e +.It Ta Ta Ao Va elapsed-time Ac +.It Ao Va end-name Ac Ta ::= Ta Vt string No # Boundary name or TRAD +.It Ao Va end-id Ac Ta ::= Ta Vt integer +.It Ao Va x Ac Ta ::= Ta Vt real +.It Ao Va y Ac Ta ::= Ta Vt real +.It Ao Va z Ac Ta ::= Ta Vt real +.It Ao Va elapsed-time Ac Ta ::= Ta Vt real No # [s] +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Geometry +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh GEOMETRY DUMP +A +.Aq Va geometry-dump +is generated when +.Xr stardis 1 +is invoked with option +.Fl d . +In this mode, +.Xr stardis 1 +outputs the system geometry, as submitted in +.Xr stardis-input 5 +description, to standard output in VTK format. +The output geometry is +.Em not +the concatenation of the various geometry files +used in +.Xr stardis-input 5 +description. +It is the result of a deduplication process that removes duplicate and +degenerated triangles from the submited geometry. +Additionaly, as permitted by the VTK format, the output geometry is +decorated with many different properties provided to help users +understand the description processing, including possible errors. +.Pp +If errors are detected, some optional error-related data fields are +included in the geometry file. +Some errors report a by-triangle error status, other errors report a +by-enclosure error status. +.Pp +Also, holes in the geometry, if any, are reported in geometry dumps. +A hole is defined by its frontier that is a collection of triangles +surrounding the hole. +Such triangles are detected as having their 2 sides in the same +enclosure, but with a different medium on each side. +.Pp +Media information is provided in two different flavours. +First the medium on front and back sides of triangles can be found +through the +.Li Front_medium +and +.Li Back_medium +fields. +These fields use the special value +.Sy INT_MAX +for sides with no defined medium, as one can expect on boundary +triangles. +On the other hand, medium information provided by the +Enclosures_internal_media field displays the id of the medium created to +hold boundary information for boundary triangles. +In either case, media numbering information can be found in log messages +if option +.Fl V Ar 3 +is used in conjunction with the +.Fl d +dump option. +.Pp +The VTK layout is as follows: +.Bl -column (******************) (::=) () +.It Ao Va geometry-dump Ac Ta ::= Ta Li # vtk DataFile Version 2.0 +.It Ta Ta Ao Va description Ac +.It Ta Ta Li ASCII +.It Ta Ta Li DATASET POLYDATA +.It Ta Ta Aq Va vertices +.It Ta Ta Aq Va triangles +.It Ta Ta Li CELL_DATA Ao Va #triangles Ac +.It Ta Ta Aq Va front-media +.It Ta Ta Aq Va back-media +.It Ta Ta Aq Va interfaces +.It Ta Ta Aq Va unique-ids +.It Ta Ta Aq Va user-ids +.It Ta Ta Op Aq Va merge-conflicts +.It Ta Ta Op Aq Va property-conflicts +.It Ta Ta Aq Va file-ids +.It Ta Ta Aq Va boundaries +.It Ta Ta Op Aq Va compute-region +.It Ta Ta Aq Va encl-or-overlaps +.It \ Ta Ta +.It Ao Va description Ac Ta ::= Ta Vt string No # Up to 256 characters +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Geometry +.Bl -column (******************) (::=) () +.It Ao Va vertices Ac Ta ::= Ta Li POINTS Ao Va #vertices Ac Li double +.It Ta Ta Ao Va x Ac Ao Va y Ac Ao Va z Ac +.It Ta Ta ... +.It Ao Va triangles Ac Ta ::= Ta Li POLYGONS Ao Va #triangles Ac Ao Va #triangles*4 Ac +.It Ta Ta Li 3 Ao Va vertex-id Ac Ao Va vertex-id Ac Ao Va vertex-id Ac +.It Ta Ta ... +.El +.Pp +List triangle indices +.Em after +.Xr stardis 1 +deduplication: +.Bl -column (******************) (::=) () +.It Ao Va unique-ids Ac Ta ::= Ta Li SCALARS Unique_ID unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va triangle-id Ac No # \&In Bq 0, Ao Va #triangles Ac +.It Ta Ta ... # Up to Aq Va #triangles +.El +.Pp +List triangle indices +.Em before +deduplication to let the caller indentify his geometry as submitted to +.Xr stardis 1 : +.Bl -column (******************) (::=) () +.It Ao Va user-ids Ac Ta ::= Ta Li SCALARS User_ID unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va triangle-id Ac +.It Ta Ta ... # Up to Aq Va #triangles +.El +.Pp +List the file identifier in which each triangle first appeared: +.Bl -column (******************) (::=) () +.It Ao Va file-ids Ac Ta ::= Ta Li SCALARS Created_at_sg3d_geometry_add \e +.It Ta Ta Li unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va file-rank +.It Ta Ta ... # Up to Aq Va #triangles +.El +.Bl -column (******************) (::=) () +.It Ao Va #vertices Ac Ta ::= Ta Vt integer +.It Ao Va #triangles Ac Ta ::= Ta Vt integer +.It Ao Va #triangles*4 Ac Ta ::= Ta Vt integer +.It Ao Va vertex-id Ac Ta ::= Ta Vt integer No # \&In Bq 0, Ao Va #vertices Ac +.It Ao Va triangle-id Ac Ta ::= Ta Vt integer +.It Ao Va x Ac Ta ::= Ta Vt real +.It Ao Va y Ac Ta ::= Ta Vt real +.It Ao Va z Ac Ta ::= Ta Vt real +.It Ao Va file-rank Ac Ta ::= Ta Vt integer +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Properties +.Bl -column (******************) (::=) () +.It Ao Va front-media Ac Ta ::= Ta Li SCALARS Front_medium unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va medium-id Ac | Ao Va undef-medium Ac +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va back-media Ac Ta ::= Ta Li SCALARS Back_medium unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va medium-id Ac | Ao Va undef-medium Ac +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va interfaces-media Ac Ta ::= Ta Li SCALARS Interface unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va interface-id Ac +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va boundaries Ac Ta ::= Ta Li SCALARS Boundaries unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va boundary-id +.It Ta Ta ... # Up to Aq Va #triangles +.It \ Ta Ta +.It Ao Va medium-id Ac Ta ::= Ta Vt integer +.It Ao Va undef-medium Ac Ta ::= Ta Sy INT_MAX +.It Ao Va interface-id Ac Ta ::= Ta Vt integer +.It Ao Va boundary-id Ac Ta ::= Ta Vt integer +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Compute region +Define which triangles are members of the surface on which +.Xr stardis 1 +performs the calculation +.Pq options Fl F , Fl S No or Fl s : +.Bl -column (******************) (::=) () +.It Ao Va compute-region Ac Ta ::= Ta Li SCALARS Compute_region unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va region-membership +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va region-membership Ac Ta ::= Ta Li 0 No # Not member +.It Ta \& \& | Ta Li 1 No # The front side is member +.It Ta \& \& | Ta Li 2 No # The back side is member +.It Ta \& \& | Ta Li 3 No # Both sides are members +.It Ta \& \& | Ta Sy INT_MAX No # Error: must not be member +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Check description problems +Define which triangles have an invalid media definition when merging +partitions: +.Bl -column (******************) (::=) () +.It Ao Va merge-conflicts Ac Ta ::= Ta Li SCALARS Merge_conflict int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va merge-conflict-id +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va merge-conflict-id Ac Ta ::= Ta Li 0 No # \&No conflict +.It Ta \& \& | Ta Li 1 No # Conflict +.El +.Pp +Define which triangles have an invalid limit condition or an invalid +connection and report what is wrong: +.Bl -column (******************) (::=) () +.It Ao Va property-conflicts Ac Ta ::= Ta Li SCALARS Property_conflict int 1 +.It Ta Ta Aq Va prop-conflict-id +.It Ta Ta ... +.It Ao Va prop-conflict-id Ac Ta ::= Ta Li 0 No # \&No conflict +.It Ta \& \& | Ta Li 1 No # Robin btw 2 defined fluids +.It Ta \& \& | Ta Li 2 No # Robin btw 2 undefined fluids +.It Ta \& \& | Ta Li 3 No # Robin on fluid applied to solid +.It Ta \& \& | Ta Li 4 No # Robin btw 2 defined solids +.It Ta \& \& | Ta Li 5 No # Robin btw 2 undefined solids +.It Ta \& \& | Ta Li 6 No # Robin on solid applied to fluid +.It Ta \& \& | Ta Li 7 No # Robin&Neumann btw 2 defined media +.It Ta \& \& | Ta Li 8 No # Robin&Neumann btw 2 undefined media +.It Ta \& \& | Ta Li 9 No # Robin&Neumann applied to fluid +.It Ta \& \& | Ta Li 10 No # Dirichlet btw 2 defined solids +.It Ta \& \& | Ta Li 11 No # Dirichlet btw 2 undefined solids +.It Ta \& \& | Ta Li 12 No # Dirichlet on solid applied to fluid +.It Ta \& \& | Ta Li 13 No # Neumann btw 2 defined media +.It Ta \& \& | Ta Li 14 No # Neumann btw 2 undefined media +.It Ta \& \& | Ta Li 15 No # Neumann applied to fluid +.It Ta \& \& | Ta Li 16 No # Solid/fluid btw 2 solids +.It Ta \& \& | Ta Li 17 No # Solid/fluid btw 2 fluids +.It Ta \& \& | Ta Li 18 No # Solid/fluid used as boundary +.It Ta \& \& | Ta Li 19 No # Solid/fluid btw 2 undefined media +.It Ta \& \& | Ta Li 20 No # \&No connection btw fluid/fluid +.It Ta \& \& | Ta Li 21 No # \&No connection btw solid/fluid +.It Ta \& \& | Ta Li 22 No # \&No boundary around fluid +.It Ta \& \& | Ta Li 23 No # \&No boundary around solid +.It Ta \& \& | Ta Li 24 No # Invalid part of a compute surface +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss Enclosure +.Bl -column (******************) (::=) () +.It Ao Va encl-or-overlaps Ac Ta ::= Ta Ao Va encl-information Ac +.It Ta \& \& | Ta Ao Va overlappings Ac +.It \ Ta Ta +.It Ao Va encl-information Ac Ta ::= Ta Oo Ao Va holes Ac Oc No # If any +.It Ta Ta Aq Va enclosures +.It \ Ta Ta +.It Ao Va enclosures Ac Ta ::= Ta Li FIELD FieldData 2 +.It Ta Ta Ao Va enclosures-geoms Ac +.It Ta Ta Ao Va enclosures-media Ac +.El +.Pp +Report which triangles surround a hole: +.Bl -column (******************) (::=) () +.It Ao Va holes Ac Ta ::= Ta Li SCALARS Hole_frontiers unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va hole-membership +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va hole-membership Ac Ta ::= Ta Li 0 No # Not surrounding a hole +.It Ta Ta Li 1 No # Surrounding a hole +.El +.Pp +List the enclosures to which the triangle belongs and report the +validity status of the enclosures: +.Bl -column (******************) (::=) () +.It Ao Va enclosures-geoms Ac Ta ::= Ta Li Enclosures Ao Va #enclosures Ac \e +.It Ta Ta Ao Va #triangles Ac Li unsigned_char +.It Ta Ta Ao Va encl-status Ac ... # Up to Aq Va #enclosures +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va encl-status Ac Ta ::= Ta Li 0 No # Not part of the enclosure +.It Ta \& \& | Ta Li 1 No # Enclosure is valid +.It Ta \& \& | Ta Li 3 No # More than 1 medium +.It Ta \& \& | Ta Li 5 No # Triangles with undef medium +.It Ta \& \& | Ta Li 7 No # More than 1 medium including undef +.El +.Pp +List the media that the triangle surrounds for each enclosure and report +media description problems: +.Bl -column (******************) (::=) () +.It Ao Va enclosures-media Ac Ta ::= Ta Li Enclosures_internal_media Ao Va #enclosures Ac \e +.It Ta Ta Ao Va #triangles Ac Li unsigned_char +.It Ta Ta Ao Va encl-media Ac ... # Up to Aq Va #enclosures +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va encl-media Ac Ta ::= Ta Ao Va medium-id Ac No # Medium of the enclosure +.It Ta \& \& | Ta Sy INT_MAX No # Not part of the enclosure +.It Ta \& \& | Ta Sy INT_MAX Ns Li -1 No # Error: \&in the enclosure +.It Ta \& \& | Ta Sy INT_MAX Ns Li -2 No # Error: medium missing +.El +.Pp +Report problems of triangle overlap: +.Bl -column (******************) (::=) () +.It Ao Va overlappings Ac Ta ::= Ta Li SCALARS Overlapping_triangles \e +.It Ta Ta unsigned_int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Ao Va overlapping-status Ac +.It Ta Ta ... # Up to Aq Va #triangles +.It Ao Va overlapping-status Ac Ta ::= Ta Li 0 No # Doesn't overlap another triangle +.It Ta \& \& | Ta Li 1 No # Error: overlaps another triangle +.El +.Bl -column (******************) (::=) () +.It Ao Va #enclosures Ac Ta ::= Ta Vt integer +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Infrared image +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh INFRARED IMAGE +When invoked with option +.Fl R , +.Xr stardis 1 +calculates an infrared image of the system and write it to standard +output. +Depending on the +.Cm fmt +sub-option, this file can be either in +.Xr htrdr-image 5 +format or in VTK format. +.Bl -column (******************) (::=) () +.It Ao Va infrared-image Ac Ta ::= Ta Ao Va infrared-image-ht Ac # Option Fl R Cm fmt=HT +.It Ta \& \& | Ta Ao Va infrared-image-vtk Ac # Option Fl R Cm fmt=VTK +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss htrdr-image format +The +.Xr htrdr-image 5 +layout of an infrared image is as follows: +.Bl -column (******************) (::=) () +.It Ao Va infrared-image-ht Ac Ta ::= Ta Ao Va definition Ac +.It Ta Ta Aq Va pixel +.It Ta Ta ... # Up to number of pixels +.It \ Ta Ta +.It Ao Va definition Ac Ta ::= Ta Ao Va width Ac Ao Va height Ac +.It Ao Va width Ac Ta ::= Ta Vt integer +.It Ao Va height Ac Ta ::= Ta Vt integer +.It \ Ta Ta +.It Ao Va pixel Ac Ta ::= Ta Ao Va temperature Ac Li 0 0 0 0 Ao Va time Ac +.It Ao Va temperature Ac Ta ::= Ta Ao Va estimate Ac +.It Ao Va time Ac Ta ::= Ta Ao Va estimate Ac # Time per realisation +.It \ Ta Ta +.It Ao Va estimate Ac Ta ::= Ta Ao Va expected-value Ac Ao Va standard-error Ac +.It Ao Va expected-value Ac Ta ::= Ta Vt real +.It Ao Va standard-error Ac Ta ::= Ta Vt real +.El +.Pp +See +.Xr htpp 1 +to convert images in +.Xr htrdr-image 5 +format into a regular image. +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Ss VTK format +An infrared VTK image is an XY plane. +By convention, the origin +.Pq 0,0 +pixel is at the top-left corner of the image. +The result not only includes the computed temperature image, but also +includes a per-pixel computation time image as well as a per-pixel path +error count image and per-pixel standard deviation images for both +temperature and computation time. +.Pp +The VTK layout of an infrared image is as follows: +.Bl -column (******************) (::=) () +.It Ao Va infrared-image-vtk Ac Ta ::= Ta Li # vtk DataFile Version 2.0 +.It Ta Ta Ao Va description Ac +.It Ta Ta Li DATASET STRUCTURED_POINTS +.It Ta Ta Li DIMENSIONS Ao Va width Ac Ao Va height Ac Li 1 +.It Ta Ta Li ORIGIN 0 0 0 +.It Ta Ta Li SPACING 1 1 1 +.It Ta Ta Li POINT_DATA Ao Va #pixels Ac +.It Ta Ta Aq Va temp +.It Ta Ta Aq Va temp-stderr +.It Ta Ta Aq Va time +.It Ta Ta Aq Va time-stderr +.It Ta Ta Aq Va failures-count +.It \ Ta Ta +.It Ao Va temp Ac Ta ::= Ta Li SCALARS temperature_estimate float 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real +.It Ta Ta ... # Up to Aq Va #pixels +.It \ Ta Ta +.It Ao Va temp-stderr Ac Ta ::= Ta Li SCALARS temperature_std_dev float 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real +.It Ta Ta ... # Up to Aq Va #pixels +.It \ Ta Ta +.It Ao Va time Ac Ta ::= Ta Li SCALARS computation_time float 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real +.It Ta Ta ... # Up to Aq Va #pixels +.It \ Ta Ta +.It Ao Va time-stderr Ac Ta ::= Ta Li SCALARS computation_time_std_dev float 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real +.It Ta Ta ... # Up to Aq Va #pixels +.It \ Ta Ta +.It Ao Va failures-count Ac Ta ::= Ta Li SCALARS failures_count \e +.It Ta Ta Li unsigned_long_long 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt integer +.It Ta Ta ... # Up to Aq Va #pixels +.It \ Ta Ta +.It Ao Va #pixels Ac Ta ::= Ta Vt integer No # = Ao Va width Ac * Ao Va height Ac +.It Ao Va width Ac Ta ::= Ta Vt integer +.It Ao Va height Ac Ta ::= Ta Vt integer +.It Ao Va description Ac Ta ::= Ta Vt string No # Up to 256 characters +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" Heath paths +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh HEAT PATHS +When the +.Xr stardis 1 +option +.Fl D +is used in conjunction with an option that computes a result, some of +the heat paths +.Pq successful paths, erroneous paths, or both +sampled during the simulation are written to files. +Each path is written in VTK format, one VTK file per path. +The path description can include vertices' time if it makes sense, that +is if the computation time is not +.Sy INF . +.Pp +Due to the branching nature of non-linear Monte Carlo algorithms, paths +are made of strips. +With a Picard order of 1 +.Pq option Fl o Ar 1 , +there is only a single strip. +With higher orders, the number of strips can be greater than 1. +As a result, the whole path is a tree: past the first strip, each strip +can start from any vertex of one of the previous strips. +This tree, when displaying the +.Li Branch_id +field, starts with id 0, then increments each time a non-linearity leads +to the creation of a new strip +.Pq to fetch a temperature . +.Pp +The VTK layout of a path is as follows: +.Bl -column (******************) (::=) () +.It Ao Va heat-path Ac Ta ::= Ta Li # vtk DataFile Version 2.0 +.It Ta Ta Aq Va description +.It Ta Ta Li ASCII +.It Ta Ta Li DATASET POLYDATA +.It Ta Ta Aq Va vertices +.It Ta Ta Aq Va strips +.It Ta Ta Li CELL_DATA Aq Va #strips +.It Ta Ta Aq Va status +.It Ta Ta Li POINT_DATA Aq Va #vertices +.It Ta Ta Aq Va segment-types +.It Ta Ta Aq Va weights +.It Ta Ta Aq Va branch-ids +.It Ta Ta Oo Ao Va vertices-time Ac Oc # If not steady +.It \ Ta Ta +.It Ao Va description Ac Ta ::= Ta Vt string No # Up to 256 characters +.It Ao Va #vertices Ac Ta ::= Ta Vt integer +.It Ao Va #strips Ac Ta ::= Ta Vt integer +.El +.Pp +List the vertices of the main trajectory and its branches: +.Bl -column (******************) (::=) () +.It Ao Va vertices Ac Ta ::= Ta Li POINTS Ao Va #vertices Ac Li double +.It Ta Ta Ao Va x Ac Ao Va y Ac Ao Va z Ac +.It Ta Ta ... # Up to Aq Va #vertices +.It Ao Va x Ac Ta ::= Ta Vt real +.It Ao Va y Ac Ta ::= Ta Vt real +.It Ao Va z Ac Ta ::= Ta Vt real +.El +.Pp +List the main trajectory and branches of the path: +.Bl -column (******************) (::=) () +.It Ao Va strips Ac Ta ::= Ta Li LINES Ao Va #strips Ac Ao Va strip-list-size Ac +.It Ta Ta Ao Va #strip-vertices Ac Ao Va vertex-id Ac ... +.It Ta Ta ... # Up to Aq Va #strips +.It Ao Va strip-list-size Ac Ta ::= Ta Vt integer No # vertices per strip + Ao Va #strips Ac +.It Ao Va vertex-id Ac Ta ::= Ta Vt integer No # \&In [0 , Ao Va #vertices Ac Ns [ +.El +.Pp +Status of the path: +.Bl -column (******************) (::=) () +.It Ao Va status Ac Ta ::= Ta Li SCALARS Path_Failure unsigned_char 1 +.It Ta Ta Li 0 | Li 1 No # 0: Success; 1: Failure +.It Ta Ta ... # Up to Aq Va #strips +.El +.Pp +List the type of heat transfert to which each path vertex belongs: +.Bl -column (******************) (::=) () +.It Ao Va segment-types Ac Ta ::= Ta Li SCALARS Segment_Type unsigned_char 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Aq Va segment-type +.It Ta Ta ... # Up to Aq Va #vertices +.It Ao Va segment-type Ac Ta ::= Ta Li 0 No # Conduction +.It Ta \& \& | Ta Li 1 No # Convection +.It Ta \& \& | Ta Li 2 No # Radiative +.El +.Pp +Monte Carlo weight along the path: +.Bl -column (******************) (::=) () +.It Ao Va weights Ac Ta ::= Ta Li SCALARS Weight double 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real +.It Ta Ta ... # Up to Aq Va #vertices +.El +.Pp +List the identifier of the main path and its branches with respect to +the branch depth: +.Bl -column (******************) (::=) () +.It Ao Va branch-ids Ac Ta ::= Ta Li SCALARS Branch_id int 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt integer No # \&In [0 , Picard_order[ +.It Ta Ta ... # Up to Aq Va #vertices +.El +.Pp +Rewinded time along the path: +.Bl -column (******************) (::=) () +.It Ao Va vertices-time Ac Ta ::= Ta Li SCALARS Time double 1 +.It Ta Ta Li LOOKUP_TABLE default +.It Ta Ta Vt real No # Time [s] +.It Ta Ta ... # Up to Aq Va #vertices +.El +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.\" External references +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.Sh SEE ALSO +.Xr htpp 1 , +.Xr stardis 1 , +.Xr htrdr-image 5 , +.Xr stardis-input 5 +.Sh STANDARDS +.Rs +.%B The VTK User's Guide +.%O Simple Legacy Formats +.%I Kitware, Inc +.%N 11 +.%D 2010 +.%P 470--482 +.Re diff --git a/doc/stardis-output.5.txt b/doc/stardis-output.5.txt @@ -1,902 +0,0 @@ -// Copyright (C) 2018-2023 |Méso|Star> -// -// 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/>. - -:toc: - -= stardis-output(5) - -== NAME - -stardis-output - output format of stardis(1) results - -== DESCRIPTION - -*stardis-output* describes the output format of the *stardis*(1) program. -Any *stardis*(1) result is written to _standard output_, even though some -additional information can be written in files. - -The type of the data that are generated depends on the options used when -*stardis*(1) is invoked. When invoked with one of the basic computation options -(*-p*, *-P*, *-m*, *-s* or *-F*), *stardis*(1) outputs a single Monte-Carlo -result. On the opposite, *stardis*(1) ouputs compound results when invoked with -option *-S* or *-R*. Additionally, options *-g* and *-G* make *stardis*(1) -compute and output a Green function and possibly information on heat paths' -ends. Most of the complex data output is in VTK [1] format that can be -displayed and manipulated by the open-source software Paraview [2]. - -Finaly, some special options (*-v*, *-h* or *-d*) that does not involve any -computation produce output including information on the *stardis*(1) software -(their ouputs will not be described thereafter) or the provided thermal system. - -== UNITS - -As with the values in *stardis-input*(5), any physical quantity in output is in -the International System of Units (second, metre, kilogram, kelvin) except the -coordinates that are in same system as the geometry. - -== OPTIONS - -Every top-level item of the output listed below is produced by one or more -specific options of the *stardis*(1) program. The following list gives the -correspondance: - -*-p* or *-P*: produce <probe-temp> - -*-m*: produces <medium-temp> - -*-s*: produces <mean-temp> - -*-F*: produces <mean-flux> - -*-p*, *-P*, *-m* or *-s* with *-g* or *-G*: produce <ascii-green> or -<binary-green> and possibly <heat-paths-ends> respectively. - -*-D*: produces <heat-path> files in addition to the simulation output - -*-R*: produces <infrared-image> - -*-d*: produces <geometry-dump> - -== GRAMMAR - -In what follows, some lines end in *\*. This is used as a convenience to -continue a description next line. However, this trick is not part of the -actual output, that continues on a single line. On the other hand, multiple -lines not using the *\* convenience in multi-lines descriptions are truly -different lines of output. Also, text appearing between quote marks is a -verbatim part of the output, except the quote characters, *\#something* -denotes a count (the number of something), and the math operators '*+*' -and '***', when not verbatim, are used with the usual meaning (like in -\#something+1). Finally, text introduced by the *#* character in a description, -when neither verbatim nor count, is a comment and is not part of the output. - -== OUTPUT - -[verse] -_______ - -<output> ::= <single-MC-result> - | <binary-green> - | <heat-paths-ends> - | <ascii-green> - | <geometry-dump> - | <infrared-image> -_______ - -== SINGLE MONTE CARLO - -When *stardis*(1) is used to produce a single Monte-Carlo result, either -temperature or flux, this result is output first to _standard output_, possibly -followed by some of the heat paths involved in the computation if option *-D* -was used too. - -Two different formats are possible: a compact, numbers only format (the default) -or an extended format that mixes numbers and their descriptions (if option *-e* -is used). - -[verse] -_______ -<single-MC-result> ::= <single-MC-result> - | <ext-single-MC-result> - -<single-MC-result> ::= <probe-temp> - | <medium-temp> - | <mean-temp> - | <mean-flux> - -<ext-single-MC-result> ::= <ext-probe-temp> - | <ext-medium-temp> - | <ext-mean-temp> - | <ext-mean-flux> - -------------------------------------- - -<probe-temp> ::= <MC-estimate> <failures-report> - -<mean-temp> ::= <MC-estimate> <failures-report> - -<mean-flux> ::= <MC-estimate> <MC-estimate> <MC-estimate> \ - <MC-estimate> <MC-estimate> <failures-report> - # MC estimates order is: temperature, convective flux, - # radiative flux, imposed flux, total flux - -<medium-temp> ::= <MC-estimate> <failures-report> - -<MC-estimate> ::= <expected-value> <standard-deviation> - -<failures-report> ::= <error-count> <success-count> - -<ext-probe-temp> ::= "Temperature at" <ext-probe-position> <ext-time> \ - <ext-temp-estimate> - <ext-failures-report> - -<ext-mean-temp> ::= "Temperature at boundary" <file-name> <ext-time> \ - <ext-temp-estimate> - <ext-failures-report> - -<ext-mean-flux> ::= "Temperature at boundary" <file-name> <ext-time> \ - <ext-temp-estimate> - "Convective flux at boundary " <file-name> \ - <ext-time> <ext-flux-estimate> - "Radiative flux at boundary" <file-name> <ext-time> \ - <ext-flux-estimate> - "Imposed flux at boundary" <file-name> <ext-time> \ - <ext-flux-estimate> - "Total flux at boundary" <file-name> <ext-time> \ - <ext-flux-estimate> - <ext-failures-report> - -<ext-medium-temp> ::= "Temperature in medium" <medium-name> <ext-time> \ - <ext-temp-estimate> - <ext-failures-report> - -<ext-probe-position> ::= "[" <x-value> "," <y-value> "," <z-value> "]" - -<ext-time> ::= "at t=" <time-value> "=" - | "with t in [" <time-value> <time-value> "] =" - -<ext-temp-estimate> ::= <expected-value> "K +/-" <standard-deviation> - -<ext-flux-estimate> ::= <expected-value> "W +/-" <standard-deviation> - -<ext-failures-report> ::= "#failures:" <error-count> "/" <success-count> - -<ext-file-name> ::= STRING # as provided in input data - -<ext-medium-name> ::= STRING # as provided in input data - -------------------------------------- - -<x-value> ::= REAL - -<y-value> ::= REAL - -<z-value> ::= REAL - -<time-value> ::= REAL # in [0, INF) - -<error-count> ::= INTEGER # in [0, #samples] - -<success-count> ::= INTEGER # in [0, #samples] - -<expected-value> ::= REAL # depending on value semantics, - # range can be restricted - -<standard-deviation> ::= REAL # in [0, INF) - -_______ - -== GREEN - -The Green function is generated, either in binary or ascii format, when a -green-compatible *stardis*(1) simulation option is used in conjuction with -option *-G* for a binary output, or option *-g* for an ascii output. For -every successful heat path sampled carrying out the simulation, the solver -records all the elements of the path history relevant to link the various -imposed temperature, fluxe and volumic power values to the simulation result. -Note that to be able to explore different values of volumic power when -applying the Green function, it must have been generated with these values -being non-zero. On the other hand, any temperature or flux value in boundary -descriptions can be modified when applying the Green function, as well as the -ambient radiative temperature (Trad). - -The output in green mode is made of tables containing the different media and -boundaries and their imposed temperature, flux and volumic power values, -followed by the heat paths' history. Also, option *-G* make it possible to -output heat paths' end information on an ascii, csv formated file. - -The Monte-Carlo estimate and standard deviation for a given set of settings can -be computed as the mean and standard deviation of the samples of the *Green -function* computed using these settings. Each sample can be computed as -follows: - -* Get the temperature of the ending boundary, medium or Trad; -* Add the temperature gain of each power term; -* Add the temperature gain of each flux term. - -=== BINARY GREEN - -Binary Green outputs are formated according to the various C types from the -*stardis-green.h* header file. The output begins with a header (of type struct -green_file_header) that includes counts, followed by descriptions (of type -struct green_description) and samples. Thereafter is the format of binary -Green outputs. This output is produced by fwrite calls and does not take care -of endianness. Comments include the C type of the written data. - -[verse] -_______ -<binary-green> ::= "GREEN_BIN_FILE:" # char[16] - <file_format_version> # unsigned - #descriptions # unsigned - #solids # unsigned - #fluids # unsigned - #h-boundaries # unsigned - #t-boundaries # unsigned - #f-boundaries # unsigned - #solid-fluid-connections # unsigned - #solid-solid-connections # unsigned - #ok-samples # size_t - #failed-samples # size_t - Trad # double - Trad-reference # double - time-range # double[2] - <descriptions> - <samples> - -<descriptions> ::= description # struct green_description - <descriptions> # #descriptions descriptions - -<samples> ::= <sample> - <samples> # #ok-samples samples - ---------------------- - -<sample> ::= <sample-header> # struct green_sample_header - <ids> # unsigned[header.pw_count then header.fx_count] - <weights> # double[header.pw_count then header.fx_count] -_______ - - -=== ASCII GREEN - -Thereafter is the format of ascii Green outputs. - -[verse] -_______ -<ascii-green> ::= "---BEGIN GREEN---" - "# time range" - <time-range> - "# #solids #fluids #t_boundaries #h_boundaries \ - #f_boundaries #ok #failures" - #solids #fluids #t_boundaries #h_boundaries \ - #f_boundaries #ok #failures - "# Solids" - "# ID Name lambda rho cp power" - <solids> - "# Fluids" - "# ID Name rho cp" - <fluids> - "# T Boundaries" - "# ID Name temperature" - <t-bounds> - "# H Boundaries" - "# ID Name ref_temperature emissivity specular_fraction hc T_env" - <h-bounds> - "# F Boundaries" - "# ID Name flux" - <f-bounds> - "# Radiative Temperature" - "# ID Rad_Temp" - <rad-temps> - "# Samples" - "# end #power_terms #flux_terms power_term_1 ... \ - power_term_n flux_term_1 ... flux_term_n" - "# end = end_type end_id; end_type = T | H | X | R | F \ - | S" - "# power_term_i = power_id_i factor_i" - "# flux_term_i = flux_id_i factor_i" - <samples> - "---END GREEN---" - -<time-range> ::= <REAL> <REAL> # in [0, INF) x [first REAL, INF) - -<solids> ::= <solid> - <solids> # #solids solid descriptions - -<fluids> ::= <fluid> - <fluids> # #fluids fluid descriptions - -<t-bounds> ::= <t-bound> - <t-bounds> # #t-bounds t-bound descriptions - -<h-bounds> ::= <h-bound> - <h-bounds> # #h-bounds h-bound descriptions - -<f-bounds> ::= <f-bound> - <f-bounds> # #f-bounds f-bound descriptions - -<rad-temps> ::= <green-id> <Trad> <Trad-ref> - -<samples> ::= <sample> - <samples> # #samples sample descriptions - -------------------------------------- - -<sample> ::= <end-spec> <power-count> <flux-count> <power-terms> \ - <flux-terms> - -<solid> ::= <green-id> <name> <lambda> <rho> <cp> <power> \ - <initial-temp> <imposed-temp> - -<fluid> ::= <green-id> <name> <rho> <cp> <initial-temp> \ - <imposed-temp> - -<t-bound> ::= <green-id> <name> <temperature> - -<h-bound> ::= <green-id> <name> <ref_temperature> <emissivity> \ - <specular_fraction> <hc> <temperature> - -<f-bound> ::= <green-id> <name> <flux> - - -<name> ::= STRING - -<lambda> ::= REAL # in ]0, INF) - -<rho> ::= REAL # in ]0, INF) - -<cp> ::= REAL # in ]0, INF) - -<power> ::= REAL # in (-INF , INF) - -<initial-temp> ::= REAL # in [0 , INF) - | "NONE" if not imposed - -<imposed-temp> ::= REAL # in [0 , INF) - | "NONE" if not imposed - -<temperature> ::= REAL # in [0, INF) - -<ref-temperature> ::= REAL # in [0, INF) - -<emissivity> ::= REAL # in [0, 1] - -<specular-fraction> ::= REAL # in [0, 1] - -<hc> ::= REAL # in [0, INF) - -<flux> ::= REAL # in (-INF, INF) - -<Trad> ::= REAL # in [0, INF) - -<Trad-ref> ::= REAL # in [0, INF) - -<green-id> ::= INTEGER # in [0 #green-sources[ - -------------------------------------- - -<end-spec> ::= <end-type> <green-id> -<end-type> ::= "T" # sample ends at an t-bound - | "H" # sample ends at an h-bound - # a sample cannot end at an f-bound - | "R" # sample ends with Trad - | "F" # sample ends in a fluid with known temperature - | "S" # sample ends in a solid with known temperature - -<power-count> ::= INTEGER # in [0 INF) - -<flux-count> ::= INTEGER # in [0 INF) - -<power-terms> ::= <power-term> - <power-terms> # <power-count> power terms - -<flux-terms> ::= <flux-term> - <flux-terms> # <flux-count> flux terms - -------------------------------------- - -<power-term> ::= <green-id> <power-factor> - -<flux-term> ::= <green-id> <flux-factor> - -<power-factor> ::= REAL # in ]0, INF) - # the temperature gain is: - # <power-factor> * Power(green-id) - -<flux-factor> ::= REAL # in ]0, INF) - # the temperature gain is: - # <flux-factor> * Flux(green-id) -_______ - -== HEAT PATHS' ENDS - -When computing the Green function in binary mode, stardis can output partial -information ot the sampled heat paths. Opposed to what the *-D* option outputs, -that is the complete history of selected heat paths, here the information -output is restricted to paths' ends to allow the inclusion of all the sampled -heat paths, allowing statistical analysis. - -Note that in wath follows, the meaning of external quotes is as usual: what is -inside is verbatim, including quotes. - -[verse] -_______ -<heat-paths-ends> ::= ""End", "End ID", "X", "Y", "Z", "Elapsed time"" - <heat-path-end-list> - -<heat-path-end-list> ::= <end-name> ", " <endid> ", " <x> ", " <y> ", " \ - <z> ", " <elapsed-time> - <heat-path-end-list> # #samples heat path ends - -------------------------------------- - -<end-name> ::= STRING # the name of the boundary at the end of the - # heat path, or TRAD for radiative ending - -<end-id> ::= INTEGER # in [0 #boundaries] - # order is the order in the description file, - # TRAD's id being #boundaries - -<x> ::= REAL - -<y> ::= REAL - -<z> ::= REAL - -<elapsed-time> ::= REAL # in [0, INF) -_______ - -== GEOMETRY DUMP - -A *geometry-file* is generated when *stardis*(1) is invoked with option *-d*. -In this mode, *stardis*(1) outputs the system geometry, as submitted in -*stardis-input*(5) description, to _standard output_ in VTK [1] format. -The output geometry is not the concatenation of the various geometry files -used in *stardis-input*(5) description. It is the result of a deduplication -process that removes duplicate and degenerated triangles from the submited -geometry. - -Additionaly, as permitted by the VTK [1] format, the output geometry is -decorated with many different properties provided to help users understand -the description processing, including possible errors. - -If errors are detected, some optional error-related data fields are included -in the geometry file. Some errors report a by-triangle error status, other -errors report a by-enclosure error status. - -Also, holes in the geometry, if any, are reported in geometry dumps. A hole is -defined by its frontier that is a collection of triangles surrounding the hole. -Such triangles are detected as having their 2 sides in the same enclosure, but -with a different medium on each side. - -Media information is provided in two different flavours. First the medium on -front and back sides of triangles can be found through the Front_medium and -Back_medium fields. These fields use the special value 4294967295 (INT_MAX) for -sides with no defined medium, as one can expect on boundary triangles. On the -other hand, medium information provided by the Enclosures_internal_media -field displays the id of the medium created to hold boundary information for -boundary triangles. In either case, media numbering information can be found -in log messages if option -V 3 is used in conjunction with the -d dump option. - -[verse] -_______ -<geometry-file> ::= "# vtk DataFile Version 2.0" - "Dump of star-geometry-3d geometry" - "ASCII" - "DATASET POLYDATA" - <vertices> - <triangles> - "CELL_DATA" #triangles - <front-media> - <back-media> - <interfaces> - <unique-ids> - <user-ids> - [ <merge-conflicts> ] # if some merge conflict occured - [ <property-conflicts> ] # if some property conflict - # occured - <file-ids> - <boundaries> - [ <compute-region> ] # if defined - <encl-or-overlaps> - -<vertices> ::= "POINTS" #vertices "double" - <vertex-list> - -<triangles> ::= "POLYGONS" #triangles #triangles*4 - <triangle-list> - -<front-media> ::= "SCALARS Front_medium unsigned_int 1" - "LOOKUP_TABLE default" - <front-medium-ids> - -<back-media> ::= "SCALARS Back_medium unsigned_int 1" - "LOOKUP_TABLE default" - <back-medium-ids> - -<interfaces> ::= "SCALARS Interface unsigned_int 1" - "LOOKUP_TABLE default" - <interface-ids> - -<unique-ids> ::= "SCALARS Unique_ID unsigned_int 1" - "LOOKUP_TABLE default" - <trg-unique-ids> - -<user-ids> ::= "SCALARS User_ID unsigned_int 1" - "LOOKUP_TABLE default" - <trg-user-ids> - -<merge-conflicts> ::= "SCALARS Merge_conflict int 1" - "LOOKUP_TABLE default" - <trg-merge-conflicts> - -<property-conflicts> ::= "SCALARS Property_conflict int 1" - "LOOKUP_TABLE default" - <trg-prop-conflicts> - -<file-ids> ::= "SCALARS Created_at_sg3d_geometry_add unsigned_int 1" - "LOOKUP_TABLE default" - <file-ranks> - -<boundaries> ::= "SCALARS Boundaries unsigned_int 1" - "LOOKUP_TABLE default" - <boundary-ids> - -<compute-region> ::= "SCALARS Compute_region unsigned_int 1" - "LOOKUP_TABLE default" - <region-membership> - -<encl-or-overlaps> ::= <encl-information> # if enclosure extraction was - # possible - | <overlaps> # if overlapping triangles where detected - ------------------ - -<vertex-list> ::= "3" <vertice_id> <vertice_id> <vertice_id> - <vertex-list> # #vertices vertices - -<triangle-list> ::= <real3> - <triangle-list> # #triangles triangles - -<front-medium-ids> ::= <medium-id> | <undef-medium> - <front-medium-ids> # #triangles ids - -<back-medium-ids> ::= <medium-id> | <undef-medium> - <back-medium-ids> # #triangles ids - -<interface-ids> ::= INTEGER # in [0 #interface[ - <interface-ids> # #triangles ids - -<trg-unique-ids> ::= INTEGER # in [0 #triangles[ - <trg-unique-ids> # #triangles ids - -<trg-user-ids> ::= INTEGER # in [0 #submitted triangles[ - <trg-user-ids> # #triangles ids - -<trg-merge-conflicts> ::= "0" # triangle without any merge conflict - | "1" # triangle with a merge conflict - <trg-merge-conflicts> # #triangles statuses - -<trg-prop-conflicts> ::= "0" # triangle with no property conflict - | "1" # H_BOUNDARY_FOR_FLUID between 2 defined media - | "2" # H_BOUNDARY_FOR_FLUID between 2 undefined media - | "3" # H_BOUNDARY_FOR_FLUID enclosing a solid - | "4" # H_BOUNDARY_FOR_SOLID between 2 defined media - | "5" # H_BOUNDARY_FOR_SOLID between 2 undefined media - | "6" # H_BOUNDARY_FOR_SOLID enclosing a fluid - | "7" # HF_BOUNDARY_FOR_SOLID between 2 defined media - | "8" # HF_BOUNDARY_FOR_SOLID between 2 undefined media - | "9" # HF_BOUNDARY_FOR_SOLID enclosing a fluid - | "10" # T_BOUNDARY_FOR_SOLID between 2 defined media - | "11" # T_BOUNDARY_FOR_SOLID between 2 undefined media - | "12" # T_BOUNDARY_FOR_SOLID enclosing a fluid - | "13" # F_BOUNDARY_FOR_FLUID between 2 defined media - | "14" # F_BOUNDARY_FOR_FLUID between 2 undefined media - | "15" # F_BOUNDARY_FOR_SOLID enclosing a fluid - | "16" # SOLID_FLUID_CONNECTION between 2 solids - | "17" # SOLID_FLUID_CONNECTION between 2 fluids - | "18" # SOLID_FLUID_CONNECTION used as boundary - | "19" # SOLID_FLUID_CONNECTION between 2 undefined - # media - | "20" # no connexion between 2 fluids - | "21" # no connexion between a solid and a fluid - | "22" # no boundary around a fluid - | "23" # no boundary around a solid - | "24" # invalid part of a compute surface - <trg-prop-conflicts> # #triangles statuses - -<real3> ::= REAL REAL REAL - -<vertice-id> ::= INTEGER # in [0 #vertices[ - -<file-ranks> ::= INTEGER # in [0 #submitted files[ - <file-ranks> # #triangles ranks - -<boundary-ids> ::= INTEGER # in [0 #submitted descriptions[ - <boundary-ids> # #triangles ids - -<region-membership> ::= <reg-not-member> # triangle not part of the compute - # region - | <reg-member> # triangle is part of the compute region - <region-membership> # #triangles membership status - -<encl-information> ::= [ <holes> ] # if there are holes - <enclosures> - -<overlaps> ::= "SCALARS Overlapping_triangles unsigned_int 1" - "LOOKUP_TABLE default" - <overlapping-status> - -<holes> ::= "SCALARS Hole_frontiers unsigned_int 1" - "LOOKUP_TABLE default" - <hole-memberships> - -<enclosures> ::= "FIELD FieldData 2" - "Enclosures" #enclosures #triangles "unsigned_char" - <encl-memberships> - "Enclosures_internal_media" #enclosures #triangles \ - "unsigned_int" - <encl-media> - ------------------ - -<hole-memberships> ::= "0" # triangle not surrounding a hole - | "1" # triangle surrounding a hole - <hole-memberships> # #triangles hole memberships - -<encl-memberships> ::= <encl-status 0> ... <encl-status #enclosures-1> - <encl-memberships> # #triangles enclosure memberships - -<encl-media> ::= <encl 0 medium> ... <encl #enclosures-1 medium> - <encl-media> # #triangles enclosure media - -<medium-id> ::= INTEGER # in [0, #medium[ - -<undef-medium> ::= "4294967295" - -<reg-not-member> ::= "0" - -<reg-member> ::= "1" # the FRONT side is member of the region - | "2" # the BACK side is member of the region - | "3" # both sides are member of the region - | "4294967295" # the triangle is an invalid part of - # the region - -<overlapping-status> ::= "0" # triangle not overlapping another triangle - | "1" # triangle overlapping another triangle - <overlapping-status> # #triangles overlapping status - -<encl-status i> ::= <encl-not-member> # the triangle is not part of the - # ith enclosure - | <encl-member> # the triangle is part of the ith - # enclosure - -<enc i medium> ::= <medium-id> # the triangle is part of the ith - # enclosure and has this medium in the - # involved side(s) - | "4294967293" # the triangle is part of the ith - # enclosure and has no defined medium in - # the involved side(s) - | "4294967294" # the 2 sides of the triangle are part of - # the ith enclosure, but have 2 different - #media - | "4294967295" # the triangle is not part of the ith - # enclosure - ------------------ - -<encl-not-member> ::= "0" - -<encl-member> ::= "1" # valid enclosure - | "3" # invalid enclosure: more than 1 medium - | "5" # invalid enclosure: some triangles with no - # defined medium - | "7" # invalid enclosure: more than 1 "medium", - # including undefined -_______ - -== INFRARED IMAGE - -When invoked with option *-R*, *stardis*(1) generates an infrared image of -the system and write it to _standard output_. Depending on the *fmt* -sub-option, this file can be either in VTK [1] format on in *htrdr-image*(5) -format. - -=== HTRDR-IMAGE INFRARED IMAGE -If the output image is in *htrdr-image*(5) format, it comply with the *lw* -section of the format, with only the temperature fields being informed. The -resulting format is as follows: - -[verse] -_______ -<htrdr-image> ::= <definition> - <pixel> - [ <pixel> ... ] - -<definition> ::= <width> <height> -<width> ::= INTEGER -<height> ::= INTEGER - -<pixel> ::= <temperature> 0 0 0 0 <time> - -<temperature> ::= <estimate> -<time> ::= <estimate> - -<estimate> ::= <expected-value> <standard-error> -<expected-value> ::= REAL -<standard-error> ::= REAL -_______ - -These files can be post-processed using the *htpp*(1) tool, that is part of -the high-tune project. - -=== VTK INFRARED IMAGE -If the output image is in VTK format, it is on an XY plane with coordinates in -the [0 pixel_count[ range. By convention, the origine (0,0) pixel is at the -top-left corner of the image. - -The result not only includes the computed temperature image, but also includes -a per-pixel computation time image as well as a per-pixel path error count -image and per-pixel standard deviation images for both temperature and -computation time. - -[verse] -_______ -<infrared-image> ::= "# vtk DataFile Version 2.0" - "Infrared Image" - "ASCII" - "DATASET STRUCTURED_POINTS" - "DIMENSIONS" <image-width> <image-height> "1" - "ORIGIN 0 0 0" - "SPACING 1 1 1" - "POINT_DATA" <image-width>*<image-height> - "SCALARS temperature_estimate float 1" - "LOOKUP_TABLE default" - <temperatures> - "SCALARS temperature_std_dev float 1" - "LOOKUP_TABLE default" - <temp_std_devs> - "SCALARS computation_time float 1" - "LOOKUP_TABLE default" - <computation_times> - "SCALARS computation_time_std_dev float 1" - "LOOKUP_TABLE default" - <com_time_std_devs> - "SCALARS failures_count unsigned_long_long 1" - "LOOKUP_TABLE default" - <failures_counts> - -<temperatures> ::= REAL # in [0, INF) - <temperatures> # <image-width>*<image-height> - # temperatures - -<temp_std_devs> ::= REAL # in [0, INF) - <temperature_std_devs> # <image-width>*<image-height> - # std_devs - -<computation_times> ::= REAL # in [0, INF) - <computation_times> # <image-width>*<image-height> - # times - -<comp_time_std_devs> ::= REAL # in [0, INF) - <comp_time_std_devs> # <image-width>*<image-height> - # std_devs - -<failures_counts> ::= INTEGER # in [0, SAMPLES_COUNT] - <failures_counts> # <image-width>*<image-height> - # failures_counts -_______ - -== DUMP HEAT PATHS - -When the *stardis*(1) option *-D* is used in conjunction with an option that -computes a result, some of the heat paths (successful paths, erroneous paths, -or both) sampled during the simulation are written to files. Each path is -written in VTK [1] format, one VTK file per path. The path description can -include vertices' time if it makes sense, that is if the computation time is -not INF. Due to the branching nature of non-linear Monte-Carlo algorithms, -paths are made of strips. Whith a Picard order of 1, there is only a single -strip, with higher orders, the number of strips can be greater than 1. As a -result, the whole path is a tree: past the first strip, each strip can start -from any vertex of one of the previous strips. This tree, when displaying the -*Branch_id* field, starts with id 0, then increments each time a non-linearity -leads to the creation of a new strip (to fetch a temperature). - -[verse] -_______ - -<heat-path> ::= "# vtk DataFile Version 2.0" - "Heat path" - "ASCII" - "DATASET POLYDATA" - "POINTS" #vertices "double" - <path-vertices> - "LINES" #strips #vertices+#strips - <heat-strips> - "CELL_DATA" #strips - "SCALAR Path_Failure unsigned_char 1" - "LOOKUP_TABLE default" - <path-failures> - "POINT_DATA" #vertices - "SCALARS Segment_Type unsigned_char 1" - "LOOKUP_TABLE default" - <segments-types> - "SCALARS Weight double 1" - "LOOKUP_TABLE default" - <weights> - "SCALARS Branch_id int 1" - "LOOKUP_TABLE default" - <branch_ids> - [ <vertices-time> ] # if not steady - -<path-vertices> ::= <real3> - <path-vertices> # #vertices vertices - -<path-failures> ::= <path-failure> - <path-failures> # #strips failure statutes - -<heat-strips> ::= <heat-strip> - <heat-strips> # #strips strips - -<segments-types> ::= <segment-type> - <segments-types> # #segments types - -<weights> ::= <weight> - <weights> # #vertices weights - -<branch_ids> ::= <branch_id> - <branch_ids> # #vertices ids - -<vertices-time> ::= "SCALARS Time double 1" - "LOOKUP_TABLE default" - <durations> - ------------------ - -<real3> ::= REAL REAL REAL - -<path-failure> ::= "0" # SUCCESS - | "1" # FAILURE - -<heat-strip> ::= #strip_vertices <vtx_idx 1> ... <vtx_idx #strip_vertices> - -<segment-type> ::= "0" # CONDUCTION - | "1" # CONVECTION - | "2" # RADIATIVE - -<weight> ::= REAL - -<branch-id> ::= INTEGER in [0 Picard_Order] - -<durations> ::= REAL # in [0, INF) - <durations> # #vertices durations - -<vtx_idx> ::= INTEGER # in [0 #vertices[ - -_______ - -== NOTES - -1. VTK file format - - <http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf> - -2. Paraview softawre - - <https://www.paraview.org/> - -== SEE ALSO - -*stardis*(1), -*stardis-input*(5), -*htrdr-image*(5) diff --git a/doc/stardis.1.in b/doc/stardis.1.in @@ -0,0 +1,619 @@ +.\" 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/>. +.Dd April 24, 2024 +.Dt STARDIS 1 +.Os +.Sh NAME +.Nm stardis +.Nd statistical solving of coupled thermal systems +.Sh SYNOPSIS +.Nm +.Op Fl eghiv +.Op Fl a Ar diff_algo +.Op Fl D Ar path_type , Ns Ar files_name_prefix +.Op Fl d Ar file_base_name +.Op Fl F Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +.Op Fl G Pa green_bin Ns Op , Ns Pa green_ascii +.Op Fl I Ar initial_time +.Op Fl L Pa interface_probes +.Op Fl m Ar medium_name Ns Op , Ns Ar time Ns Op , Ns Ar time +.Op Fl n Ar samples_count +.Op Fl o Ar picard_order +.Op Fl P Ar x , Ns Ar y , Ns Ar z Ns Oo , Ns Ar time Ns Oo , Ns Ar time Oc Oc \ + Ns Op : Ns Ar side_indicator +.Op Fl p Ar x , Ns Ar y , Ns Ar z Ns Op , Ns Ar time Ns Op , Ns Ar time +.Op Fl R Ar rendering_opt Ns Op : Ns Ar rendering_opt No ... +.Op Fl S Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +.Op Fl s Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +.Op Fl t Ar threads_count +.Op Fl V Ar verbosity_level +.Op Fl X Pa output_rng +.Op Fl x Pa input_rng +.Fl M Pa system +.Sh DESCRIPTION +.Nm +solves coupled thermal systems: conductive, convective and radiative transfers +are solved together. +The physical model used for conduction is the local unstationary heat conduction +equation. +Convection fluxes are assumed to be linear with temperature, and radiation +is assumed to be integrated over the whole thermal spectral range, +therefore radiative heat fluxes are proportionnal to a difference of +temperatures to the power 4. +.Nm +can deal with complex geometries as well as high-frequency external +solicitations over a very long period of time, relative to the characteristic +time of the system. +The provided system description should comply with the +.Xr stardis-input 5 +format. +.Pp +.Nm +can compute a thermal observable, like temperature or flux, at a probe point and +date or the mean value of an observable over a given surface, volume, or time +range. +When a time range +.Ar t1 , Ns Ar t2 +is provided, the computed value is the mean value over the time range. +To compute the value at a given time, simply provide a single value +.Ar t . +In addition, +.Nm +gives access to the evaluation of the propagator (a.k.a the Green function). +The propagator is of great value for thermicist engineers as it gives some +crucial information to analyse heat transfers in the system. +It helps engineers answer questions like +.Dq Where from does the heat come at this location? . +Propagators seamlessly aggregate all the provided geometrical and physical +information on the system in an unbiased and very-fast statistical model. +.Pp +.Nm +also provides two additional functionalities: converting the +.Xr stardis-input 5 geometry into a VTK file and rendering an infrared image of +the submitted system. +.Pp +.Nm Ns ' +algorithms are based on state-of-the-art Monte Carlo method applied to radiative +transfer physics (Delatorre et al. 2014) combined with conduction's +statistical formulation (Kac 1949 and Muller 1956). +Monte Carlo algorithms associated with convective and conductive processes +consist in sampling heat paths: this can be seen as an extension of Monte Carlo +algorithms that solve monochromatic radiative transfer. +The radiative transfer algorithm, based on the Picard method, is also based on +sampling radiative paths. +However, since +.Nm +solves the spectrally integrated radiative transfer, the process can be +recursive: secondary heat paths (convective, conductive and radiative) may be +necessary along the sampling of an initial radiative path. +The solution may not be sufficiently converged with a Picard order equal to 1 in +the presence of high temperature gradients. +Increasing the Picard order may be necessary in this case, until the required +convergence is reached. +.Pp +One of the key features of +.Nm +is that its algorithms are not based on a volumetric mesh of the system: +only the representation of its interfaces is required. +And these are used only as a description of the system, not as a basis +for calculation, whose discretization would have an impact on the +accuracy of estimates. +.Pp +.Nm +implements mixed parallelism. +On a single computer (that is, a node), it uses shared memory parallelism while +it relies on Message Passing Interface (MPI) to parallelize calculations between +multiple nodes. +.Nm +can therefore be launched either directly or via a process launcher such as +.Xr mpirun 1 +to distribute the calculation on several computers. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a Ar diff_algo +Define the diffusion algorithm to be used when sampling a conductive +path. +The default diffusion algorithm is +.Cm dsphere . +.Pp +The diffusion algorithms are as follows: +.Bl -tag -width Ds +.It Cm dsphere +Use the delta sphere algorithm, in which Brownian motion is approximated +by a random walk of random delta steps. +The algorithm is consistent with respect to the +.Ar delta +parameter, i.e. Brownian motion is estimated exactly with +.Ar delta +tending towards 0. +This numerical parameter +.Ar delta +is defined by solid and can be varied in +time and space to handle the spatio-temporal temperature gradient +without prohibitively increasing computation time +.Pq see Xr stardis-input 1 . +.It Cm wos +Use the Walk on Sphere algorithm to estimate Brownian motion. +Although a numerical parameter is required to define the distance at +which the random walk is considered to have reached the boundary, it can +be assumed that this algorithm estimates Brownian motion without any +bias with respect to numerical uncertainty. +Indeed, the aforementioned distance can be set to the computer's +numerical accuracy without any significant impact on performance. +.El +.It Fl D Ar path_type , Ns Ar files_name_prefix +Write sampled heat paths of the given +.Ar path_type +to files in VTK format, one file per path. +Possible values for +.Ar path_type +are +.Cm error +.Pq write paths ending in error , +.Cm success +.Pq write successful paths , +and +.Cm all +.Pq write all paths . +Actual file names are produced by appending +.Ar files_name_prefix +and the path rank starting at index +.Li 00000000 , +and possibly followed by +.Li _err +for failure paths +.Pq e.g. Pa prefix00000000.vtk , Pa prefix00000001_err.vtk +.It Fl d Ar file_base_name +Write the geometry to a file in VTK format along with various properties, +including possible errors. +Also possibly write some problematic parts of the geometry (if any) in OBJ +format. +Possible parts are overlapping triangles, riangles with property conflicts, and +triangles with merge errors. +The various file are all named after the provided base name. +If this option is used, no computation occurs. +.Pp +Using this option in conjunction with an option that +specifies a compute region +.Pq i.e. Fl F , Fl S , Fl s +has the effect to include the region in the VTK output. +.It Fl e +Use extended format to output Monte Carlo results. +Can only be used in conjunction with options that compute a single Monte-Carlo +.Pq Fl F , Fl m , Fl P , Fl p No or Fl s No without options Fl g No or Fl G . +.It Fl F Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the mean flux on a given 2D surface at a given time, the surface +being defined as the front sides of the triangles in the provided STL +file. +These triangles are not added to the geometry, but must be part of it. +Flux is accounted positive when going from the front side to the back +side, at a single-triangle level. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +The surface does not need to be connex. +.It Fl G Pa green_bin Ns Op , Ns Pa green_ascii +Compute the Green function at the specified time and write it to a binary file. +If a +.Pa green_ascii +file name is provided, information on heat paths' ends is also written in this +second file in ascii csv format. +.Pp +This option can only be used in conjunction with one these options: +.Fl p , Fl P , Fl m , Fl s +and cannot be used in conjunction with option +.Fl D . +.Pp +The resulting file can be further used through the +.Xr sgreen 1 +command to apply different temperature, flux or volumic power values. +.It Fl g +Compute the Green function at the specified time and write it in ASCII to +standard output. +This option can only be used in conjunction with one these options: +.Fl p , Fl P , Fl m , Fl s +and cannot be used in conjunction with option +.Fl D . +.It Fl h +Output short help and exit. +.It Fl I Ar initial_time +Define initial time in seconds. +It can take any value between +/- infinity. +The default initial time is 0. +.It Fl i +Disable internal radiative exchanges. +External radiative exchanges are still processed, i.e. the external +source. +.It Fl L Pa interface_probes +Defines a set of interface probes for which +.Nm +calculates the temperature. +The argument file lists the interface probe points. +Each line of this file describes a probe point using the same grammar as +that used to describe a single interface probe +.Pq see Fl P No option . +In addition to this syntax, characters behind the hash mark +.Pq Li # +are considered comments and are therefore ignored, as are empty lines, +i.e. lines with no characters at all or composed solely of spaces and +tabs. +.Pp +Note that this option parallelizes the calculation of the probe list, +and not the calculation of each individual probe. +Its use is therefore more advantageous in terms of load distribution +when the number of probes to be evaluated is large, compared with the +cost of calculating a single probe point. +.It Fl M Pa system +Read a text file containing a possibly partial description of the system. +Can include programs, media enclosures and boundary conditions. +Media and boundaries can appear in any order, but programs must be defined +before their first reference. +Refer to +.Xr stardis-input 5 +for a full description of the file format. +Can be used more than once if the description is split across different files. +.It Fl m Ar medium_name Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the mean temperature in a given medium at a given time. +The medium name must be part of the +.Pa system +description. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +The medium region does not need to be connex. +.It Fl o Ar picard_order +Determine the iteration level used with the Picard method to deal with +non-linear radiative transfer accross the model. +By default +.Ar picard_order +is set to @STARDIS_ARGS_DEFAULT_PICARD_ORDER@. +Note that a Picard order greater than 1 is incompatible both with Green +computations and systems including volumic power sources or non zero flux at a +boundary. +.It Fl P Ar x , Ns Ar y , Ns Ar z Ns Oo , Ns Ar time Ns Oo , Ns Ar time Oc Oc \ +Ns Op : Ns Ar side_indicator +Compute the temperature at the given probe on an interface at a given time. +If the probe is on an interface where a thermal contact resistance is defined, +it is mandatory to provide a side indicator +.Pq either Cm FRONT , Cm BACK , No or a medium name , +as the temperature differs between the two sides. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +The probe is supposed to be on an interface and is moved to the closest point of +the closest interface before the computation starts. +The probe coordinates must be in the same system as the geometry. +.It Fl p Ar x , Ns Ar y , Ns Ar z Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the temperature at the given probe at a given time. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +The probe must be in a medium. +The probe coordinates must be in the same system as the geometry. +.It Fl R Ar rendering_opt Ns Op : Ns Ar rendering_opt No ... +Render an infrared image of the system through a pinhole camera. +One can use all-default sub-options by simply providing the colon character +.Pq Li \&: +alone as an argument. +Please note that the camera position must be outside the geometry or in a fluid. +.Pp +The rendering options are as follows: +.Bl -tag -width Ds +.It Cm file= Ns Pa output_file +File name to use to write the infrared image to. +If no file name is provided, the result is written to standard output. +.It Cm fmt= Ns Ar image_file_format +Format of the image file in output. +Can be +.Cm VTK , +or +.Cm HT +.Pq see Xr htrdr-image 5 No and Xr htpp 1 . +Default +.Ar image_file_format +is @STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT@. +.It Cm fov= Ns Ar angle +Vertical field of view of the camera in [30,120] degrees. +The default field of view is @STARDIS_ARGS_DEFAULT_RENDERING_FOV@ degrees. +.It Cm img= Ns Ar width Ns x Ns Ar height +Image definition. +Default is +@STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH@x@STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT@. +.It Cm pos= Ns Ar x , Ns Ar y , Ns Ar z +Camera position. +Default is @STARDIS_ARGS_DEFAULT_RENDERING_POS@ unless +.Cm tgt +is not defined, in which case the position is automatically calculated to ensure +that the entire scene is visible. +.It Cm spp= Ns Ar samples_per_pixel +Number of samples to solve the Monte Carlo estimation of each pixel. +Default is @STARDIS_ARGS_DEFAULT_RENDERING_SPP@. +.It Cm t= Ns Ar time , Ns Op Ns Ar time +Rendering time. +Default is @STARDIS_ARGS_DEFAULT_RENDERING_TIME@. +.It Cm tgt= Ns Ar x , Ns Ar y , Ns Ar z +Targeted position. +Default is @STARDIS_ARGS_DEFAULT_RENDERING_TGT@ unless +.Cm pos +is not defined, in which case the targeted position is automatically calculated +to ensure that the entire scene is visible. +.It Cm up= Ns Ar x , Ns Ar y , Ns Ar z +Upward vector that the top of the camera is pointing towards. +Default is @STARDIS_ARGS_DEFAULT_RENDERING_UP@. +.El +.It Fl S Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the by-triangle mean temperature on a given 2D +.Pa surface +at a given time, +the +.Pa surface +defined as the front sides of the triangles in the provided STL file. +These triangles are not added to the geometry, but must be part of it. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +The +.Pa surface +does not need to be connex. +.It Fl s Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the mean temperature on a given 2D +.Pa surface +at a given time, the +.Pa surface +being defined as the front sides of the triangles in the provided STL file. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. +These triangles are not added to the geometry, but must be part of it. +The +.Pa surface +does not need to be connex. +.It Fl t Ar threads_count +Advice on the number of threads to use. +By default, +.Nm +uses many threads as processor cores. +.It Fl V Ar verbosity_level +Set the verbosity level. +Possible values are +.Li 0 Pq no message , +.Li 1 Pq error messages only , +.Li 2 error and warning messages , +and +.Li 3 Pq error, warning and informative messages . +All the messages are written to standard error. +Default is @STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL@. +.It Fl v +Output version information and exit. +.It Fl X Pa output_rng +Write the random generator's internal state, as it is at the end of the +computation, to the provided file. +.It Fl x Pa input_rng +Read the provided file and use its content to initialize the random generator's +internal state. +Used in conjunction with the +.Fl X +option, this can be used to ensure statistical independence between subsequent +computations. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +Preprocess the system as described in +.Dq Pa scene 5.txt +when intending to compute the mean flux on the triangles from the file +.Pa edge.stl , +and write its geometry in the file +.Pa scene.vtk . +Verbosity level is set to +.Ar 3 : +.Pp +.Dl stardis -M "scene 5.txt" -F edge.stl -d -V 3 > scene.vtk +.Pp +Compute the temperature at the probe point +.Ar 0 , Ns Ar 0.5 , Ns Ar 0 +at steady state. +The system is read from the file +.Pa model.txt +and the number of samples is set to +.Ar 1000000 : +.Pp +.Dl stardis -M model.txt -p 0,0.5,0 -n 1000000 +.Pp +Compute the mean temperature in the medium +.Ar med05 +at +.No t= Ns Ar 100 Ns s . +The system is read from the file +.Pa model.txt +and the result is output with extended format +.Pq option Fl e : +.Pp +.Dl stardis -M model.txt -m med05,100 -e +.Pp +Compute the temperature at the probe point +.Ar 0 , Ns Ar 0 , Ns Ar 0 +at +.No t= Ns Ar 2500 . +The system is read from the 2 files +.Pa media.txt +and +.Pa bounds.txt , +and the number of samples is set to +.Ar 1000000 : +.Pp +.Dl stardis -M media.txt -M bounds.txt -p 0,0,0,2500 -n 1000000 +.Pp +Compute the mean temperature at the probe point +.Ar 1 , Ns Ar 2.5 , Ns Ar 0 +over the +.Ar 50 , Ns Ar 5000 +time range. +The system is read from the file +.Pa model.txt : +.Pp +.Dl stardis -M model.txt -p 1,2.5,0,50,5000 +.Pp +Compute 3 probe temperatures, ensuring statistical independence: +.Bd -literal -offset Ds +stardis -M model.txt -p 1,1.5,0,50,5000 -Xstate1 +stardis -M model.txt -p 1,2.5,0,50,5000 -xstate1 -Xstate2 +stardis -M model.txt -p 1,3.5,0,50,5000 -xstate2 +.Ed +.Pp +Use +.Xr mpirun 1 +to launch +.Nm +on several hosts defined in the my_hosts file. +Render the system as described in +.Pa scene.txt +with default settings: +.Pp +.Dl mpirun --hostfile my_hosts stardis -M scene.txt -R\&: +.Pp +Render the system as described in +.Pa scn.txt +at +.Ar 100 +seconds +Using 2 samples per pixel +for an image of +.Ar 800 No by Ar 600 +pixels +saved in +.Xr htrdr-image 5 +format +and all other settings set to their default values. +The output is redirected to the +.Pa img.ht +file. +If the computation encounters erroneous heat paths, they will be dumped to VTK +files named +.Pa err_path_00000000.vtk , err_path_00000001.vtk , +etc. +The image file is then post-processed using +.Xr htpp 1 +with default settings to obtain a png file: +.Bd -literal -offset Ds +stardis -M scn.txt \\ + -R t=100:spp=2:img=800x600:fmt=ht \\ + -D error,err_path_ \\ + > img.ht +htpp -o img.pgn -v -m default img.ht +.Ed +.Pp +Compute the Green function that computes the temperature at the probe point +.Ar 0 , Ns Ar 0 , Ns Ar 0 +at steady state. +The system is read from the file +.Pa model.txt +and the Green function is written to the +.Pa probe.green +file and the heat paths' ends are written to the +.Pa probe_ends.csv +file: +.Pp +.Dl stardis -M model.txt -p 0,0,0 -G probe.green,probe_ends.csv +.Sh SEE ALSO +.Xr htpp 1 , +.Xr mpirun 1 , +.Xr sgreen 1 , +.Xr htrdr-image 5 , +.Xr stardis-input 5 , +.Xr stardis-output 5 +.Rs +.%A Léa Penazzi et al. +.%T Path integrals formulations leading to propagator evaluation for coupled \ +linear physics in large geometric models +.%J Computer Physics Communications +.%V 294 +.%D 2024 +.%U https://doi.org/10.1016/j.cpc.2023.108911 +.Re +.Rs +.%A Mégane Bati et al. +.%T Coupling Conduction, Convection and Radiative Transfer in a Single \ +Path-Space: Application to Infrared Rendering +.%J ACM Transactions on Graphics +.%V 42 +.%N 4 +.%D August 2023 +.%U https://doi.org/10.1145/3592121 +.Re +.Rs +.%A Jean Marc Tregan et al. +.%T Coupling radiative, conductive and convective heat-transfers in a single \ +Monte Carlo algorithm: A general theoretical framework for linear situations +.%J PLOS ONE +.%V 18 +.%N 4 +.%D 2023 +.%U https://doi.org/10.1371/journal.pone.0283681 +.Re +.Rs +.%A Jérémie Delatorre et al. +.%T Monte Carlo advances and concentrated solar applications +.%J Solar Energy +.%V 103 +.%P 653--681 +.%D 2014 +.%U https://doi.org/10.1016/j.solener.2013.02.035 +.Re +.Rs +.%A Abdolhossein Haji-Sheikh +.%A Ephraim Maurice Sparrow +.%T The floating random walk and its applications to Monte-Carlo \ +solutions of heat equations +.%J SIAM Journal on Applied Mathematics +.%V 14 +.%N 2 +.%P 370--389 +.%D 1966 +.Re +.Rs +.%A Mervin E Muller +.%T Some continuous Monte Carlo methods for the Dirichlet problem +.%J The Annals of Mathematical Statistics +.%P 569--589 +.%D 1956 +.Re +.Rs +.%A Mark Kac +.%T On distributions of certain Wiener functionals +.%J Transactions of the American Mathematical Society +.%V 65 +.%N 1 +.%P 1--13 +.%D 1949 +.Re +.Sh STANDARDS +.Rs +.%B The VTK User's Guide +.%O Simple Legacy Formats +.%I Kitware, Inc +.%N 11 +.%D 2010 +.%P 470--482 +.Re +.Pp +.Rs +.%A OpenMP Architecture Review Board +.%D March 2002 +.%T OpenMP C and C++ Application Interface +.%O version 2.0 +.Re +.Pp +.Rs +.%A Message Passing Interface Forum +.%D July 1997 +.%T MPI-2: Extensions to The Message-Passing Interface +.Re +.Pp +.Rs +.%T The StL Format: Standard Data Format for Fabbers +.%A Marshall Burns +.%D 1993 +.%U https://www.fabbers.com/tech/STL_Format +.Re diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in @@ -1,367 +0,0 @@ -// Copyright (C) 2018-2023 |Méso|Star> -// -// 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/>. - -:toc: - -stardis(1) -=========== - -NAME ----- -stardis - statistical solving of coupled thermal systems - -SYNOPSIS --------- -[verse] -*stardis* [_option_] -*stardis* *-M* <__file__> [_option_] - -DESCRIPTION -*stardis* solves coupled thermal systems: conductive, convective and -radiative transfers are solved together. The physical model used for -conduction is the local unstationary heat conduction equation. -Convection fluxes are assumed to be linear with temperature, and radiation -is assumed to be integrated over the whole thermal spectral range, -therefore radiative heat fluxes are proportionnal to a difference of -temperatures to the power 4. *stardis* can deal with complex geometries as -well as high-frequency external solicitations over a very long period of time, -relative to the characteristic time of the system. The provided system -description should comply with the *stardis-input*(5) format. - -*stardis* can compute a thermal observable, like temperature or flux, at a -probe point and date or the mean value of an observable over a given surface, -volume, or time range. When a time range *t1, t2* is provided, the computed -value is the mean value over the time range. To compute the value at a given -time, simply provide a single value *t*. In addition, *stardis* gives access to -the evaluation of the propagator (a.k.a the *Green function*). - -The propagator is of great value for thermicist engineers as it gives some -crucial information to analyse heat transfers in the system. It helps engineers -answer questions like _"Where from does the heat come at this location?"_. -Propagators seamlessly aggregate all the provided geometrical and physical -information on the system in an unbiased and very-fast statistical model. - -*stardis*(1) also provides two additional functionalities: converting the -*stardis-input*(5) geometry into a VTK file and rendering an infrared image -of the submitted system. - -Stardis' algorithms are based on state-of-the-art Monte-Carlo method applied -to radiative transfer physics (Delatorre [1]) combined with conduction's -statistical formulation (Kac [2] and Muller [3]). Thanks to recent advances in -computer graphics technology which has already been a game changer in the -cinema industry (FX and animated movies), this theoretical framework can now -be practically used on the most geometrically complex systems. - -Monte-Carlo algorithms associated with convective and conductive processes -consist in sampling heat paths: this can be seen as an extension of -Monte-Carlo algorithms that solve monochromatic radiative transfer. -The radiative transfer algorithm, based on the Picard method, is also based -on sampling radiative paths. However, since stardis solves the spectrally -integrated radiative transfer, the process can be recursive: secondary heat -paths (convective, conductive and radiative) may be necessary along the -sampling of an initial radiative path. - -The solution may not be sufficiently converged with a Picard order equal -to 1 in the presence of high temperature gradients. -Increasing the Picard order may be necessary in this case, until the -required convergence is reached. - -A main property of this approach is that the resulting algorithms do -not rely on a volumic mesh of the system: only the representation -of interfaces is necessary. - -*stardis* supports shared memory parallelism and relies on the Message -Passing Interface specification [4] to parallelise its computations in a -distributed memory environment; it can thus be run either directly or through -a MPI process launcher like *mpirun(1)*. - -[1] Delatorre et al., Monte Carlo advances and concentrated solar applications, -Solar Energy, 2014 - -[2] Kac, On Distributions of Certain Wiener Functionals. The Annals of -Mathematical Statistics, 1949. - -[3] Muller, Some continuous Monte-Carlo Methods for the Dirichlet Problem, -Transactions of the American Mathematical Society, 1956. - -[4] MPI specifications - https://www.mpi-forum.org/docs/ - -MANDATORY OPTIONS ------------------ -*-M* _file_:: - Read a text file containing a possibly partial description of the system. - Can include programs, media enclosures and boundary conditions. Media and - boundaries can appear in any order, but programs must be defined before their - first reference. Refer to *stardis-input(5)* for details. - Can be used more than once if the description is split across different - files. - -EXCLUSIVE OPTIONS ------------------ -*-p* _x,y,z[,time[,time]]_:: - Compute the temperature at the given probe at a given time. By default the - compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The probe must - be in a medium. The probe coordinates must be in the same system as the - geometry. - -*-P* _x,y,z[,time[,time]][:side_indicator]_:: - Compute the temperature at the given probe on an interface at a given time. - If the probe is on an interface where a thermal contact resistance is - defined, it is mandatory to provide a side indicator (either FRONT, BACK, or - a medium name), as the temperature differs between the two sides. - By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The - probe is supposed to be on an interface and is moved to the closest point of - the closest interface before the computation starts. The probe coordinates - must be in the same system as the geometry. - -*-m* _medium_name[,time[,time]]_:: - Compute the mean temperature in a given medium at a given time. The medium - name must be part of the system description. By default the compute time - is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The medium region does not need - to be connex. - -*-s* _file[,time[,time]]_:: - Compute the mean temperature on a given 2D region at a given time, the region - being defined as the front sides of the triangles in the provided *STL* file. - By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. - These triangles are not added to the geometry, but must be part of it. The - region does not need to be connex. - -*-S* _file[,time[,time]]_:: - Compute the by-triangle mean temperature on a given 2D region at a given - time, the region being defined as the front sides of the triangles in the - provided *STL* file. These triangles are not added to the geometry, but must - be part of it. By default the compute time is - @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The region does not need to be connex. - -*-F* _file[,time[,time]]_:: - Compute the mean flux on a given 2D region at a given time, the region - being defined as the front sides of the triangles in the provided *STL* file. - These triangles are not added to the geometry, but must be part of it. Flux - is accounted positive when going from the front side to the back side, at a - single-triangle level. By default the compute time is - @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The region does not need to be connex, - but it can currently only include geometry appearing in description lines - starting with H_BOUNDARY_FOR_SOLID, H_BOUNDARY_FOR_FLUID, - F_BOUNDARY_FOR_SOLID or SOLID_FLUID_CONNECTION (see *stardis-input*(5)). - -*-R* [__sub-option__:...]:: - Render an infrared image of the system through a pinhole camera. One can use - all-default sub-options by simply providing the colon character (*:*) alone - as an argument. Please note that the camera position must be outside the - geometry or in a fluid. - Available sub-options are: - - **file=**_output_file_;; - File name to use to write the infrared image to. If no file name is - provided, the result is written to _standard output_. - - **fmt=**_image_file_format_;; - Format of the image file in output. Can be *VTK*, or *HT* (see - htrdr-image(5) and htpp(1)). Default _image_file_format_ is - @STARDIS_ARGS_DEFAULT_RENDERING_OUTPUT_FILE_FMT@. - - **fov=**_angle_;; - Horizontal field of view of the camera in [30, 120] degrees. By default - _angle_ is @STARDIS_ARGS_DEFAULT_RENDERING_FOV@ degrees. - - **img=**_width_**x**_height_;; - Definition of the rendered image in pixels. By default the image definition - is @STARDIS_ARGS_DEFAULT_RENDERING_IMG_WIDTH@x@STARDIS_ARGS_DEFAULT_RENDERING_IMG_HEIGHT@. - - **pos=**_x_**,**_y_**,**_z_;; - Position of the camera. By default it is set to - { @STARDIS_ARGS_DEFAULT_RENDERING_POS@ } or it is automatically computed to - ensure that the whole scene is visible, whether *tgt* is set or not, - respectively. - - **spp=**_samples-count_;; - Number of samples per pixel. - By default, use @STARDIS_ARGS_DEFAULT_RENDERING_SPP@ samples per pixel. - - **t=**_time[,time]_;; - Rendering time. By default the rendering time is - @STARDIS_ARGS_DEFAULT_RENDERING_TIME@. - - **tgt=**_x_**,**_y_**,**_z_;; - Position targeted by the camera. By default, it is set to - { @STARDIS_ARGS_DEFAULT_RENDERING_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. By default, it is set to - { @STARDIS_ARGS_DEFAULT_RENDERING_UP@ }. - -OTHER OPTIONS -------------- -*-d*:: - Write the geometry to _standard output_ in VTK format along with various - properties, including possible errors. If this option is used, no - computation occurs. -+ -Using this option in conjunction with an option that -specifies a compute region (-F, -S, -s) has the effect to include the -region in the output. This option cannot be used in conjunction with other -options that write to _standard output_ (-g, -h, -R, -v). - -*-D* _type,files_name_prefix_:: - Write sampled heat paths of the given *type* to files in VTK format, one - file per path. Possible values for *type* are *error* (write paths ending - in error), *success* (write successful paths), and *all* (write all paths). - Actual file names are produced by appending *files_name_prefix* and the path - rank starting at index 00000000, and possibly followed by *_err* for failure - paths: prefix00000000.vtk, prefix00000001_err.vtk, ... -+ -This option can only be used in conjunction with options that compute a -result (-F, -m, -P, -p, -R, -S, -s) and cannot be used in conjunction with -options -g or -G. - -*-e*:: - Use extended format to output Monte-Carlo results. Can only be used in - conjunction with options that compute a single Monte-Carlo (-F, -m, -P, -p, - or -s without options -g or -G). - -*-g*:: - Compute the Green function at the specified time and write it in ASCII to - _standard output_. -+ -This option can only be used in conjunction with one these options: -p, -P, --m, -s and cannot be used in conjunction with option -D. - -*-G* _file_name_[,__file_name__]:: - Compute the Green function at the specified time and write it to a binary - file. If a second file name is provided, information on heat paths' ends - is also written in this second file in ascii csv format. -+ -This option can only be used in conjunction with one these options: -p, -P, --m, -s and cannot be used in conjunction with option -D. -+ -The resulting file can be further used through the *sgreen*(1) command to apply -different temperature, flux or volumic power values. - -*-h*:: - Output short help and exit. - -*-n* _samples-count_:: - Number of Monte-Carlo samples. By default *samples-count* is set to - @STARDIS_ARGS_DEFAULT_SAMPLES_COUNT@. - -*-o* _Picard_order_:: - Determine the iteration level used with the Picard method to deal with - non-linear radiative transfer accross the model. - By default *Picard_order* is set to @STARDIS_ARGS_DEFAULT_PICARD_ORDER@. - Note that a Picard order greater than 1 is incompatible both with Green - computations and models including volumic power sources or non zero flux - at a boundary. - -*-t* _threads-count_:: - Hint on the number of threads to use. By default use as many threads as CPU - cores. - -*-v*:: - Output version information and exit. - -*-V* _level_:: - Set the verbosity level. Possible values are *0* (no message), *1* (error - messages only), *2* (error and warning messages), and *3* (error, warning - and informative messages). All the messages are written to _standard error_. - Default verbosity *level* is @STARDIS_ARGS_DEFAULT_VERBOSE_LEVEL@. - -*-x* _file_name_:: - Read the provided file and use its content to initialize the random - generator's internal state. Used in conjunction with the *-X* option, this - can be used to ensure statistical independence between subsequent - computations. - -*-X* _file_name_:: - Write the random generator's internal state, as it is at the end of the - computation, to the provided file. - -EXAMPLES --------- -Preprocess the system as described in *scene 5.txt* when intending to compute -the mean flux on the triangles from the file *edge.stl*, and write its geometry -in the file *scene.vtk*. Verbosity level is set to *3*: - - $ stardis -M "scene 5.txt" -F edge.stl -d -V 3 > scene.vtk - -Compute the temperature at the probe point *0, 0.5, 0* at steady state. The -system is read from the file *model.txt* and the number of samples is set to -*1000000*: - - $ stardis -M model.txt -p 0,0.5,0 -n 1000000 - -Compute the mean temperature in the medium *med05* at *t=100* s. The system is -read from the file *model.txt* and the result is output with extended format: - - $ stardis -M model.txt -m med05,100 -e - -Compute the temperature at the probe point *0, 0, 0* at *t=2500*. The system is -read from the 2 files *media.txt* and *bounds.txt* and the number of samples is -set to *1000000*: - - $ stardis -M media.txt -M bounds.txt -p 0,0,0,2500 -n 1000000 - -Compute the mean temperature at the probe point *1, 2.5, 0* over the *50, 5000* -time range. The system is read from the file *model.txt*: - - $ stardis -M model.txt -p 1,2.5,0,50,5000 - -Compute 3 probe temperatures, ensuring statistical independence: - - $ stardis -M model.txt -p 1,1.5,0,50,5000 -Xstate1 - $ stardis -M model.txt -p 1,2.5,0,50,5000 -xstate1 -Xstate2 - $ stardis -M model.txt -p 1,3.5,0,50,5000 -xstate2 - - -Use mpirun(1) to launch stardis on several hosts defined in the my_hosts file. -Render the system as described in *scene.txt* with default settings: - - $ mpirun --hostfile my_hosts stardis -M scene.txt -R : - -Render the system as described in *scn.txt* at *t=100*, *spp=2*, -*img=800x600*, with output format *fmt=ht* and all other settings set to their -default values. The output is redirected to the *img.ht* file. If the -computation encounters erroneous heat paths, they will be dumped to VTK files -named err_path_00000000.vtk, err_path_00000001.vtk, etc. The image file is then -post-processed using *htpp*(1) with default settings to obtain a png file. - - $ stardis -M scn.txt -R t=100:spp=2:img=800x600:fmt=ht \ - -D error,err_path_ > img.ht - $ htpp -o img.pgn -v -m default img.ht - -Compute the Green function that computes the temperature at the probe point -*0, 0, 0* at steady state. The system is read from the file *model.txt* and -the Green function is written to the *probe.green file* and the heat paths' -ends are written to the *probe_ends.csv* file: - - $ stardis -M model.txt -p 0,0,0 -G probe.green,probe_ends.csv - -COPYRIGHT ---------- -Copyright &copy; 2018-2023 |Méso|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 --------- -*stardis-input*(5), -*stardis-output*(5), -*sgreen*(1), -*htpp*(1) -*htrdr-image*(5) -*mpirun(1)* diff --git a/make.sh b/make.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# 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/>. + +set -e + +install() +{ + prefix=$1 + shift 1 + + mkdir -p "${prefix}" + + for i in "$@"; do + dst="${prefix}/${i##*/}" + + if cmp -s "${i}" "${dst}"; then + printf "Up to date %s\n" "${dst}" + else + printf "Installing %s\n" "${dst}" + cp "${i}" "${prefix}" + fi + done +} + +"$@" diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -14,9 +14,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef STARDIS_ENABLE_MPI -#define _POSIX_C_SOURCE 200112L + #define _POSIX_C_SOURCE 200112L #endif +#include <star/sg3d.h> + #include "stardis-app.h" #include "stardis-args.h" #include "stardis-description.h" @@ -37,12 +39,13 @@ #include <rsys/logger.h> #include <rsys/double2.h> #include <rsys/double3.h> +#include <rsys/dynamic_array_double.h> #include <string.h> #ifdef STARDIS_ENABLE_MPI -#include <stdio.h> -#include <mpi.h> + #include <stdio.h> + #include <mpi.h> #endif static const struct dummies DUMMIES_NULL = DUMMIES_NULL__; @@ -103,7 +106,11 @@ check_delta_and_create_solid external = 1; } else { double d = header.volume / (header.area * 6); - ASSERT(d >= 0); + if(d <= 0) { + /* Should not */ + res = RES_BAD_OP; + goto error; + } delta_range[0] = MMIN(delta_range[0], d); delta_range[1] = MMAX(delta_range[1], d); } @@ -222,7 +229,8 @@ stardis_init res_T tmp_res, res = RES_OK; struct sg3d_sdisXd_scene_create_context create_context; struct htable_intface htable_interfaces; - struct str str; + struct str str, name; + FILE* f = NULL; unsigned i, vcount, tcount, ocount, count; int is_for_compute; struct sdis_device_create_args dev_args = SDIS_DEVICE_CREATE_ARGS_DEFAULT; @@ -230,7 +238,8 @@ stardis_init ASSERT(args && logger && allocator && stardis); str_init(allocator, &str); - /* Init everithing that cannot fail */ + str_init(allocator, &name); + /* Init everything that cannot fail */ stardis->dummies = DUMMIES_NULL; stardis->logger = logger; stardis->allocator = allocator; @@ -245,6 +254,7 @@ stardis_init stardis->counts = COUNTS_NULL; init_camera(stardis->allocator, &stardis->camera); str_init(stardis->allocator, &stardis->solve_name); + str_init(stardis->allocator, &stardis->dump_model_filename); str_init(stardis->allocator, &stardis->paths_filename); str_init(stardis->allocator, &stardis->bin_green_filename); str_init(stardis->allocator, &stardis->end_paths_filename); @@ -254,14 +264,15 @@ stardis_init darray_size_t_init(stardis->allocator, &stardis->compute_surface.primitives); darray_sides_init(stardis->allocator, &stardis->compute_surface.sides); darray_uint_init(stardis->allocator, &stardis->compute_surface.err_triangles); + darray_probe_boundary_init(stardis->allocator, &stardis->probe_boundary_list); stardis->compute_surface.area = 0; stardis->samples = args->samples; stardis->nthreads = args->nthreads; stardis->picard_order = args->picard_order; stardis->scale_factor = -1; /* invalid value */ - stardis->trad = STARDIS_DEFAULT_TRAD; - stardis->trad_ref = STARDIS_DEFAULT_TRAD_REFERENCE; - stardis->trad_def = 0; + stardis->radenv = RADIATIVE_ENV_DEFAULT; + stardis->radenv_def = 0; + stardis->initial_time = args->initial_time; stardis->geometry_initialized = 0; d2(stardis->t_range, INF, -INF); stardis->dump_paths = SDIS_HEAT_PATH_NONE; @@ -269,14 +280,17 @@ stardis_init stardis->dump_paths |= SDIS_HEAT_PATH_FAILURE; if(args->dump_paths & DUMP_SUCCESS) stardis->dump_paths |= SDIS_HEAT_PATH_SUCCESS; + stardis->diff_algo = args->diff_algo; stardis->next_medium_id = 0; stardis->undefined_medium_behind_boundary_id = SENC3D_UNSPECIFIED_MEDIUM; stardis->verbose = args->verbose; + stardis->extsrc = EXTERN_SOURCE_NULL; + stardis->disable_intrad = args->disable_intrad; darray_media_ptr_init(stardis->allocator, &stardis->media); /* If a dump is expected, we won't process any computation */ is_for_compute = - (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_VTK); + (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_MODEL); dev_args.logger = stardis->logger; dev_args.allocator = stardis->allocator; @@ -303,14 +317,20 @@ stardis_init &stardis->geometry)); stardis->geometry_initialized = 1; + if(args->dump_model_filename) { + ERR(str_set(&stardis->dump_model_filename, args->dump_model_filename)); + } + if(args->mode & MODE_IR_COMPUTE) { ERR(parse_camera(stardis->logger, args->camera, stardis)); } else if(args->mode & MODE_MEDIUM_COMPUTE) { ERR(str_set(&stardis->solve_name, args->medium_name)); } - else if(args->mode & MODE_PROBE_COMPUTE_ON_INTERFACE && args->medium_name) { - ERR(str_set(&stardis->solve_name, args->medium_name)); + else if((args->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) + || (args->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE)) { + ERR(darray_probe_boundary_copy + (&stardis->probe_boundary_list, &args->probe_boundary_list)); } else if(args->mode & SURFACE_COMPUTE_MODES) { ERR(str_set(&stardis->solve_name, args->solve_filename)); @@ -334,6 +354,20 @@ stardis_init ERR(sg3d_geometry_get_unique_triangles_with_properties_conflict_count( stardis->geometry.sg3d, &count)); if(count) { + if(!str_is_empty(&stardis->dump_model_filename)) { + ERR(str_copy(&name, &stardis->dump_model_filename)); + ERR(str_append(&name, "_property_conflits.obj")); + f = fopen(str_cget(&name), "w"); + if(!f) { + logger_print(stardis->logger, LOG_ERROR, + "cannot open file '%s' for writing.\n", str_cget(&name)); + res = RES_IO_ERR; + goto error; + } + ERR(sg3d_geometry_dump_as_obj(stardis->geometry.sg3d, f, + SG3D_OBJ_DUMP_PROPERTY_CONFLICTS)); + fclose(f); f = NULL; + } logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "Property conflicts found in the model (%u triangles).\n", count); if(is_for_compute) { @@ -376,6 +410,32 @@ stardis_init } ERR(senc3d_scene_get_overlapping_triangles_count(stardis->senc3d_scn, &ocount)); if(ocount) { + if(!str_is_empty(&stardis->dump_model_filename)) { + ERR(str_copy(&name, &stardis->dump_model_filename)); + ERR(str_append(&name, "_overlapping_triangles.obj")); + f = fopen(str_cget(&name), "w"); + if(!f) { + logger_print(stardis->logger, LOG_ERROR, + "cannot open file '%s' for writing.\n", str_cget(&name)); + res = RES_IO_ERR; + goto error; + } + /* Dump vertices */ + for(i = 0; i < vcount; i++) { + double coord[3]; + ERR(senc3d_scene_get_vertex(stardis->senc3d_scn, i, coord)); + fprintf(f, "v %.16g %.16g %.16g\n", SPLIT3(coord)); + } + /* Dump triangles */ + for(i = 0; i < ocount; i++) { + unsigned id, trg[3]; + ERR(senc3d_scene_get_overlapping_triangle(stardis->senc3d_scn, i, &id)); + ERR(senc3d_scene_get_triangle(stardis->senc3d_scn, id, trg)); + fprintf(f, "f %u %u %u\n", + 1 + trg[0], 1 + trg[1], 1 + trg[2]); /* OBJ indexing starts at 1 */ + } + fclose(f); f = NULL; + } logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "Scene contains %u overlapping triangles.\n", ocount); @@ -395,8 +455,8 @@ stardis_init enum stardis_return_status rs; rs = desc->d.program->finalize(desc->d.program->prog_data); switch(rs) { - case STARDIS_SUCCESS: tmp_res = RES_OK; break; - case STARDIS_FAILURE: tmp_res = RES_BAD_ARG; break; + case STARDIS_SUCCESS: tmp_res = RES_OK; break; + case STARDIS_FAILURE: tmp_res = RES_BAD_ARG; break; default: FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); } @@ -434,7 +494,7 @@ stardis_init /* If computation is on a volume, check medium is known */ if(args->mode & MODE_MEDIUM_COMPUTE) { - if(!find_medium_by_name(stardis, &stardis->solve_name, NULL)) { + if(!find_medium_by_name(stardis, str_cget(&stardis->solve_name), NULL)) { logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "Cannot find medium '%s'\n", str_cget(&stardis->solve_name)); res = RES_BAD_ARG; @@ -446,16 +506,30 @@ stardis_init struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT; ASSERT(darray_interface_ptrs_size_get(&stardis->geometry.interf_bytrg) == tcount); + + res = radiative_env_create_solver_radiative_env(&stardis->radenv, stardis); + if(res != RES_OK) goto error; + scn_args.get_indices = sg3d_sdisXd_geometry_get_indices; scn_args.get_interface = sg3d_sdisXd_geometry_get_interface; scn_args.get_position = sg3d_sdisXd_geometry_get_position; scn_args.nprimitives = tcount; scn_args.nvertices = vcount; scn_args.fp_to_meter = stardis->scale_factor; - scn_args.trad.temperature = stardis->trad; - scn_args.trad.reference = stardis->trad_ref; - d2_set(scn_args.t_range, stardis->t_range); + scn_args.t_range[0] = stardis->t_range[0]; + scn_args.t_range[1] = stardis->t_range[1]; + scn_args.source = stardis->extsrc.sdis_src; + scn_args.radenv = stardis->radenv.sdis_radenv; scn_args.context = &create_context; + + /* Setting Tmax to 0 is a way of setting the radiative coefficient to 0, and + * thus setting the probability of evolving in a radiative random walk to + * zero. */ + if(stardis->disable_intrad) { + scn_args.t_range[0] = 0; + scn_args.t_range[1] = 0; + } + res = sdis_scene_create(stardis->dev, &scn_args, &stardis->sdis_scn); if(res != RES_OK) { logger_print(stardis->logger, LOG_ERROR, @@ -465,7 +539,9 @@ stardis_init } exit: + if(f) fclose(f); str_release(&str); + str_release(&name); htable_intface_release(&htable_interfaces); return res; error: @@ -485,10 +561,15 @@ stardis_release if(stardis->sdis_scn) SDIS(scene_ref_put(stardis->sdis_scn)); if(stardis->senc3d_scn) SENC3D(scene_ref_put(stardis->senc3d_scn)); str_release(&stardis->solve_name); + str_release(&stardis->dump_model_filename); str_release(&stardis->paths_filename); str_release(&stardis->bin_green_filename); str_release(&stardis->end_paths_filename); str_release(&stardis->chunks_prefix); + + extern_source_release(&stardis->extsrc); + radiative_env_release(&stardis->radenv); + /* release non-PROGRAM descritions first */ FOR_EACH(i, 0, darray_descriptions_size_get(&stardis->descriptions)) { struct description* d = darray_descriptions_data_get(&stardis->descriptions) +i; @@ -519,6 +600,7 @@ stardis_release if(stardis->dummies.stardis_solid) { release_solid(stardis->dummies.stardis_solid, stardis->allocator); } + darray_probe_boundary_release(&stardis->probe_boundary_list); } unsigned @@ -732,7 +814,7 @@ init_geometry struct sg3d_device* sg3d_dev = NULL; ASSERT(allocator && geom); - + geom->sg3d = NULL; darray_interface_ptrs_init(allocator, &geom->interfaces); darray_interface_ptrs_init(allocator, &geom->interf_bytrg); @@ -841,16 +923,16 @@ void log_prt_fn (const char* msg, void* ctx) { -#ifdef stardis_enable_mpi +#ifdef STARDIS_ENABLE_MPI int initialized, rank = 0; #endif ASSERT(msg); (void)ctx; -#ifdef stardis_enable_mpi - chk(mpi_initialized(&initialized) == mpi_success); - if(initialized) chk(mpi_comm_rank(mpi_comm_world, &rank) == mpi_success); +#ifdef STARDIS_ENABLE_MPI + CHK(MPI_Initialized(&initialized) == MPI_SUCCESS); + if(initialized) CHK(MPI_Comm_rank(MPI_COMM_WORLD, &rank) == MPI_SUCCESS); /* only master prints */ if(rank != 0) return; #endif diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -16,7 +16,10 @@ #ifndef STARDIS_APP_H #define STARDIS_APP_H +#include "stardis-args.h" #include "stardis-description.h" +#include "stardis-extern-source.h" +#include "stardis-radiative-env.h" #include <star/sg3d.h> @@ -55,7 +58,7 @@ struct fluid; #define DELTA_AUTO INF /* Placeholder until actual value is substituted */ -#define UNKNOWN_MEDIUM_TEMPERATURE -1 /* Unknown for stardis solver is -1 */ +#define UNKNOWN_MEDIUM_TEMPERATURE SDIS_TEMPERATURE_NONE enum properties_conflict_t { NO_PROPERTY_CONFLICT, @@ -213,6 +216,7 @@ struct stardis { struct compute_surface compute_surface; /* 2D compute region when mode is [FLUX_]BOUNDARY_COMPUTE or MAP_COMPUTE */ + struct str dump_model_filename; struct str paths_filename; struct str bin_green_filename; struct str end_paths_filename; @@ -222,21 +226,27 @@ struct stardis { struct mem_allocator* allocator; struct logger* logger; struct sdis_device* dev; + struct radiative_env radenv; + int radenv_def; size_t samples; double scale_factor; - double trad, trad_ref; double t_range[2]; + double initial_time; /* [s] */ int mode; - int trad_def; unsigned nthreads; unsigned picard_order; unsigned next_medium_id; unsigned undefined_medium_behind_boundary_id; + enum sdis_diffusion_algorithm diff_algo; int dump_paths; int verbose; int geometry_initialized; int mpi_initialized; int mpi_rank; + + struct darray_probe_boundary probe_boundary_list; + struct extern_source extsrc; + int disable_intrad; /* Disable internal radiative exchanges */ }; unsigned diff --git a/src/stardis-args.c b/src/stardis-args.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -20,16 +20,17 @@ #include "stardis-default.h" #include "stardis-version.h" +#include <sdis_version.h> + #include <rsys/cstr.h> #include <rsys/double2.h> #include <rsys/double3.h> -#include <sdis_version.h> #include <rsys/logger.h> +#include <rsys/text_reader.h> #include <getopt.h> #include <stdlib.h> #include <stdio.h> -#include <ctype.h> #include <string.h> #ifdef COMPILER_GCC @@ -103,19 +104,19 @@ split_line } static char -mode_option - (const int m) +mode_option(const int m) { int found = 0; char res = '?'; if(m & MODE_DUMP_C_CHUNKS) { found++; res = 'c'; } - if(m & MODE_DUMP_VTK) { found++; res = 'd'; } + if(m & MODE_DUMP_MODEL) { found++; res = 'd'; } if(m & MODE_DUMP_PATHS) { found++; res = 'D'; } if(m & MODE_EXTENDED_RESULTS) { found++; res = 'e'; } if(m & MODE_FLUX_BOUNDARY_COMPUTE) { found++; res = 'F'; } if(m & MODE_GREEN) { found++; res = 'g'; } if(m & MODE_BIN_GREEN) { found++; res = 'G'; } if(m & MODE_DUMP_HELP) { found++; res = 'h'; } + if(m & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE) { found++; res = 'L'; } if(m & MODE_MEDIUM_COMPUTE) { found++; res = 'm'; } if(m & MODE_PROBE_COMPUTE) { found++; res = 'p'; } if(m & MODE_PROBE_COMPUTE_ON_INTERFACE) { found++; res = 'P'; } @@ -153,6 +154,238 @@ print_multiple_modes } while(m < modes); } +static res_T +parse_diff_algo + (const char* str, + struct logger* logger, + enum sdis_diffusion_algorithm* out_diff_algo) +{ + enum sdis_diffusion_algorithm diff_algo = SDIS_DIFFUSION_NONE; + res_T res = RES_OK; + ASSERT(str && out_diff_algo); + + if(!strcmp(str, "dsphere")) { + diff_algo = SDIS_DIFFUSION_DELTA_SPHERE; + } else if(!strcmp(str, "wos")) { + diff_algo = SDIS_DIFFUSION_WOS; + } else { + logger_print(logger, LOG_ERROR, + "Invalid diffusion algorithm `%s'\n", str); + res = RES_BAD_ARG; + goto error; + } + +exit: + *out_diff_algo = diff_algo; + return res; +error: + goto exit; +} + +static res_T +parse_position_and_time(const char* str, double pos[3], double time[2]) +{ + char buf[128]; + double pos_and_time[5]; + size_t len; + res_T res = RES_OK; + ASSERT(str && pos && time); + + + if(strlen(str) >= sizeof(buf)-1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate the string defining a position and, optionally, " + "a time range `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + res = cstr_to_list_double(str, ',', pos_and_time, &len, 5); + if(res != RES_OK + || len < 3 /* Invalid position */ + || len > 5 /* Too many fields */) { + fprintf(stderr, + "Error parsing position and optional time range `%s'\n", str); + res = RES_BAD_ARG; + goto error; + } + + pos[0] = pos_and_time[0]; + pos[1] = pos_and_time[1]; + pos[2] = pos_and_time[2]; + + switch(len) { + /* No time was parsed => Steady state */ + case 3: + time[0] = INF; + time[1] = INF; + break; + /* A single time was parsed => the time range is degenerated */ + case 4: + time[0] = pos_and_time[3]; + time[1] = pos_and_time[3]; + break; + /* A time range was parsed and must be not degenerated */ + case 5: + time[0] = pos_and_time[3]; + time[1] = pos_and_time[4]; + if(time[0] > time[1]) { + fprintf(stderr, "Invalid time range [%g, %g}\n", time[0], time[1]); + res = RES_BAD_ARG; + goto error; + } + break; + default: FATAL("Unreachable code\n"); break; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_side_indicator(const char* str, char side_name[STARDIS_MAX_NAME_LENGTH]) +{ + res_T res = RES_OK; + ASSERT(str && side_name); + + if(strlen(str) >= STARDIS_MAX_NAME_LENGTH) { + fprintf(stderr, + "Side indicator could not exceed %d characters `%s'\n", + STARDIS_MAX_NAME_LENGTH-1, str); + res = RES_MEM_ERR; + goto error; + } + strncpy(side_name, str, STARDIS_MAX_NAME_LENGTH); + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_probe_boundary(const char* str, struct stardis_probe_boundary* probe) +{ + char buf[128]; + char* pos_and_time = NULL; + char* side = NULL; + char* ctx = NULL; + res_T res = RES_OK; + ASSERT(str && probe); + + if(strlen(str) >= sizeof(buf)-1/*NULL char*/) { + fprintf(stderr, + "Could not duplicate string defining probe at boundary `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + pos_and_time = strtok_r(buf, ":", &ctx); + side = strtok_r(NULL, "", &ctx); + + res = parse_position_and_time(pos_and_time, probe->position, probe->time); + if(res != RES_OK) goto error; + + if(side) { + res = parse_side_indicator(side, probe->side); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +allocate_probe_boundary + (struct args* args, + struct stardis_probe_boundary** out_probe) +{ + size_t i = 0; + res_T res = RES_OK; + ASSERT(args && out_probe); + + i = darray_probe_boundary_size_get(&args->probe_boundary_list); + res = darray_probe_boundary_resize(&args->probe_boundary_list, i+1); + if(res != RES_OK) { + logger_print(args->logger, LOG_ERROR, + "Error allocating the probe on the boundary -- %s.\n", + res_to_cstr(res)); + goto error; + } + + *out_probe = darray_probe_boundary_data_get(&args->probe_boundary_list) + i; + +exit: + return res; +error: + darray_probe_boundary_resize(&args->probe_boundary_list, i); /* Deallocate */ + goto exit; +} + +static res_T +parse_probe_boundary_list + (const char* filename, + struct logger* logger, + struct mem_allocator* allocator, + struct darray_probe_boundary* list) +{ + struct txtrdr* txtrdr = NULL; + res_T res = RES_OK; + ASSERT(filename && list); + + res = txtrdr_file(allocator, filename, '#', &txtrdr); + if(res != RES_OK) goto error; + + for(;;) { + struct stardis_probe_boundary probe = STARDIS_PROBE_BOUNDARY_NULL; + const char* line = NULL; + + res = txtrdr_read_line(txtrdr); + if(res != RES_OK) { + logger_print(logger, LOG_ERROR, + "%s: could not read the line `%lu' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + res_to_cstr(res)); + goto error; + } + + if(!(line = txtrdr_get_cline(txtrdr))) goto exit; /* No line to parse */ + + res = parse_probe_boundary(line, &probe); + if(res != RES_OK) goto error; + + res = darray_probe_boundary_push_back(list, &probe); + if(res != RES_OK) { + logger_print(logger, LOG_ERROR, + "%s:%lu: error registering the probe on the boundary -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + res_to_cstr(res)); + goto error; + } + } + + if(!darray_probe_boundary_size_get(list)) { + logger_print(logger, LOG_ERROR, + "The file `%s' does not list any probes on the boundary.\n", + filename); + res = RES_BAD_ARG; + goto error; + } + +exit: + if(txtrdr) txtrdr_ref_put(txtrdr); + return res; +error: + darray_probe_boundary_clear(list); + goto exit; +} + /******************************************************************************* * Public Functions ******************************************************************************/ @@ -170,7 +403,7 @@ print_version "disabled.\n", #endif STARDIS_APP_VERSION_MAJOR, STARDIS_APP_VERSION_MINOR, STARDIS_APP_VERSION_PATCH, - Stardis_VERSION_MAJOR, Stardis_VERSION_MINOR, Stardis_VERSION_PATCH); + SDIS_VERSION_MAJOR, SDIS_VERSION_MINOR, SDIS_VERSION_PATCH); } res_T @@ -196,9 +429,11 @@ init_args args->samples = STARDIS_DEFAULT_SAMPLES_COUNT; args->nthreads = SDIS_NTHREADS_DEFAULT; args->picard_order = STARDIS_DEFAULT_PICARD_ORDER; + args->diff_algo = SDIS_DIFFUSION_DELTA_SPHERE; d2(args->pos_and_time+3, STARDIS_DEFAULT_COMPUTE_TIME, STARDIS_DEFAULT_COMPUTE_TIME); args->verbose = STARDIS_DEFAULT_VERBOSE_LEVEL; + darray_probe_boundary_init(allocator, &args->probe_boundary_list); end: *out_args = args; @@ -214,120 +449,25 @@ release_args(struct args* args) { ASSERT(args); darray_str_release(&args->model_files); + darray_probe_boundary_release(&args->probe_boundary_list); free(args); } void -short_help - (FILE* stream, - const char* prog) +usage(FILE* stream) { - const char* name; -#ifdef STARDIS_ENABLE_MPI - int rank; -#endif - ASSERT(stream && prog); - -#ifdef STARDIS_ENABLE_MPI - CHK(MPI_Comm_rank(MPI_COMM_WORLD, &rank) == MPI_SUCCESS); - /* Only master prints */ - if(rank != 0) return; -#endif - -#ifdef COMPILER_GCC - name = strrchr(prog, '/'); -#else - name = strrchr(prog, '\\'); -#endif - - name = name ? name + 1 : prog; - fprintf(stream, - "Usage: %s [OPTIONS]\n" - "\nSolve coupled thermal systems under the linear assumption.\n" - "Refer to stardis(1) man page for more information.\n\n", - name); - print_version(stream); - - fprintf(stream, "\nMandatory options\n"); - fprintf(stream, "-----------------\n"); - - fprintf(stream, "\n -M <FILE>\n"); - fprintf(stream, " Read a text file that contains (partial) description of the model.\n"); - - fprintf(stream, "\nExclusive options\n"); - fprintf(stream, "-----------------\n"); - - fprintf(stream, "\n -F STL_FILE[,TIME-RANGE]\n"); - fprintf(stream, " Compute the mean flux on a given 2D region at a given time.\n"); - - fprintf(stream, "\n -m MEDIUM_NAME[,TIME-RANGE]\n"); - fprintf(stream, " Compute the mean temperature in a given medium at a given time.\n"); - - fprintf(stream, "\n -p X,Y,Z[,TIME-RANGE]\n"); - fprintf(stream, " Compute the temperature at the given probe.\n"); - - fprintf(stream, "\n -P X,Y,Z[,TIME-RANGE]\n"); - fprintf(stream, " Compute the temperature at the given probe on an interface.\n"); - - fprintf(stream, "\n -R [RENDERING_OPTIONS]\n"); - fprintf(stream, " Compute an infra-red image of the model.\n"); - - fprintf(stream, "\n -s STL_FILE[,TIME-RANGE]\n"); - fprintf(stream, " Compute the mean temperature on a given 2D region.\n"); - - fprintf(stream, "\n -S STL_FILE[,TIME-RANGE]\n"); - fprintf(stream, " Compute the by-triangle mean temperature on a given 2D region.\n"); - - fprintf(stream, "\nOther options\n"); - fprintf(stream, "-------------\n"); - - fprintf(stream, "\n -c NAMES_PREFIX\n"); - fprintf(stream, " Dump the geometry and property ids to stdout as C chunks.\n"); - - fprintf(stream, "\n -d\n"); - fprintf(stream, " Dump the geometry to stdout in VTK format along with various properties.\n"); - - fprintf(stream, "\n -D TYPE,FILE_NAMES_PREFIX\n"); - fprintf(stream, " Write thermal paths of the given TYPE in VTK format.\n"); - - fprintf(stream, "\n -e\n"); - fprintf(stream, " Use extended format to output Monte-Carlo results.\n"); - - fprintf(stream, "\n -g\n"); - fprintf(stream, " Change the computation to produce the green function.\n"); - - fprintf(stream, "\n -G BIN_FILE_NAME[,CSV_FILE_NAME]\n"); - fprintf(stream, " Change the computation to produce the green function and possibly end of paths information.\n"); - - fprintf(stream, "\n -h\n"); - fprintf(stream, " Print this help and exit.\n"); - - fprintf(stream, "\n -n SAMPLE_COUNT\n"); - fprintf(stream, " Set the number of Monte-Carlo samples.\n"); - - fprintf(stream, "\n -o\n"); - fprintf(stream, " Set the order for the Picard linearization of radiative transfer.\n"); - - fprintf(stream, "\n -t NUM_OF_THREADS\n"); - fprintf(stream, " Hint on the number of threads.\n"); - - fprintf(stream, "\n -v\n"); - fprintf(stream, " Print version information and exit.\n"); - - fprintf(stream, "\n -V LEVEL\n"); - fprintf(stream, " Set the verbosity level.\n"); - - fprintf(stream, "\n -x <FILE>\n"); - fprintf(stream, " Use a random generator's state read from a file.\n"); - - fprintf(stream, "\n -X <FILE>\n"); - fprintf(stream, " Save the final random generator's state in a file.\n"); - - fprintf(stream, -"\nCopyright (C) 2018-2023 |Méso|Star> <contact@meso-star.com>.\n" -"stardis is free software released under the GNU GPL license, version 3 or later.\n" -"You are free to change or redistribute it under certain conditions\n" -"<http://gnu.org/licenses/gpl.html>.\n"); + #define PRINT(Msg) fprintf(stream, Msg) + PRINT("stardis [-eghiv] [-a diff_algo] [-D path_type,files_name_prefix]\n"); + PRINT(" [-d file_base_name] [-F surface[,time[,time]]]\n"); + PRINT(" [-G green_bin[,green_ascii]] [-I initial_time]\n"); + PRINT(" [-L interface_probes] [-m medium_name[,time[,time]]]\n"); + PRINT(" [-n samples_count] [-o picard_order]\n"); + PRINT(" [-P x,y,z[,time[,time]][:side_indicator]]\n"); + PRINT(" [-p x,y,z[,time[,time]]] [-R rendering_opt[:rendering_opt ...]]\n"); + PRINT(" [-S surface[,time[,time]]] [-s surface[,time[,time]]]\n"); + PRINT(" [-t threads_count] [-V verbosity_level] [-X output_rng]\n"); + PRINT(" [-x input_rng] -M system\n"); + #undef PRINT } #define FREE_AARRAY(ARRAY) \ @@ -385,7 +525,7 @@ parse_args { int opt = 0, n_used = 0, o_used = 0; size_t len = 0; - const char option_list[] = "c:dD:eF:gG:hm:M:n:o:p:P:R:s:S:t:vV:x:X:"; + const char option_list[] = "a:c:d:D:eF:gG:hiI:L:m:M:n:o:p:P:R:s:S:t:vV:x:X:"; char buf[128]; struct str keep; char** line = NULL; @@ -412,6 +552,11 @@ parse_args goto error; } + case 'a': + res = parse_diff_algo(optarg, args->logger, &args->diff_algo); + if(res != RES_OK) goto error; + break; + case 'c': if(args->mode & USE_STDOUT_MODES) { res = RES_BAD_ARG; @@ -426,15 +571,8 @@ parse_args break; case 'd': - if(args->mode & USE_STDOUT_MODES) { - res = RES_BAD_ARG; - print_multiple_modes(buf, sizeof(buf), USE_STDOUT_MODES, MODE_DUMP_VTK); - logger_print(args->logger, LOG_ERROR, - "Option -%c cannot be used in conjunction with other dump options (%s).\n", - (char)opt, buf); - goto error; - } - args->mode |= MODE_DUMP_VTK; + args->dump_model_filename = optarg; + args->mode |= MODE_DUMP_MODEL; break; case 'D': { @@ -521,6 +659,28 @@ parse_args args->mode |= MODE_DUMP_HELP; break; + case 'I': + res = cstr_to_double(optarg, &args->initial_time); + if(res != RES_OK) goto error; + break; + + case 'i': + args->disable_intrad = 1; + break; + + case 'L': + if(args->mode & EXCLUSIVE_MODES) { + logger_print(args->logger, LOG_ERROR, + "Options -%c and -%c are exclusive.\n", + (char)opt, mode_option(args->mode)); + goto error; + } + args->mode |= MODE_PROBE_LIST_COMPUTE_ON_INTERFACE; + res = parse_probe_boundary_list + (optarg, args->logger, args->allocator, &args->probe_boundary_list); + if(res != RES_OK) goto error; + break; + case 'm': { char* ptr; if(args->mode & EXCLUSIVE_MODES) { @@ -589,42 +749,23 @@ parse_args GET_POS_AND_OPTIONAL_TIME_RANGE(optarg, args->pos_and_time, optarg); break; - case 'P': + case 'P': { + struct stardis_probe_boundary* probe = NULL; + if(args->mode & EXCLUSIVE_MODES) { - res = RES_BAD_ARG; logger_print(args->logger, LOG_ERROR, - "Options -%c and -%c are exclusive.\n", - (char)opt, mode_option(args->mode)); - goto error; - } - args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE; - - ERR(str_set(&keep, optarg)); - line = split_line(optarg, ':'); - if(!line) { - res = RES_MEM_ERR; - str_release(&keep); - goto error; - } - - /* We expect 1 or 2 parts in line */ - if(!line[0] || (line[1] && line[2])) { - logger_print((args->logger), LOG_ERROR, - "Invalid argument for option ""-%c"": %s\n", - opt, str_cget(&keep)); - str_release(&keep); + "Options -%c and -%c are exclusive.\n", + (char)opt, mode_option(args->mode)); res = RES_BAD_ARG; goto error; } - - /* First part is pos and optional time, optional second part is a - * medium name (OK if NULL) */ - GET_POS_AND_OPTIONAL_TIME_RANGE(line[0], args->pos_and_time, - str_cget(&keep)); - if(line[1]) - args->medium_name = optarg + strlen(line[0]) + 1; - + args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE; + res = allocate_probe_boundary(args, &probe); + if(res != RES_OK) goto error; + res = parse_probe_boundary(optarg, probe); + if(res != RES_OK) goto error; break; + } case 'R': if(args->mode & EXCLUSIVE_MODES) { @@ -751,9 +892,10 @@ parse_args if(args->mode == UNDEF_MODE) { print_multiple_modes(buf, sizeof(buf), EXCLUSIVE_MODES | USE_STDOUT_MODES, 0); - logger_print(args->logger, LOG_WARNING, - "Nothing to do.\nOne of the following options should be used: %s\n", - buf); + logger_print(args->logger, LOG_ERROR, + "Nothing to do.\n"); + logger_print(args->logger, LOG_ERROR, + "One of the following options should be used: %s\n", buf); res = RES_BAD_ARG; goto error; } diff --git a/src/stardis-args.h b/src/stardis-args.h @@ -1,140 +0,0 @@ -/* Copyright (C) 2018-2023 |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/>. */ - -#ifndef STARDIS_ARGS_H -#define STARDIS_ARGS_H - -#include <sdis.h> - -#include <rsys/rsys.h> -#include <rsys/dynamic_array_str.h> - -struct camera; -struct logger; -struct mem_allocator; -struct stardis; - -enum stardis_mode { - /* Ordered so that print_multiple_modes() prints in alphabetical order */ - UNDEF_MODE = 0, - MODE_DUMP_C_CHUNKS = BIT(0), /* -c */ - MODE_DUMP_PATHS = BIT(1), /* -D */ - MODE_DUMP_VTK = BIT(2), /* -d */ - MODE_EXTENDED_RESULTS = BIT(3), /* -e */ - MODE_FLUX_BOUNDARY_COMPUTE = BIT(4), /* -F */ - MODE_BIN_GREEN = BIT(5), /* -G */ - MODE_GREEN = BIT(6), /* -g */ - MODE_DUMP_HELP = BIT(7), /* -h */ - MODE_MEDIUM_COMPUTE = BIT(8), /* -m */ - MODE_PROBE_COMPUTE_ON_INTERFACE = BIT(9), /* -P */ - MODE_PROBE_COMPUTE = BIT(10), /* -p */ - MODE_IR_COMPUTE = BIT(11), /* -R */ - MODE_MAP_COMPUTE = BIT(12), /* -S */ - MODE_BOUNDARY_COMPUTE = BIT(13), /* -s */ - MODE_VERBOSITY = BIT(14), /* -V */ - MODE_DUMP_VERSION = BIT(15), /* -v */ - - GREEN_COMPATIBLE_MODES - = MODE_PROBE_COMPUTE | MODE_PROBE_COMPUTE_ON_INTERFACE | MODE_MEDIUM_COMPUTE - | MODE_BOUNDARY_COMPUTE, - - SURFACE_COMPUTE_MODES - = MODE_BOUNDARY_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE | MODE_MAP_COMPUTE, - - EXT_COMPATIBLE_MODES - = GREEN_COMPATIBLE_MODES | MODE_MEDIUM_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE, - - REGION_COMPUTE_MODES = SURFACE_COMPUTE_MODES | MODE_MEDIUM_COMPUTE, - - COMPUTE_MODES = GREEN_COMPATIBLE_MODES | MODE_IR_COMPUTE | SURFACE_COMPUTE_MODES, - - EXCLUSIVE_MODES = COMPUTE_MODES, - - SHORT_EXIT_MODES = MODE_DUMP_HELP | MODE_DUMP_VERSION, - - USE_STDOUT_MODES - = MODE_DUMP_C_CHUNKS | MODE_DUMP_VTK | MODE_DUMP_HELP | MODE_DUMP_VERSION - | MODE_IR_COMPUTE | MODE_GREEN, - - RANDOM_RW_MODES - = MODE_PROBE_COMPUTE | MODE_PROBE_COMPUTE_ON_INTERFACE | MODE_MEDIUM_COMPUTE - | MODE_BOUNDARY_COMPUTE | MODE_FLUX_BOUNDARY_COMPUTE -}; - -STATIC_ASSERT(GREEN_COMPATIBLE_MODES == (COMPUTE_MODES & GREEN_COMPATIBLE_MODES), - Cannot_have_a_GREEN_COMPATIBLE_MODE_that_is_not_a_COMPUTE_MODE); - -enum dump_path_type { - DUMP_NONE = 0, - DUMP_SUCCESS = BIT(0), - DUMP_ERROR = BIT(1), - DUMP_ALL = DUMP_SUCCESS | DUMP_ERROR -}; - -struct args { - struct logger* logger; - struct mem_allocator* allocator; - struct darray_str model_files; - char* medium_name; - char* solve_filename; - char* bin_green_filename; - char* end_paths_filename; - char* paths_filename; - char* rndgen_state_in_filename; - char* rndgen_state_out_filename; - char* chunks_prefix; - char* camera; - size_t samples; - double pos_and_time[5]; - unsigned nthreads; - unsigned picard_order; - enum stardis_mode mode; - enum dump_path_type dump_paths; - int verbose; -}; - -res_T -init_args - (struct logger* logger, - struct mem_allocator* mem, - struct args** args); - -void -release_args - (struct args* args); - -void -print_version - (FILE* stream); - -void -short_help - (FILE* stream, - const char* prog); - -res_T -parse_args - (const int argc, - char** argv, - struct args* args, - struct mem_allocator* allocator); - -res_T -parse_camera - (struct logger* logger, - char* cam_param, - struct stardis* stardis); - -#endif /* STRADIS_ARGS_H */ diff --git a/src/stardis-args.h.in b/src/stardis-args.h.in @@ -0,0 +1,183 @@ +/* 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/>. */ + +#ifndef STARDIS_ARGS_H +#define STARDIS_ARGS_H + +#define STARDIS_MAX_NAME_LENGTH @STARDIS_MAX_NAME_LENGTH@ + +#include <sdis.h> + +#include <rsys/rsys.h> +#include <rsys/dynamic_array_str.h> + +struct camera; +struct logger; +struct mem_allocator; +struct stardis; + +struct stardis_probe_boundary { + double position[3]; + double time[2]; /* Observation time */ + char side[STARDIS_MAX_NAME_LENGTH]; +}; +#define STARDIS_PROBE_BOUNDARY_NULL__ {{0,0,0},{0,0},{0}} +static const struct stardis_probe_boundary STARDIS_PROBE_BOUNDARY_NULL = + STARDIS_PROBE_BOUNDARY_NULL__; + +/* Define the dynamic array of probes on the boundary */ +#define DARRAY_NAME probe_boundary +#define DARRAY_DATA struct stardis_probe_boundary +#include <rsys/dynamic_array.h> + +enum stardis_mode { + /* Ordered so that print_multiple_modes() prints in alphabetical order */ + UNDEF_MODE = 0, + MODE_DUMP_C_CHUNKS = BIT(0), /* -c */ + MODE_DUMP_PATHS = BIT(1), /* -D */ + MODE_DUMP_MODEL = BIT(2), /* -d */ + MODE_EXTENDED_RESULTS = BIT(3), /* -e */ + MODE_FLUX_BOUNDARY_COMPUTE = BIT(4), /* -F */ + MODE_BIN_GREEN = BIT(5), /* -G */ + MODE_GREEN = BIT(6), /* -g */ + MODE_DUMP_HELP = BIT(7), /* -h */ + MODE_PROBE_LIST_COMPUTE_ON_INTERFACE = BIT(8), /* -L */ + MODE_MEDIUM_COMPUTE = BIT(9), /* -m */ + MODE_PROBE_COMPUTE_ON_INTERFACE = BIT(10), /* -P */ + MODE_PROBE_COMPUTE = BIT(11), /* -p */ + MODE_IR_COMPUTE = BIT(12), /* -R */ + MODE_MAP_COMPUTE = BIT(13), /* -S */ + MODE_BOUNDARY_COMPUTE = BIT(14), /* -s */ + MODE_VERBOSITY = BIT(15), /* -V */ + MODE_DUMP_VERSION = BIT(16), /* -v */ + + GREEN_COMPATIBLE_MODES = + MODE_PROBE_COMPUTE + | MODE_PROBE_COMPUTE_ON_INTERFACE + | MODE_MEDIUM_COMPUTE + | MODE_BOUNDARY_COMPUTE, + + SURFACE_COMPUTE_MODES = + MODE_BOUNDARY_COMPUTE + | MODE_FLUX_BOUNDARY_COMPUTE + | MODE_MAP_COMPUTE, + + EXT_COMPATIBLE_MODES = + GREEN_COMPATIBLE_MODES + | MODE_MEDIUM_COMPUTE + | MODE_FLUX_BOUNDARY_COMPUTE, + + REGION_COMPUTE_MODES = + SURFACE_COMPUTE_MODES + | MODE_MEDIUM_COMPUTE, + + COMPUTE_MODES = + GREEN_COMPATIBLE_MODES + | MODE_IR_COMPUTE + | SURFACE_COMPUTE_MODES + | MODE_PROBE_LIST_COMPUTE_ON_INTERFACE, + + EXCLUSIVE_MODES = COMPUTE_MODES, + + SHORT_EXIT_MODES = + MODE_DUMP_HELP + | MODE_DUMP_VERSION, + + USE_STDOUT_MODES = + MODE_DUMP_C_CHUNKS + | MODE_DUMP_HELP + | MODE_DUMP_VERSION + | MODE_IR_COMPUTE + | MODE_GREEN, + + RANDOM_RW_MODES = + MODE_PROBE_COMPUTE + | MODE_PROBE_COMPUTE_ON_INTERFACE + | MODE_PROBE_LIST_COMPUTE_ON_INTERFACE + | MODE_MEDIUM_COMPUTE + | MODE_BOUNDARY_COMPUTE + | MODE_FLUX_BOUNDARY_COMPUTE +}; + +STATIC_ASSERT(GREEN_COMPATIBLE_MODES == (COMPUTE_MODES & GREEN_COMPATIBLE_MODES), + Cannot_have_a_GREEN_COMPATIBLE_MODE_that_is_not_a_COMPUTE_MODE); + +enum dump_path_type { + DUMP_NONE = 0, + DUMP_SUCCESS = BIT(0), + DUMP_ERROR = BIT(1), + DUMP_ALL = DUMP_SUCCESS | DUMP_ERROR +}; + +struct args { + struct logger* logger; + struct mem_allocator* allocator; + struct darray_str model_files; + char* medium_name; + char* solve_filename; + char* bin_green_filename; + char* end_paths_filename; + char* dump_model_filename; + char* paths_filename; + char* rndgen_state_in_filename; + char* rndgen_state_out_filename; + char* chunks_prefix; + char* camera; + size_t samples; + double pos_and_time[5]; + double initial_time; /* [s] */ + unsigned nthreads; + unsigned picard_order; + int mode; + enum dump_path_type dump_paths; + enum sdis_diffusion_algorithm diff_algo; + int verbose; + int disable_intrad; /* Disable internal radiative exchanges */ + + struct darray_probe_boundary probe_boundary_list; +}; + +extern LOCAL_SYM res_T +init_args + (struct logger* logger, + struct mem_allocator* mem, + struct args** args); + +extern LOCAL_SYM void +release_args + (struct args* args); + +extern LOCAL_SYM void +print_version + (FILE* stream); + +extern LOCAL_SYM void +usage + (FILE* stream); + +extern LOCAL_SYM res_T +parse_args + (const int argc, + char** argv, + struct args* args, + struct mem_allocator* allocator); + +extern LOCAL_SYM res_T +parse_camera + (struct logger* logger, + char* cam_param, + struct stardis* stardis); + +#endif /* STRADIS_ARGS_H */ diff --git a/src/stardis-compute-probe-boundary.c b/src/stardis-compute-probe-boundary.c @@ -0,0 +1,994 @@ +/* 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/>. */ + +#include "stardis-app.h" +#include "stardis-compute.h" +#include "stardis-output.h" +#include "stardis-prog-properties.h" +#include "stardis-solid.h" +#include "stardis-solid-prog.h" +#include "stardis-ssconnect.h" + +#include <sdis.h> + +#include <star/senc3d.h> +#include <star/ssp.h> + +#include <rsys/logger.h> +#include <rsys/str.h> +#include <rsys/clock_time.h> + +#include <strings.h> + +struct filter_ctx { + float distance; + enum sg3d_property_type side; +}; +#define FILTER_CTX_DEFAULT__ {0.f, SG3D_INTFACE} +static const struct filter_ctx FILTER_CTX_DEFAULT = FILTER_CTX_DEFAULT__; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE const char* +sdis_side_to_cstr(const enum sdis_side side) +{ + const char* cstr = NULL; + switch(side) { + case SDIS_FRONT: cstr = "FRONT"; break; + case SDIS_BACK: cstr = "BACK"; break; + case SDIS_SIDE_NULL__: cstr = "UNDEFINED"; break; + default: FATAL("Unreachable code.\n"); + } + return cstr; +} + +static res_T +read_rng_state + (struct stardis* stardis, + const char* filename, + struct ssp_rng* rng) +{ + FILE* fp = NULL; + res_T res = RES_OK; + ASSERT(stardis && filename && rng); + + if(stardis->mpi_initialized && stardis->mpi_rank != 0) { + goto exit; /* Non master process. Nothing to do */ + } + + if((fp = fopen(filename, "r")) == NULL) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open generator's state file ('%s').\n", filename); + res = RES_IO_ERR; + goto error; + } + + res = ssp_rng_read(rng, fp); + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot read random generator's state ('%s').\n", filename); + goto error; + } + +exit: + if(fp) CHK(fclose(fp) == 0); + return res; +error: + goto exit; +} + +static res_T +write_rng_state + (struct stardis* stardis, + const char* filename, + struct ssp_rng* rng_state) +{ + FILE* fp = NULL; + res_T res = RES_OK; + ASSERT(stardis && filename && rng_state); + + if(stardis->mpi_initialized && stardis->mpi_rank != 0) { + goto exit; /* Non master process. Nothing to do */ + } + + if((fp = fopen(filename, "wb")) == NULL) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open generator's state file ('%s').\n", filename); + res = RES_IO_ERR; + goto error; + } + + res = ssp_rng_write(rng_state, fp); + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot write random generator's state ('%s').\n", filename); + res = RES_IO_ERR; + goto error; + } + +exit: + if(fp) CHK(fclose(fp) == 0); + return res; +error: + goto exit; +} + +/* Filter used from a point query to determine not only one of the closest + * point, but the better one if there are more than one. In some circumstances + * it is not possible to determine the medium we are in using a given hit, but + * it is possible using another equidistant hit : + * + * + * P C + * +.............+---trg 1--- + * | + * medium 1 trg 2 medium 2 + * | + * + * C is the closest point from P, and 2 different hits at C are possible (one + * on each triangle). However, only hit on trg 2 allows to find out that P is + * in medium 1 using sign(PC.Ntrg1) as PC.Ntrg2 = 0. + * The following filter function aims at selecting the hit on trg2 regardless + * of the order in which the 2 triangles are checked. + * One unexpected case cannot be decided though, but it implies that the + * closest triangle has 2 different media on its sides and that P lies on the + * triangle's plane : + * + * P C medium 1 + * + +---trg--- + * medium 2 */ +static int +hit_filter + (const struct s3d_hit* hit, + const float ray_org[3], + const float ray_dir[3], + const float ray_range[2], + void* ray_data, + void* filter_data) +{ + struct filter_ctx* filter_ctx = ray_data; + + (void)ray_org, (void)ray_range, (void)filter_data; + ASSERT(hit && filter_ctx); + ASSERT(hit->uv[0] == CLAMP(hit->uv[0], 0, 1)); + ASSERT(hit->uv[1] == CLAMP(hit->uv[1], 0, 1)); + + /* That's not the closest point. Keep the previous one if it can be used to + * detect the medium (i.e. side != SG3D_INTFACE) */ + if(filter_ctx->distance == hit->distance && filter_ctx->side != SG3D_INTFACE) { + return 1; /* Skip */ + } + + filter_ctx->distance = hit->distance; + + if(filter_ctx->distance == 0) { + filter_ctx->side = SG3D_INTFACE; + } else { + float sign = 0; + float N[3] = {0,0,0}; /* Normalized normal */ + + /* Calculate the dot product with normalized vectors limits the numerical + * inaccuracies on its sign */ + f3_normalize(N, hit->normal); + sign = f3_dot(ray_dir, N); + + /* Star3D hit normals are left-handed */ + if(sign < 0) filter_ctx->side = SG3D_FRONT; + else if(sign > 0) filter_ctx->side = SG3D_BACK; + else/*sign == 0*/ filter_ctx->side = SG3D_INTFACE; + } + + return 0; /* Keep */ +} + +static INLINE res_T +find_closest_point + (struct stardis* stardis, + const double pos[3], + struct filter_ctx* filter_ctx, + size_t* iprim, + double uv[2]) +{ + struct sdis_scene_find_closest_point_args closest_pt_args = + SDIS_SCENE_FIND_CLOSEST_POINT_ARGS_NULL; + res_T res = RES_OK; + ASSERT(stardis && pos && filter_ctx && iprim && uv); + + /* Find the surface point closest to the input position */ + closest_pt_args.position[0] = pos[0]; + closest_pt_args.position[1] = pos[1]; + closest_pt_args.position[2] = pos[2]; + closest_pt_args.radius = INF; + closest_pt_args.filter_3d = hit_filter; + closest_pt_args.filter_data = filter_ctx; + ERR(sdis_scene_find_closest_point + (stardis->sdis_scn , &closest_pt_args, iprim, uv)); + if(*iprim == SDIS_PRIMITIVE_NONE) { + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +check_move_to_solid_boundary + (const struct stardis* stardis, + const double pos[3], /* Original position */ + const double time, /* [s] */ + const struct description* desc, /* Solid medium in which pos lies */ + const size_t iprim, /* Triangle index to which to move */ + const double uv[2], /* Triangle coordinates to which to move */ + const double distance) /* Move distance */ +{ + struct stardis_vertex vtx = STARDIS_VERTEX_NULL; + const char* prefix = ""; + const char* solid_name = ""; + double delta = 0; + res_T res = RES_OK; + + /* Check pre-conditions */ + ASSERT(stardis && pos && time > 0 && desc && uv && distance >= 0); + + /* Retrieve the delta and define the prefix of the solid for log messages */ + switch(desc->type) { + /* Regular solid, i.e. solid with constant properties */ + case DESC_MAT_SOLID: + delta = desc->d.solid->delta; + prefix = ""; + break; + + /* Solid with programmed properties */ + case DESC_MAT_SOLID_PROG: + vtx.P[0] = pos[0]; + vtx.P[1] = pos[1]; + vtx.P[2] = pos[2]; + vtx.time = time; + delta = desc->d.solid_prog->delta(&vtx, desc->d.solid_prog->prog_data); + prefix = "programmed"; + break; + + default: FATAL("Unreachable code.\n"); + } + + solid_name = str_cget(get_description_name(desc)); + logger_print(stardis->logger, LOG_OUTPUT, "Probe was in %ssolid '%s'.\n", + prefix, solid_name); + + /* The position is closed from the triangle */ + if(distance < 0.5*delta) { + logger_print(stardis->logger, LOG_OUTPUT, + "Probe was %g delta from closest boundary.\n", + distance/delta); + + /* Notice that the position is a little far from the triangle */ + } else if(distance < 2*delta) { + logger_print(stardis->logger, LOG_WARNING, + "Probe was %g delta from closest boundary. " + "Consider using -p instead of -P.\n", + distance/delta); + + /* The position is too far from the triangle */ + } else { + logger_print(stardis->logger, LOG_ERROR, + "Probe moved to (%g, %g, %g), primitive %lu, uv = (%g, %g). " + "Move is %g delta long. Use -p instead of -P.\n", + SPLIT3(pos), (unsigned long)iprim, SPLIT2(uv), distance/delta); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + +/* This function checks nothing. It only records the status. It is named as the + * one used to check the projection on the solid limit to make it symmetrical, + * and thus simplify the reading of sources */ +static res_T +check_move_to_fluid_boundary + (struct stardis* stardis, + const struct description* desc, /* Fluid medium in which pos lies */ + const double distance) /* Move distance */ +{ + const char* prefix = ""; + const char* fluid_name = ""; + + ASSERT(stardis && desc && distance >= 0); + + switch(desc->type) { + case DESC_MAT_FLUID: prefix = ""; break; + case DESC_MAT_FLUID_PROG: prefix = "programmed"; break; + default: FATAL("Unreachable code.\n"); + } + + fluid_name = str_cget(get_description_name(desc)); + logger_print(stardis->logger, LOG_OUTPUT, + "Probe was in %sfluid '%s'.\n", prefix, fluid_name); + logger_print(stardis->logger, LOG_OUTPUT, + "Probe distance from closest boundary was %g.\n", distance); + + return RES_OK; +} + +static res_T +move_to_boundary + (struct stardis* stardis, + const double pos[3], + const double time, /* [s] */ + size_t* out_iprim, + double uv[2]) +{ + /* Position on boundary */ + struct filter_ctx filter_ctx = FILTER_CTX_DEFAULT; + double proj_pos[3] = {0,0,0}; + size_t iprim = 0; + + /* Properties */ + const struct description* desc_list = NULL; + const struct description* desc = NULL; + unsigned desc_ids[SG3D_PROP_TYPES_COUNT__]; + + /* Miscellaneous */ + size_t nvertices_close = 0; + res_T res = RES_OK; + + /* Check pre-conditions */ + ASSERT(stardis && pos && time >= 0 && out_iprim && uv); + + ERR(find_closest_point(stardis, pos, &filter_ctx, &iprim, uv)); + SG3D(geometry_get_unique_triangle_properties + (stardis->geometry.sg3d, (unsigned)iprim, desc_ids)); + + desc_list = darray_descriptions_cdata_get(&stardis->descriptions); + + /* Undefined medium */ + if(filter_ctx.side == SG3D_INTFACE + || desc_ids[filter_ctx.side] == SG3D_UNSPECIFIED_PROPERTY) { + logger_print(stardis->logger, LOG_WARNING, + "Could not determine the medium probe is in.\n"); + } + + if(filter_ctx.side != SG3D_INTFACE) { + + /* Probe is outside the system */ + if(desc_ids[filter_ctx.side] == SG3D_UNSPECIFIED_PROPERTY) { + logger_print(stardis->logger, LOG_WARNING, + "Probe was outside the system.\n"); + + /* Probe is in a medium */ + } else { + desc = desc_list + desc_ids[filter_ctx.side]; + + switch(desc->type) { + case DESC_MAT_SOLID: + case DESC_MAT_SOLID_PROG: + ERR(check_move_to_solid_boundary + (stardis, pos, time, desc, iprim, uv, filter_ctx.distance)); + break; + case DESC_MAT_FLUID: + case DESC_MAT_FLUID_PROG: + ERR(check_move_to_fluid_boundary + (stardis, desc, filter_ctx.distance)); + break; + default: FATAL("Unreachable code.\n"); + } + } + } + + SDIS(scene_get_boundary_position(stardis->sdis_scn, iprim, uv, proj_pos)); + + /* Count the number of vertices that are close to the boundary position + * and issue a warning if necessary */ + nvertices_close += CLAMP(uv[0], 0.0005, 0.9995) != uv[0]; + nvertices_close += CLAMP(uv[1], 0.0005, 0.9995) != uv[1]; + if(nvertices_close) { + logger_print(stardis->logger, LOG_WARNING, + "Probe %s close to / on %s. " + "If computation fails, try moving it slightly.\n", + filter_ctx.distance == 0 ? "is" : "moved", + nvertices_close == 1 ? "an edge" : "a vertex"); + } + + /* Probe is on a boundary */ + if(filter_ctx.distance == 0) { + logger_print(stardis->logger, LOG_OUTPUT, + "Probe is on primitive %lu, uv = (%g, %g), not moved.\n", + (unsigned long)iprim, SPLIT2(uv)); + + /* Probe was projected on a boundary */ + } else { + logger_print(stardis->logger, LOG_OUTPUT, + "Probe moved to (%g, %g, %g), primitive %lu, uv = (%g, %g).\n", + SPLIT3(proj_pos), (unsigned long)iprim, SPLIT2(uv)); + } + +exit: + *out_iprim = iprim; + return res; +error: + goto exit; +} + +static res_T +setup_probe_side + (struct stardis* stardis, + const unsigned desc_ids[SG3D_PROP_TYPES_COUNT__], + const char* side_str, + const size_t iprim, + enum sdis_side *out_side) +{ + const struct description* desc_list = NULL; + const struct description* desc_front = NULL; + const struct description* desc_back = NULL; + size_t ndescs = 0; + enum sdis_side side = SDIS_SIDE_NULL__; + res_T res = RES_OK; + (void)ndescs; /* Avoid "Unused variable" warnings in release */ + + /* Check pre-conditions */ + ASSERT(stardis && side_str && desc_ids && out_side); + + /* Fetch the properties */ + desc_list = darray_descriptions_cdata_get(&stardis->descriptions); + ndescs = darray_descriptions_size_get(&stardis->descriptions); + desc_front = desc_list + desc_ids[SG3D_FRONT]; + desc_back = desc_list + desc_ids[SG3D_BACK]; + + /* No side specified */ + if(!side_str || !strlen(side_str)) { + side = SDIS_SIDE_NULL__; + + /* Set probe to front side */ + } else if(!strcasecmp(side_str, "FRONT")) { + ASSERT(desc_ids[SG3D_FRONT] < ndescs && DESC_IS_MEDIUM(desc_front)); + side = SDIS_FRONT; + + /* Set probe to back side */ + } else if(!strcasecmp(side_str, "BACK")) { + ASSERT(desc_ids[SG3D_BACK] < ndescs && DESC_IS_MEDIUM(desc_back)); + side = SDIS_BACK; + + /* Set the probe to the side that points to the submitted medium name */ + } else { + unsigned med_id_probe = 0; /* Medium defined on the probe */ + unsigned med_id_front = 0; /* Medium on front side */ + unsigned med_id_back = 0; /* Medium on back side */ + ASSERT(DESC_IS_MEDIUM(desc_front) && DESC_IS_MEDIUM(desc_back)); + + if(!find_medium_by_name(stardis, side_str, &med_id_probe)) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot locate side from medium name '%s' (unknown medium)\n", + side_str); + res = RES_BAD_ARG; + goto error; + } + + description_get_medium_id(desc_front, &med_id_front); + description_get_medium_id(desc_back, &med_id_back); + + /* Invalid probe medium wrt the boundary on which it is located */ + if(med_id_probe != med_id_front + && med_id_probe != med_id_back) { + logger_print(stardis->logger, LOG_ERROR, + "Medium '%s' is not used at this interface (prim id=%lu)\n", + side_str, (unsigned long)iprim); + res = RES_BAD_ARG; + goto error; + } + + /* The same medium is used on both sides: cannot differentiate */ + if(med_id_front == med_id_back) { + unsigned encs[2]; /* Identifier of the enclosures */ + + ERR(senc3d_scene_get_triangle_enclosures + (stardis->senc3d_scn, (unsigned)iprim, encs)); + logger_print(stardis->logger, LOG_ERROR, + "Medium '%s' is used on both sides of this interface (prim id=%lu).\n", + side_str, (unsigned long)iprim); + logger_print(stardis->logger, LOG_ERROR, + "Side must be defined using either FRONT or BACK.\n"); + logger_print(stardis->logger, LOG_ERROR, + "FRONT side is related to enclosure %u, BACK side to enclosure %u.\n", + encs[SENC3D_FRONT], encs[SENC3D_BACK]); + + res = RES_BAD_ARG; + goto error; + } + + side = med_id_probe == med_id_front ? SDIS_FRONT : SDIS_BACK; + } + +exit: + *out_side = side; + return res; +error: + side = SDIS_SIDE_NULL__; + goto exit; +} + +/* This function checks the conformity between the potential thermal contact + * resistance at the probe location and the specified probe side. */ +static res_T +setup_thermal_contact_resistance + (struct stardis* stardis, + const unsigned desc_ids[SG3D_PROP_TYPES_COUNT__], + const enum sdis_side probe_side) +{ + struct str log_msg; + const struct description* desc_list = NULL; + const struct description* desc_front = NULL; + const struct description* desc_back = NULL; + const struct description* desc_intface = NULL; + size_t ndescs = 0; + double tcr = 0; + res_T res = RES_OK; + (void)ndescs; /* Avoid "Unused variable" warnings in release */ + + /* Check pre-conditions */ + ASSERT(stardis && desc_ids); + + str_init(stardis->allocator, &log_msg); + + /* Fetch the properties */ + desc_list = darray_descriptions_cdata_get(&stardis->descriptions); + ndescs = darray_descriptions_size_get(&stardis->descriptions); + desc_front = desc_list + desc_ids[SG3D_FRONT]; + desc_back = desc_list + desc_ids[SG3D_BACK]; + desc_intface = desc_list + desc_ids[SG3D_INTFACE]; + + /* Get the thermal contact resistance between solid/solid connection if any */ + if(desc_ids[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY + && desc_intface->type == DESC_SOLID_SOLID_CONNECT) { + ASSERT(desc_ids[SG3D_INTFACE] < ndescs); + tcr = desc_intface->d.ss_connect->tcr; + } + + /* Warn if side defined and no resistance defined */ + if(tcr == 0 && probe_side != SDIS_SIDE_NULL__) { + logger_print(stardis->logger, LOG_WARNING, + "Specifying a compute side at an interface with no contact resistance " + "is meaningless.\n"); + } + + #define GET_DESC_NAME(Desc) str_cget(get_description_name(Desc)) + + /* A thermal contact resistance cannot be defined if probe side is NULL */ + if(tcr != 0 && probe_side == SDIS_SIDE_NULL__) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot let probe computation side unspecified on an interface with a " + "non-nul thermal resistance.\n"); + + /* Format the log string */ + if(desc_ids[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY) { + ASSERT(desc_ids[SG3D_FRONT] < ndescs); + ERR(str_append_printf(&log_msg, " FRONT: '%s'", GET_DESC_NAME(desc_front))); + } + if(desc_ids[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY + && desc_ids[SG3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) { + ERR(str_append_char(&log_msg, ',')); + } + if(desc_ids[SG3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) { + ASSERT(desc_ids[SG3D_BACK] < ndescs); + ERR(str_append_printf(&log_msg, " BACK: '%s'", GET_DESC_NAME(desc_back))); + } + + /* Print error message */ + logger_print(stardis->logger, LOG_ERROR, + "Interface '%s',%s, resistance=%g K.m^2/W.\n", + GET_DESC_NAME(desc_intface), str_cget(&log_msg), tcr); + + res = RES_BAD_ARG; + goto error; + } + + /* Log that a calculation is done on a boundary with tcr */ + if(tcr > 0) { + const char* medium_name = probe_side == SDIS_FRONT + ? GET_DESC_NAME(desc_front) + : GET_DESC_NAME(desc_back); + + logger_print(stardis->logger, LOG_OUTPUT, + "Probe computation on an interface with a thermal resistance = %g K.m^2/W " + "on %s side (medium is '%s').\n", + tcr, sdis_side_to_cstr(probe_side), medium_name); + } + + #undef GET_DESC_NAME + +exit: + str_release(&log_msg); + return res; +error: + goto exit; +} + +static res_T +solve + (struct stardis* stardis, + struct time* start, + struct sdis_solve_probe_boundary_args* args, + res_T output[2]) +{ + struct time t0, t1; + struct sdis_mc time = SDIS_MC_NULL; + struct dump_path_context ctx = DUMP_PATH_CONTEXT_NULL; + struct sdis_estimator* estimator = NULL; + const struct str* rng_in = NULL; + const struct str* rng_out = NULL; + struct ssp_rng* rng = NULL; + int is_master_process = 0; + res_T res = RES_OK; + ASSERT(stardis && args && output); + + is_master_process = !stardis->mpi_initialized || stardis->mpi_rank == 0; + + rng_in = &stardis->rndgen_state_in_filename; + rng_out = &stardis->rndgen_state_in_filename; + + /* Read RNG state from file */ + if(!str_is_empty(rng_in)) { + ERR(ssp_rng_create(stardis->allocator, SSP_RNG_THREEFRY, &rng)); + ERR(read_rng_state(stardis, str_cget(rng_in), rng)); + args->rng_state = rng; + } + + /* Run the calculation */ + time_current(&t0); + ERR(sdis_solve_probe_boundary(stardis->sdis_scn, args, &estimator)); + time_current(&t1); + + /* No more to do for non master processes */ + if(!is_master_process) goto exit; + + /* Per per realisation time */ + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time(&time, stardis, start, &t0, &t1, NULL)); + + /* Write outputs and save their status */ + ctx.stardis = stardis; + ctx.rank = 0; + output[0] = print_single_MC_result(estimator, stardis, stdout); + output[1] = sdis_estimator_for_each_path(estimator, dump_path, &ctx); + + /* Write the resulting RNG state to a file */ + if(!str_is_empty(rng_out)) { + struct ssp_rng* rng_state = NULL; + ERR(sdis_estimator_get_rng_state(estimator, &rng_state)); + ERR(write_rng_state(stardis, str_cget(rng_out), rng_state)); + } + +exit: + if(estimator) SDIS(estimator_ref_put(estimator)); + if(rng) SSP(rng_ref_put(rng)); + return res; +error: + goto exit; +} + +static res_T +solve_list + (struct stardis* stardis, + struct time* start, + struct sdis_solve_probe_boundary_list_args* args, + res_T* output) +{ + struct time t0, t1; + struct sdis_mc time = SDIS_MC_NULL; /* Time per realisation */ + struct sdis_estimator_buffer* buffer = NULL; + size_t i = 0; + size_t def[2] = {0, 0}; + int is_master_process = 0; + res_T res = RES_OK; + ASSERT(stardis && start && args); + + is_master_process = !stardis->mpi_initialized || stardis->mpi_rank == 0; + + /* Run the calculation */ + time_current(&t0); + ERR(sdis_solve_probe_boundary_list(stardis->sdis_scn, args, &buffer)); + time_current(&t1); + + /* No more to do for non master processes */ + if(!is_master_process) goto exit; + + /* Retrieve the number of solved probes */ + ERR(sdis_estimator_buffer_get_definition(buffer, def)); + ASSERT(def[0] == darray_probe_boundary_size_get(&stardis->probe_boundary_list)); + ASSERT(def[1] == 1); + + ERR(sdis_estimator_buffer_get_realisation_time(buffer, &time)); + ERR(print_computation_time(&time, stardis, start, &t0, &t1, NULL)); + + /* Print the estimated temperature of each probe */ + FOR_EACH(i, 0, def[0]) { + const struct stardis_probe_boundary* probe = NULL; + const struct sdis_estimator* estimator = NULL; + res_T res2 = RES_OK; + + probe = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list) + i; + ERR(sdis_estimator_buffer_at(buffer, i, 0, &estimator)); + + res2 = print_single_MC_result_probe_boundary + (stardis, probe, estimator, stdout); + if(res2 != RES_OK && *output == RES_OK) *output = res2; + } + +exit: + if(buffer) SDIS(estimator_buffer_ref_put(buffer)); + return res; +error: + goto exit; +} + +static res_T +solve_green + (struct stardis* stardis, + struct time* start, + struct sdis_solve_probe_boundary_args* args) +{ + struct time t0/*calculation start*/, t1/*calculation end*/, t2/*output end*/; + struct sdis_green_function* green = NULL; + FILE* fp_green = NULL; + FILE* fp_path = NULL; + const struct str* rng_in = NULL; + struct ssp_rng* rng = NULL; + int is_master_process = 0; + res_T res = RES_OK; + + ASSERT(stardis && args); + + is_master_process = !stardis->mpi_initialized || stardis->mpi_rank == 0; + + rng_in = &stardis->rndgen_state_in_filename; + + /* Read RNG state from file */ + if(!str_is_empty(rng_in)) { + ERR(ssp_rng_create(stardis->allocator, SSP_RNG_THREEFRY, &rng)); + ERR(read_rng_state(stardis, str_cget(rng_in), rng)); + args->rng_state = rng; + } + + /* Try to open output files to detect errors early */ + if(is_master_process && (stardis->mode & MODE_BIN_GREEN)) { + const char* green_filename = str_cget(&stardis->bin_green_filename); + const char* path_filename = str_cget(&stardis->end_paths_filename); + + if((fp_green = fopen(green_filename, "wb")) == NULL) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open file '%s' for binary writing.\n", green_filename); + res = RES_IO_ERR; + goto error; + } + + if(strlen(path_filename) != 0) { + if((fp_path = fopen(path_filename, "w")) == NULL) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open file '%s' for writing.\n", path_filename); + res = RES_IO_ERR; + goto error; + } + } + } + + /* Run the Green estimation */ + time_current(&t0); /* Calculation starts */ + ERR(sdis_solve_probe_boundary_green_function(stardis->sdis_scn, args, &green)); + time_current(&t1); /* Calculation ends */ + + /* No more to do for non master processes */ + if(is_master_process) goto exit; + + /* Write ASCII Green */ + if(stardis->mode & MODE_GREEN) { + ERR(dump_green_ascii(green, stardis, stdout)); + } + + /* Write binary Green */ + if(stardis->mode & MODE_BIN_GREEN) { + ERR(dump_green_bin(green, stardis, fp_green)); + if(fp_path) { + ERR(dump_paths_end(green, stardis, fp_path)); + } + } + + time_current(&t2); /* Output ends */ + + ERR(print_computation_time(NULL, stardis, start, &t0, &t1, &t2)); + + /* Note that the resulting RNG state is not written in an output file because + * the solver API does not provide a function to recover it. But in fact, the + * green function saves the RNG state after its estimation. Therefore, the API + * can be expected to provide such functionality soon. + * + * TODO write the RNG status of the Green function when it is available */ + +exit: + if(fp_green) CHK(fclose(fp_green) == 0); + if(fp_path) CHK(fclose(fp_path) == 0); + if(green) SDIS(green_function_ref_put(green)); + if(rng) SSP(rng_ref_put(rng)); + return res; +error: + goto exit; +} + +static res_T +setup_solve_probe_boundary_args + (struct stardis* stardis, + const struct stardis_probe_boundary* probe, + struct sdis_solve_probe_boundary_args* args) +{ + enum sdis_side probe_side = SDIS_SIDE_NULL__; + double uv[2] = {0, 0}; + size_t iprim = SIZE_MAX; + unsigned desc_ids[SG3D_PROP_TYPES_COUNT__]; + res_T res = RES_OK; + ASSERT(stardis && probe && args); + + /* Calculate the probe position on the boundary */ + ERR(move_to_boundary(stardis, probe->position, probe->time[0], &iprim, uv)); + + ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, + (unsigned)iprim, desc_ids)); + + ERR(setup_probe_side(stardis, desc_ids, probe->side, iprim, &probe_side)); + ERR(setup_thermal_contact_resistance(stardis, desc_ids, probe_side)); + + /* Setup of solve input parameters */ + args->nrealisations = stardis->samples; + args->iprim = iprim; + args->uv[0] = uv[0]; + args->uv[1] = uv[1]; + args->time_range[0] = probe->time[0]; + args->time_range[1] = probe->time[1]; + args->picard_order = stardis->picard_order; + args->side = probe_side; + args->register_paths = stardis->dump_paths; + args->diff_algo = stardis->diff_algo; + + /* The solver does not accept that the side of the interface on which the + * probe is placed is invalid. Below, the side is arbitrarily defined because + * at this point, Stardis has already arbitrated that this side does not + * matter (i.e. there is no thermal contact resistance) */ + if(args->side == SDIS_SIDE_NULL__) { + args->side = SDIS_FRONT; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +compute_single_probe_on_interface + (struct stardis* stardis, + struct time* start, + const struct stardis_probe_boundary* probe) +{ + struct sdis_solve_probe_boundary_args args + = SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT; + res_T output_status[2] = {RES_OK, RES_OK}; + res_T res = RES_OK; + ASSERT(stardis && start && probe); + + ERR(setup_solve_probe_boundary_args(stardis, probe, &args)); + + /* Run the calculation */ + if(stardis->mode & (MODE_GREEN | MODE_BIN_GREEN)) { + ERR(solve_green(stardis, start, &args)); + } else { + ERR(solve(stardis, start, &args, output_status)); + } + +exit: + res = (res != RES_OK ? res : output_status[0]); + res = (res != RES_OK ? res : output_status[1]); + return res; +error: + goto exit; +} + +static res_T +compute_multiple_probes_on_interface + (struct stardis* stardis, + struct time* start) +{ + /* Probes */ + const struct stardis_probe_boundary* probes = NULL; + struct sdis_solve_probe_boundary_args* solve_args = NULL; + struct sdis_solve_probe_boundary_list_args solve_list_args = + SDIS_SOLVE_PROBE_BOUNDARY_LIST_ARGS_DEFAULT; + size_t nprobes = 0; + + /* Miscellaneous */ + res_T output_status = RES_OK; + res_T res = RES_OK; + size_t i= 0; + ASSERT(stardis && start); + + /* Fetch the list of probes arguments */ + probes = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list); + nprobes = darray_probe_boundary_size_get(&stardis->probe_boundary_list); + ASSERT(nprobes > 1); + + solve_args = MEM_CALLOC(stardis->allocator, nprobes, sizeof(*solve_args)); + if(!probes) { + logger_print(stardis->logger, LOG_ERROR, + "Argument list allocation error for resolving multiple probes " + "on the boundary.\n"); + res = RES_MEM_ERR; + goto error; + } + + /* Setup the solve arguments */ + FOR_EACH(i, 0, nprobes) { + solve_args[i] = SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT; + ERR(setup_solve_probe_boundary_args(stardis, &probes[i], &solve_args[i])); + } + solve_list_args.probes = solve_args; + solve_list_args.nprobes = nprobes; + + /* Run calculations */ + ERR(solve_list(stardis, start, &solve_list_args, &output_status)); + +exit: + if(probes) MEM_RM(stardis->allocator, solve_args); + res = (res != RES_OK ? res : output_status); + return res; +error: + goto exit; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +compute_probe_on_interface(struct stardis* stardis, struct time* start) +{ + res_T res = RES_OK; + ASSERT(stardis && start); + ASSERT((stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) + || (stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE)); + + /* Multiple probes */ + if(stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE) { + ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) > 1); + + res = compute_multiple_probes_on_interface(stardis, start); + if(res != RES_OK) goto error; + + /* Single probe */ + } else if(stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) { + const struct stardis_probe_boundary* probe = NULL; + ASSERT(darray_probe_boundary_size_get(&stardis->probe_boundary_list) == 1); + + probe = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list); + res = compute_single_probe_on_interface(stardis, start, probe); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -192,7 +192,6 @@ hit_filter static res_T check_probe_conform_to_type (const struct stardis* stardis, - const int move2boundary, double pos[3], double time, unsigned* iprim, @@ -207,7 +206,7 @@ check_probe_conform_to_type struct s3d_vertex_data attribs; struct filter_ctx filter_ctx = FILTER_CTX_DEFAULT__; float origin[3]; - unsigned vcount, tcount, j; + unsigned vcount, tcount; ASSERT(stardis && pos && iprim && uv); @@ -244,175 +243,80 @@ check_probe_conform_to_type } ASSERT(filter_ctx.dist == hit.distance); - if(move2boundary) { - /* Need to move probe to closest boundary */ - int danger = 0; - if(filter_ctx.outside) { - /* Not an error as probe moved to boundary */ - logger_print(stardis->logger, LOG_WARNING, - "Probe was outside the model.\n"); - } - if(!filter_ctx.desc) { - /* Not an error as probe moved to boundary */ - if(!filter_ctx.probe_on_boundary && !filter_ctx.outside) - logger_print(stardis->logger, LOG_WARNING, - "Could not determine the medium probe is in.\n"); - } else { - if(DESC_IS_SOLID(filter_ctx.desc)) { - double delta; - const char* pppp; - if(filter_ctx.desc->type == DESC_MAT_SOLID) { - struct solid* solid = filter_ctx.desc->d.solid; - delta = solid->delta; - pppp = ""; - } else { - struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog; - struct stardis_vertex vtx; - ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG); - d3_set(vtx.P, pos); - vtx.time = time; - delta = solid_prog->delta(&vtx, solid_prog->prog_data); - pppp = "programmed "; - } - ASSERT(delta < INF); - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in %ssolid '%s'.\n", - pppp, str_cget(get_description_name(filter_ctx.desc))); - if(filter_ctx.dist > 2 * delta) { - logger_print(stardis->logger, LOG_ERROR, - "Probe moved to (%g, %g, %g), primitive %u, uv = (%g, %g).\n", - SPLIT3(filter_ctx.pos), hit.prim.prim_id, SPLIT2(hit.uv)); - logger_print(stardis->logger, LOG_ERROR, - "Move is %g delta long. Use -p instead of -P.\n", - filter_ctx.dist / delta); - res = RES_BAD_ARG; - goto error; - } - if(filter_ctx.dist > 0.5 * delta) { - logger_print(stardis->logger, LOG_WARNING, - "Probe was %g delta from closest boundary. " - "Consider using -p instead of -P.\n", - filter_ctx.dist / delta); - } else { - if(filter_ctx.dist != 0) - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was %g delta from closest boundary.\n", - filter_ctx.dist / delta); - } - } else { - const char* pppp; - ASSERT(DESC_IS_FLUID(filter_ctx.desc)); - /* TODO: check move length wrt local geometry? */ - if(filter_ctx.desc->type == DESC_MAT_FLUID) { - pppp = ""; - } else { - ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); - pppp = "programmed "; - } - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in %sfluid '%s'.\n", - pppp, str_cget(get_description_name(filter_ctx.desc))); - logger_print(stardis->logger, LOG_OUTPUT, - "Probe distance from closest boundary was %g.\n", filter_ctx.dist); - } - } - /* Check if moved to vertex/edge */ - FOR_EACH(j, 0, 2) { - if(CLAMP(hit.uv[j], 0.0005, 0.9995) != hit.uv[j]) - danger++; - } - if(danger) { - logger_print(stardis->logger, LOG_WARNING, - "Probe %s close to / on %s. " - "If computation fails, try moving it slightly.\n", - (filter_ctx.dist != 0 ? "moved" : "is"), (danger == 1 ? "an edge" : "a vertex")); - } - if(filter_ctx.probe_on_boundary) { - logger_print(stardis->logger, LOG_OUTPUT, - "Probe is on primitive %u, uv = (%g, %g), not moved.\n", - hit.prim.prim_id, SPLIT2(hit.uv)); + /* Need to check medium */ + if(filter_ctx.outside) { + logger_print(stardis->logger, LOG_ERROR, + "Probe is outside the model.\n"); + logger_print(stardis->logger, LOG_ERROR, + "Closest geometry is primitive %u, uv = (%g, %g), pos (%g, %g, %g).\n", + hit.prim.prim_id, SPLIT2(hit.uv), SPLIT3(filter_ctx.pos)); + res = RES_BAD_ARG; + goto error; + } + if(filter_ctx.probe_on_boundary) { + logger_print(stardis->logger, LOG_ERROR, + "Probe is on primitive %u, uv = (%g, %g). Use -P instead of -p.\n", + hit.prim.prim_id, SPLIT2(hit.uv)); + res = RES_BAD_ARG; + goto error; + } + if(!filter_ctx.desc) { + logger_print(stardis->logger, LOG_ERROR, + "Could not determine the medium probe is in. " + "Try moving it slightly.\n"); + logger_print(stardis->logger, LOG_ERROR, + "Closest geometry is primitive %u, uv = (%g, %g), distance %g.\n", + hit.prim.prim_id, SPLIT2(hit.uv), filter_ctx.dist); + res = RES_BAD_ARG; + goto error; + } + if(DESC_IS_SOLID(filter_ctx.desc)) { + double delta; + if(filter_ctx.desc->type == DESC_MAT_SOLID) { + struct solid* solid = filter_ctx.desc->d.solid; + delta = solid->delta; } else { - logger_print(stardis->logger, LOG_OUTPUT, - "Probe moved to (%g, %g, %g), primitive %u, uv = (%g, %g).\n", - SPLIT3(filter_ctx.pos), hit.prim.prim_id, SPLIT2(hit.uv)); + struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog; + struct stardis_vertex vtx; + ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG); + d3_set(vtx.P, pos); + vtx.time = time; + delta = solid_prog->delta(&vtx, solid_prog->prog_data); } - d3_set_f3(pos, filter_ctx.pos); - } else { - /* Need to check medium */ - if(filter_ctx.outside) { + if(filter_ctx.dist < 0.25 * delta) { logger_print(stardis->logger, LOG_ERROR, - "Probe is outside the model.\n"); + "Probe is %g delta from closest boundary. Use -P instead of -p.\n", + filter_ctx.dist / delta); logger_print(stardis->logger, LOG_ERROR, - "Closest geometry is primitive %u, uv = (%g, %g), pos (%g, %g, %g).\n", - hit.prim.prim_id, SPLIT2(hit.uv), SPLIT3(filter_ctx.pos)); - res = RES_BAD_ARG; - goto error; - } - if(filter_ctx.probe_on_boundary) { - logger_print(stardis->logger, LOG_ERROR, - "Probe is on primitive %u, uv = (%g, %g). Use -P instead of -p.\n", + "Closest geometry is primitive %u, uv = (%g, %g).\n", hit.prim.prim_id, SPLIT2(hit.uv)); res = RES_BAD_ARG; goto error; } - if(!filter_ctx.desc) { - logger_print(stardis->logger, LOG_ERROR, - "Could not determine the medium probe is in. " - "Try moving it slightly.\n"); - logger_print(stardis->logger, LOG_ERROR, - "Closest geometry is primitive %u, uv = (%g, %g), distance %g.\n", - hit.prim.prim_id, SPLIT2(hit.uv), filter_ctx.dist); - res = RES_BAD_ARG; - goto error; + if(filter_ctx.dist < 0.5 * delta) { + logger_print(stardis->logger, LOG_WARNING, + "Probe is %g delta from closest boundary. " + "Consider using -P instead of -p.\n", + filter_ctx.dist / delta); + } else { + logger_print(stardis->logger, LOG_OUTPUT, + "Probe is %g delta from closest boundary.\n", + filter_ctx.dist / delta); } - if(DESC_IS_SOLID(filter_ctx.desc)) { - double delta; - if(filter_ctx.desc->type == DESC_MAT_SOLID) { - struct solid* solid = filter_ctx.desc->d.solid; - delta = solid->delta; - } else { - struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog; - struct stardis_vertex vtx; - ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG); - d3_set(vtx.P, pos); - vtx.time = time; - delta = solid_prog->delta(&vtx, solid_prog->prog_data); - } - if(filter_ctx.dist < 0.25 * delta) { - logger_print(stardis->logger, LOG_ERROR, - "Probe is %g delta from closest boundary. Use -P instead of -p.\n", - filter_ctx.dist / delta); - logger_print(stardis->logger, LOG_ERROR, - "Closest geometry is primitive %u, uv = (%g, %g).\n", - hit.prim.prim_id, SPLIT2(hit.uv)); - res = RES_BAD_ARG; - goto error; - } - if(filter_ctx.dist < 0.5 * delta) { - logger_print(stardis->logger, LOG_WARNING, - "Probe is %g delta from closest boundary. " - "Consider using -P instead of -p.\n", - filter_ctx.dist / delta); - } else { - logger_print(stardis->logger, LOG_OUTPUT, - "Probe is %g delta from closest boundary.\n", - filter_ctx.dist / delta); - } + } else { + ASSERT(DESC_IS_FLUID(filter_ctx.desc)); + /* In fluid; TODO: check distance wrt local geometry (use 4V/S?) */ + if(filter_ctx.desc->type == DESC_MAT_FLUID) { + logger_print(stardis->logger, LOG_WARNING, + "Probe is in fluid '%s': computing fluid temperature, " + "not using a specific position.\n", + str_cget(&filter_ctx.desc->d.fluid->name)); } else { - ASSERT(DESC_IS_FLUID(filter_ctx.desc)); - /* In fluid; TODO: check distance wrt local geometry (use 4V/S?) */ - if(filter_ctx.desc->type == DESC_MAT_FLUID) { - logger_print(stardis->logger, LOG_WARNING, - "Probe is in fluid '%s': computing fluid temperature, " - "not using a specific position.\n", - str_cget(&filter_ctx.desc->d.fluid->name)); - } else { - ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); - logger_print(stardis->logger, LOG_WARNING, - "Probe is in fluid_prog '%s': computing fluid temperature, " - "not using a specific position.\n", - str_cget(&filter_ctx.desc->d.fluid_prog->name)); - } + ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); + logger_print(stardis->logger, LOG_WARNING, + "Probe is in fluid_prog '%s': computing fluid temperature, " + "not using a specific position.\n", + str_cget(&filter_ctx.desc->d.fluid_prog->name)); } } @@ -490,12 +394,13 @@ compute_probe(struct stardis* stardis, struct time* start) ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE)); - ERR(check_probe_conform_to_type(stardis, 0, stardis->probe, + ERR(check_probe_conform_to_type(stardis, stardis->probe, stardis->time_range[0], &iprim, uv)); args.nrealisations = stardis->samples; d3_set(args.position, stardis->probe); d2_set(args.time_range, stardis->time_range); + args.diff_algo = stardis->diff_algo; /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); @@ -510,7 +415,8 @@ compute_probe(struct stardis* stardis, struct time* start) stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->bin_green_filename)); + "cannot open file '%s' for binary writing.\n", + str_cget(&stardis->bin_green_filename)); res = RES_IO_ERR; goto error; } @@ -520,7 +426,8 @@ compute_probe(struct stardis* stardis, struct time* start) stream_p = fopen(str_cget(&stardis->end_paths_filename), "w"); if(!stream_p) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->end_paths_filename)); + "cannot open file '%s' for writing.\n", + str_cget(&stardis->end_paths_filename)); res = RES_IO_ERR; goto error; } @@ -550,12 +457,14 @@ compute_probe(struct stardis* stardis, struct time* start) if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_probe(stardis->sdis_scn, &args, &estimator)); } else { + struct sdis_mc time = SDIS_MC_NULL; res_T tmp_res1, tmp_res2; time_current(&compute_start); ERR(sdis_solve_probe(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); - ERR(print_computation_time(estimator, stardis, - start, &compute_start, &compute_end, NULL)); + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time + (&time, stardis, start, &compute_start, &compute_end, NULL)); tmp_res1 = print_single_MC_result(estimator, stardis, stdout); /* Dump recorded paths according to user settings */ @@ -583,266 +492,6 @@ error: } static res_T -compute_probe_on_interface(struct stardis* stardis, struct time* start) -{ - res_T res = RES_OK; - double uv[2] = { 0,0 }; - unsigned iprim = UINT_MAX; - struct sdis_estimator* estimator = NULL; - struct sdis_green_function* green = NULL; - struct dump_path_context dump_ctx; - struct sdis_solve_probe_boundary_args args - = SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT; - FILE* stream_r = NULL; - FILE* stream_g = NULL; - FILE* stream_p = NULL; - struct time compute_start, compute_end; - enum sdis_side compute_side; - unsigned prop[3]; - const struct description* descriptions - = darray_descriptions_cdata_get(&stardis->descriptions); - double tcr = 0; - const char* solve_name; - const char* compute_side_name = NULL; - const char* medium_name = NULL; - const struct description* intface_desc = NULL; -#ifndef NDEBUG - const size_t dcount = darray_descriptions_size_get(&stardis->descriptions); -#endif - - ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE)); - ERR(check_probe_conform_to_type(stardis, 1, stardis->probe, - stardis->time_range[0], &iprim, uv)); - ASSERT(iprim != UINT_MAX); - - ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, - (unsigned)iprim, prop)); - - if(prop[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY) { - ASSERT(prop[SG3D_INTFACE] < dcount); - intface_desc = descriptions + prop[SG3D_INTFACE]; - if(intface_desc->type == DESC_SOLID_SOLID_CONNECT) - tcr = intface_desc->d.ss_connect->tcr; - } - - if(str_is_empty(&stardis->solve_name)) { - solve_name = NULL; - compute_side = SDIS_SIDE_NULL__; /* Side is let unspecified */ - } else { - solve_name = str_cget(&stardis->solve_name); - if(0 == strcasecmp(solve_name, "FRONT")) { - const struct description* d; - ASSERT(prop[SG3D_FRONT] < dcount); - d = descriptions + prop[SG3D_FRONT]; - ASSERT(DESC_IS_MEDIUM(d)); - medium_name = str_cget(get_description_name(d)); - compute_side = SDIS_FRONT; - compute_side_name = "FRONT"; - } - else if(0 == strcasecmp(solve_name, "BACK")) { - const struct description* d; - ASSERT(prop[SG3D_BACK] < dcount); - d = descriptions + prop[SG3D_BACK]; - ASSERT(DESC_IS_MEDIUM(d)); - medium_name = str_cget(get_description_name(d)); - compute_side = SDIS_BACK; - compute_side_name = "BACK"; - } else { /* solve_name must be a medium name */ - unsigned med_id, fmat_id, bmat_id; - const struct description* fd; - const struct description* bd; - struct sdis_medium* medium - = find_medium_by_name(stardis, &stardis->solve_name, &med_id); - if(medium == NULL) { /* Not found */ - logger_print(stardis->logger, LOG_ERROR, - "Cannot locate side from medium name '%s' (unknown medium)\n", - solve_name); - res = RES_BAD_ARG; - goto error; - } - - fd = descriptions + prop[SG3D_FRONT]; - bd = descriptions + prop[SG3D_BACK]; - ASSERT(DESC_IS_MEDIUM(fd)); - ASSERT(DESC_IS_MEDIUM(bd)); - description_get_medium_id(fd, &fmat_id); - description_get_medium_id(bd, &bmat_id); - - if(med_id != fmat_id && med_id != bmat_id) { /* Not here */ - logger_print(stardis->logger, LOG_ERROR, - "Medium '%s' is not used at this interface (prim id=%u)\n", - solve_name, iprim); - res = RES_BAD_ARG; - goto error; - } - if(fmat_id == bmat_id) { /* Cannot differentiate */ - unsigned encs[2]; - ERR(senc3d_scene_get_triangle_enclosures(stardis->senc3d_scn, iprim, - encs)); - logger_print(stardis->logger, LOG_ERROR, - "Medium '%s' is used on both sides of this interface (prim id=%u)\n", - solve_name,iprim); - logger_print(stardis->logger, LOG_ERROR, - "Side must be defined using either FRONT or BACK.\n"); - logger_print(stardis->logger, LOG_ERROR, - "FRONT side is related to enclosure %u, BACK side to enclosure %u.\n", - encs[SENC3D_FRONT], encs[SENC3D_BACK]); - res = RES_BAD_ARG; - goto error; - } - medium_name = solve_name; - if(med_id == fmat_id) { - compute_side = SDIS_FRONT; - compute_side_name = "FRONT"; - } else { - compute_side = SDIS_BACK; - compute_side_name = "BACK"; - } - } - } - - if(compute_side == SDIS_SIDE_NULL__) { - /* Cannot have defined a contact resistance here */ - if(tcr != 0) { - const struct description* fdesc = NULL; - const struct description* bdesc = NULL; - if(prop[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY) { - ASSERT(prop[SG3D_FRONT] < dcount); - fdesc = descriptions + prop[SG3D_FRONT]; - } - if(prop[SG3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) { - ASSERT(prop[SG3D_BACK] < dcount); - bdesc = descriptions + prop[SG3D_BACK]; - } - ASSERT(fdesc || bdesc); - logger_print(stardis->logger, LOG_ERROR, - "Cannot let probe computation side unspecified on an interface with a " - "non-nul thermal resistance.\n"); - logger_print(stardis->logger, LOG_ERROR, - "Interface '%s',%s%s%s%s%s%s%s, resistance=%g K.m^2/W.\n", - str_cget(get_description_name(intface_desc)), - (fdesc ? " FRONT:'" : ""), - (fdesc ? str_cget(get_description_name(fdesc)) : ""), - (fdesc ? "'" : ""), - (fdesc && bdesc ? "," : ""), - (bdesc ? " BACK:'" : ""), - (bdesc ? str_cget(get_description_name(bdesc)) : ""), - (bdesc ? "'" : ""), - tcr); - res = RES_BAD_ARG; - goto error; - } - /* Any side is OK as temperature is the same */ - compute_side = SDIS_FRONT; - } else if (tcr == 0) { - /* Warn if side defined and no resistance defined */ - logger_print(stardis->logger, LOG_WARNING, - "Specifying a compute side at an interface with no contact resistance " - "is meaningless.\n"); - } - - if(tcr > 0) { - ASSERT(compute_side_name && medium_name); - logger_print(stardis->logger, LOG_OUTPUT, - "Probe computation on an interface with a thermal resistance = %g K.m^2/W " - "on %s side (medium is '%s').\n", - tcr, compute_side_name, medium_name); - } - - args.nrealisations = stardis->samples; - args.iprim = iprim; - d2_set(args.uv, uv); - args.side = compute_side; - d2_set(args.time_range, stardis->time_range); - - /* Input random state? */ - READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); - - if(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)) { - if(stardis->mpi_initialized && stardis->mpi_rank != 0) { - ERR(sdis_solve_probe_boundary_green_function(stardis->sdis_scn, &args, - &green)); - } else { - /* Try to open output files to detect errors early */ - if(stardis->mode & MODE_BIN_GREEN) { - ASSERT(!str_is_empty(&stardis->bin_green_filename)); - stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); - if(!stream_g) { - logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->bin_green_filename)); - res = RES_IO_ERR; - goto error; - } - if(str_cget(&stardis->end_paths_filename) - && strlen(str_cget(&stardis->end_paths_filename))) - { - stream_p = fopen(str_cget(&stardis->end_paths_filename), "w"); - if(!stream_p) { - logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->end_paths_filename)); - res = RES_IO_ERR; - goto error; - } - } - } - /* Call solve() */ - time_current(&compute_start); - ERR(sdis_solve_probe_boundary_green_function(stardis->sdis_scn, &args, - &green)); - time_current(&compute_end); - if(stardis->mode & MODE_BIN_GREEN) { - struct time output_end; - ERR(dump_green_bin(green, stardis, stream_g)); - if(stream_p) { - ERR(dump_paths_end(green, stardis, stream_p)); - } - time_current(&output_end); - ERR(print_computation_time(NULL, stardis, - start, &compute_start, &compute_end, &output_end)); - } - if(stardis->mode & MODE_GREEN) { - ERR(dump_green_ascii(green, stardis, stdout)); - } - } - } else { - args.register_paths = stardis->dump_paths; - args.picard_order = stardis->picard_order; - if(stardis->mpi_initialized && stardis->mpi_rank != 0) { - ERR(sdis_solve_probe_boundary(stardis->sdis_scn, &args, &estimator)); - } else { - res_T tmp_res1, tmp_res2; - time_current(&compute_start); - ERR(sdis_solve_probe_boundary(stardis->sdis_scn, &args, &estimator)); - time_current(&compute_end); - ERR(print_computation_time(estimator, stardis, - start, &compute_start, &compute_end, NULL)); - tmp_res1 = print_single_MC_result(estimator, stardis, stdout); - - /* Dump recorded paths according to user settings */ - dump_ctx.stardis = stardis; - dump_ctx.rank = 0; - tmp_res2 = sdis_estimator_for_each_path(estimator, dump_path, &dump_ctx); - if(tmp_res1 != RES_OK) res = tmp_res1; - else if(tmp_res2 != RES_OK) res = tmp_res2; - } - } - - /* Output random state? */ - WRITE_RANDOM_STATE(&stardis->rndgen_state_out_filename); - -end: - if(stream_r) fclose(stream_r); - if(stream_g) fclose(stream_g); - if(stream_p) fclose(stream_p); - if(estimator) SDIS(estimator_ref_put(estimator)); - if(green) SDIS(green_function_ref_put(green)); - if(args.rng_state) SSP(rng_ref_put(args.rng_state)); - return res; -error: - goto end; -} - -static res_T auto_look_at (struct sdis_scene* scn, const double fov_x, /* Horizontal field of view in radian */ @@ -965,6 +614,7 @@ compute_camera(struct stardis* stardis, struct time* start) args.spp = (size_t)stardis->camera.spp; args.register_paths = stardis->dump_paths; args.picard_order = stardis->picard_order; + args.diff_algo = stardis->diff_algo; /* Launch the simulation */ if(stardis->mpi_initialized && stardis->mpi_rank != 0) { @@ -980,6 +630,9 @@ compute_camera(struct stardis* stardis, struct time* start) else { stream = fopen(str_cget(&stardis->camera.file_name), "w"); if(!stream) { + logger_print(stardis->logger, LOG_ERROR, + "cannot open file '%s' for writing.\n", + str_cget(&stardis->camera.file_name)); res = RES_IO_ERR; goto error; } @@ -1033,7 +686,7 @@ compute_medium(struct stardis* stardis, struct time* start) ASSERT(stardis && start && (stardis->mode & MODE_MEDIUM_COMPUTE)); /* Find medium */ - medium = find_medium_by_name(stardis, &stardis->solve_name, NULL); + medium = find_medium_by_name(stardis, str_cget(&stardis->solve_name), NULL); if(medium == NULL) { /* Not found */ logger_print(stardis->logger, LOG_ERROR, "Cannot solve medium '%s' (unknown medium)\n", @@ -1045,6 +698,7 @@ compute_medium(struct stardis* stardis, struct time* start) args.nrealisations = stardis->samples; args.medium = medium; d2_set(args.time_range, stardis->time_range); + args.diff_algo = stardis->diff_algo; /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); @@ -1059,7 +713,8 @@ compute_medium(struct stardis* stardis, struct time* start) stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->bin_green_filename)); + "cannot open file '%s' for binary writing.\n", + str_cget(&stardis->bin_green_filename)); res = RES_IO_ERR; goto error; } @@ -1069,7 +724,8 @@ compute_medium(struct stardis* stardis, struct time* start) stream_p = fopen(str_cget(&stardis->end_paths_filename), "w"); if(!stream_p) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->end_paths_filename)); + "cannot open file '%s' for writing.\n", + str_cget(&stardis->end_paths_filename)); res = RES_IO_ERR; goto error; } @@ -1100,12 +756,15 @@ compute_medium(struct stardis* stardis, struct time* start) if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_medium(stardis->sdis_scn, &args, &estimator)); } else { + struct sdis_mc time = SDIS_MC_NULL; res_T tmp_res1, tmp_res2; time_current(&compute_start); ERR(sdis_solve_medium(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); - ERR(print_computation_time(estimator, stardis, - start, &compute_start, &compute_end, NULL)); + + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time + (&time, stardis, start, &compute_start, &compute_end, NULL)); tmp_res1 = print_single_MC_result(estimator, stardis, stdout); /* Dump recorded paths according to user settings */ dump_ctx.stardis = stardis; @@ -1201,6 +860,7 @@ compute_boundary(struct stardis* stardis, struct time* start) args.nprimitives = darray_size_t_size_get(&stardis->compute_surface.primitives); d2_set(args.time_range, stardis->time_range); + args.diff_algo = stardis->diff_algo; /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); @@ -1215,7 +875,8 @@ compute_boundary(struct stardis* stardis, struct time* start) stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->bin_green_filename)); + "cannot open file '%s' for binary writing.\n", + str_cget(&stardis->bin_green_filename)); res = RES_IO_ERR; goto error; } @@ -1225,7 +886,8 @@ compute_boundary(struct stardis* stardis, struct time* start) stream_p = fopen(str_cget(&stardis->end_paths_filename), "w"); if(!stream_p) { logger_print(stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", str_cget(&stardis->end_paths_filename)); + "cannot open file '%s' for writing.\n", + str_cget(&stardis->end_paths_filename)); res = RES_IO_ERR; goto error; } @@ -1255,12 +917,14 @@ compute_boundary(struct stardis* stardis, struct time* start) if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_boundary(stardis->sdis_scn, &args, &estimator)); } else { + struct sdis_mc time = SDIS_MC_NULL; res_T tmp_res1, tmp_res2; time_current(&compute_start); ERR(sdis_solve_boundary(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); - ERR(print_computation_time(estimator, stardis, - start, &compute_start, &compute_end, NULL)); + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time + (&time, stardis, start, &compute_start, &compute_end, NULL)); tmp_res1 = print_single_MC_result(estimator, stardis, stdout); /* Dump recorded paths according to user settings */ dump_ctx.stardis = stardis; @@ -1307,6 +971,7 @@ compute_flux_boundary(struct stardis* stardis, struct time* start) = darray_size_t_size_get(&stardis->compute_surface.primitives); args.picard_order = stardis->picard_order; d2_set(args.time_range, stardis->time_range); + args.diff_algo = stardis->diff_algo; /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); @@ -1314,12 +979,14 @@ compute_flux_boundary(struct stardis* stardis, struct time* start) if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_boundary_flux(stardis->sdis_scn, &args, &estimator)); } else { + struct sdis_mc time = SDIS_MC_NULL; res_T tmp_res1, tmp_res2; time_current(&compute_start); ERR(sdis_solve_boundary_flux(stardis->sdis_scn, &args, &estimator)); time_current(&compute_end); - ERR(print_computation_time(estimator, stardis, - start, &compute_start, &compute_end, NULL)); + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time + (&time, stardis, start, &compute_start, &compute_end, NULL)); tmp_res1 = print_single_MC_result(estimator, stardis, stdout); /* Dump recorded paths according to user settings */ @@ -1375,6 +1042,7 @@ compute_map(struct stardis* stardis, struct time* start) d2_set(args.time_range, stardis->time_range); args.register_paths = stardis->dump_paths; args.picard_order = stardis->picard_order; + args.diff_algo = stardis->diff_algo; ERR(sdis_solve_boundary(stardis->sdis_scn, &args, darray_estimators_data_get(&estimators) + p)); @@ -1407,7 +1075,7 @@ error: struct sdis_medium* find_medium_by_name (struct stardis* stardis, - const struct str* name, + const char* name, unsigned* out_id) { struct sdis_medium* medium = NULL; @@ -1419,7 +1087,7 @@ find_medium_by_name unsigned id; struct description* desc = darray_descriptions_data_get(&stardis->descriptions) + i; - if(!str_eq(name, get_description_name(desc))) + if(strcmp(name, str_cget(get_description_name(desc))) != 0) continue; description_get_medium_id(desc, &id); ASSERT(darray_media_ptr_size_get(&stardis->media) > id); @@ -1518,6 +1186,8 @@ stardis_compute ERR(compute_probe(stardis, start)); else if(stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) ERR(compute_probe_on_interface(stardis, start)); + else if(stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE) + ERR(compute_probe_on_interface(stardis, start)); else if(stardis->mode & MODE_IR_COMPUTE) ERR(compute_camera(stardis, start)); else if(stardis->mode & MODE_MEDIUM_COMPUTE) diff --git a/src/stardis-compute.h b/src/stardis-compute.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -27,19 +27,24 @@ struct str; #define DARRAY_DATA struct sdis_estimator* #include <rsys/dynamic_array.h> -struct sdis_medium* +extern LOCAL_SYM struct sdis_medium* find_medium_by_name (struct stardis* stardis, - const struct str* name, + const char* name, unsigned* id); /* Can be NULL */ -res_T +extern LOCAL_SYM res_T stardis_compute (struct stardis* stardis, struct time* start); -res_T +extern LOCAL_SYM res_T read_compute_surface (struct stardis* stardis); +extern LOCAL_SYM res_T +compute_probe_on_interface + (struct stardis* stardis, + struct time* start); + #endif diff --git a/src/stardis-description.c b/src/stardis-description.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-description.h b/src/stardis-description.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-extern-source.c b/src/stardis-extern-source.c @@ -0,0 +1,239 @@ +/* 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/>. */ + +#include "stardis-app.h" +#include "stardis-extern-source.h" + +#include <sdis.h> +#include <rsys/cstr.h> +#include <rsys/logger.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +sphere_get_position(const double time, double pos[3], struct sdis_data* data) +{ + const struct spherical_source* src = NULL; + ASSERT(pos); + (void)time; + + src = *((const struct spherical_source* const*)sdis_data_cget(data)); + pos[0] = src->position[0]; + pos[1] = src->position[1]; + pos[2] = src->position[2]; +} + +static double +sphere_get_power(const double time, struct sdis_data* data) +{ + const struct spherical_source* src = NULL; + (void)time; + + src = *((const struct spherical_source* const*)sdis_data_cget(data)); + return src->power; /* [W] */ +} + +static double +sphere_get_diffuse_radiance + (const double time, + const double dir[3], + struct sdis_data* data) +{ + const struct spherical_source* src = NULL; + (void)time, (void)dir; + + src = *((const struct spherical_source* const*)sdis_data_cget(data)); + return src->diffuse_radiance; /* [W/m^2/sr] */ +} + +static res_T +create_solver_source_sphere + (struct extern_source* src, + struct stardis* stardis) +{ + struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL; + struct sdis_data* data = NULL; + res_T res = RES_OK; + ASSERT(src && src->type == EXTERN_SOURCE_SPHERE && stardis); + + /* Register with the solver source a pointer to the external source */ + res = sdis_data_create(stardis->dev, sizeof(struct spherical_source*), + ALIGNOF(struct spherical_source*), NULL, &data); + if(res != RES_OK) goto error; + *((struct spherical_source**)sdis_data_get(data)) = &src->data.sphere; + + /* Create the spherical source */ + shader.position = sphere_get_position; + shader.power = sphere_get_power; + shader.diffuse_radiance = sphere_get_diffuse_radiance; + shader.radius = src->data.sphere.radius; + res = sdis_spherical_source_create(stardis->dev, &shader, data, &src->sdis_src); + if(res != RES_OK) goto error; + +exit: + /* Release the local reference on the data: it is kept by the sdis source */ + if(data) SDIS(data_ref_put(data)); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the external spherical source for the solver -- %s\n", + res_to_cstr(res)); + goto exit; +} + +static void +sphere_prog_get_position(const double time, double pos[3], struct sdis_data* data) +{ + const struct spherical_source_prog* src = NULL; + ASSERT(pos); + + src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); + src->position(time, pos, src->data);; +} + +static double +sphere_prog_get_power(const double time, struct sdis_data* data) +{ + const struct spherical_source_prog* src = NULL; + + src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); + return src->power(time, src->data); +} + +static double +sphere_prog_get_diffuse_radiance + (const double time, + const double dir[3], + struct sdis_data* data) +{ + const struct spherical_source_prog* src = NULL; + + src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); + return src->diffuse_radiance(time, dir, src->data); +} + +static res_T +create_solver_source_sphere_prog + (struct extern_source* src, + struct stardis* stardis) +{ + struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL; + struct sdis_data* data = NULL; + res_T res = RES_OK; + ASSERT(src && src->type == EXTERN_SOURCE_SPHERE_PROG && stardis); + + /* Register a pointer to the external source with the solver source */ + res = sdis_data_create(stardis->dev, sizeof(struct spherical_source_prog*), + ALIGNOF(struct spherical_source_prog*), NULL, &data); + if(res != RES_OK) goto error; + *((struct spherical_source_prog**)sdis_data_get(data)) = &src->data.sphere_prog; + + /* Create the spherical source */ + shader.position = sphere_prog_get_position; + shader.power = sphere_prog_get_power; + shader.diffuse_radiance = sphere_prog_get_diffuse_radiance; + shader.radius = src->data.sphere_prog.radius; + res = sdis_spherical_source_create(stardis->dev, &shader, data, &src->sdis_src); + if(res != RES_OK) goto error; + +exit: + /* Release the local reference on the data: it is kept by the sdis source */ + if(data) SDIS(data_ref_put(data)); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the external spherical source for the solver -- %s\n", + res_to_cstr(res)); + goto exit; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +extern_source_init_sphere + (struct mem_allocator* allocator, + struct extern_source* src) +{ + ASSERT(src); + (void)allocator; + src->type = EXTERN_SOURCE_SPHERE; + src->data.sphere = SPHERICAL_SOURCE_NULL; + return RES_OK; +} + +res_T +extern_source_init_sphere_prog + (struct mem_allocator* allocator, + struct extern_source* src) +{ + ASSERT(src); + src->type = EXTERN_SOURCE_SPHERE_PROG; + src->data.sphere_prog = SPHERICAL_SOURCE_PROG_NULL; + src->data.sphere_prog.allocator = allocator; + str_init(allocator, &src->data.sphere_prog.prog_name); + return RES_OK; +} + +void +extern_source_release(struct extern_source* src) +{ + ASSERT(src); + if(src->type == EXTERN_SOURCE_SPHERE_PROG) { + struct spherical_source_prog* src_prog = &src->data.sphere_prog; + size_t i; + + if(src_prog->data) { + ASSERT(src_prog->release); + src_prog->release(src_prog->data); + } + + str_release(&src_prog->prog_name); + FOR_EACH(i, 0, src_prog->argc) { + MEM_RM(src_prog->allocator, src_prog->argv[i]); + } + + MEM_RM(src_prog->allocator, src_prog->argv); + } + + if(src->sdis_src) SDIS(source_ref_put(src->sdis_src)); +} + +res_T +extern_source_create_solver_source + (struct extern_source* src, + struct stardis* stardis) +{ + res_T res = RES_OK; + ASSERT(src); + + switch(src->type) { + case EXTERN_SOURCE_SPHERE: + res = create_solver_source_sphere(src, stardis); + if(res != RES_OK) goto error; + break; + case EXTERN_SOURCE_SPHERE_PROG: + res = create_solver_source_sphere_prog(src, stardis); + if(res != RES_OK) goto error; + break; + default: FATAL("Unreachable code\n"); break; + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/stardis-extern-source.h b/src/stardis-extern-source.h @@ -0,0 +1,118 @@ +/* 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/>. */ + +#ifndef SDIS_EXTERN_SOURCE_H +#define SDIS_EXTERN_SOURCE_H + +#include <rsys/rsys.h> + +/* Forward declaration */ +struct stardis; +struct stardis_description_create_context; + +enum source_type { + EXTERN_SOURCE_SPHERE, + EXTERN_SOURCE_SPHERE_PROG, + EXTERN_SOURCE_NONE__ +}; + +struct spherical_source { + double position[3]; + double radius; + double power; /* [W] */ + double diffuse_radiance; /* [W/m^2/sr] */ +}; +#define SPHERICAL_SOURCE_NULL__ {{0,0,0}, -1, 0, 0} +static const struct spherical_source SPHERICAL_SOURCE_NULL = + SPHERICAL_SOURCE_NULL__; + +struct spherical_source_prog { + struct str prog_name; + struct program* program; + void* data; /* Pointer toward the program data */ + struct mem_allocator* allocator; + + /* Input arguments */ + size_t argc; + char** argv; + + double radius; /* Not programmable */ + + void* + (*create) + (const struct stardis_description_create_context*, + void* lib_data, + size_t argc, + char* argv[]); + + void + (*release) + (void* data); + + double* + (*position) + (const double time, + double position[3], + void* data); + + double + (*power) + (const double time, + void* data); + + double + (*diffuse_radiance) + (const double time, + const double dir[3], + void* data); +}; +#define SPHERICAL_SOURCE_PROG_NULL__ \ + {{0}, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL} +static const struct spherical_source_prog SPHERICAL_SOURCE_PROG_NULL= + SPHERICAL_SOURCE_PROG_NULL__; + +/* Interface of an external source */ +struct extern_source { + enum source_type type; + union { + struct spherical_source sphere; + struct spherical_source_prog sphere_prog; + } data; + struct sdis_source* sdis_src; +}; +#define EXTERN_SOURCE_NULL__ \ + {EXTERN_SOURCE_NONE__, {SPHERICAL_SOURCE_NULL__}, NULL} +static const struct extern_source EXTERN_SOURCE_NULL = EXTERN_SOURCE_NULL__; + +extern LOCAL_SYM res_T +extern_source_init_sphere + (struct mem_allocator* allocator, + struct extern_source* src); + +extern LOCAL_SYM res_T +extern_source_init_sphere_prog + (struct mem_allocator* allocator, + struct extern_source* src); + +extern LOCAL_SYM void +extern_source_release + (struct extern_source* src); + +extern LOCAL_SYM res_T +extern_source_create_solver_source + (struct extern_source* src, + struct stardis* stardis); + +#endif /* SDIS_EXTERN_SOURCE_H */ diff --git a/src/stardis-fbound-prog.c b/src/stardis-fbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-fbound-prog.h b/src/stardis-fbound-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-fbound.c b/src/stardis-fbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -45,7 +45,7 @@ init_f_boundary str_init(allocator, &(*dst)->name); str_initialized = 1; (*dst)->mat_id = UINT_MAX; - (*dst)->imposed_flux = -1; + (*dst)->imposed_flux = SDIS_FLUX_NONE; end: return res; error: diff --git a/src/stardis-fbound.h b/src/stardis-fbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-fluid-prog.c b/src/stardis-fluid-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -81,6 +81,7 @@ create_solver_fluid_prog fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity; fluid_shader.volumic_mass = fluid_prog_get_volumic_mass; fluid_shader.temperature = fluid_prog_get_temperature; + fluid_shader.t0 = stardis->initial_time; ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*), ALIGNOF(struct fluid_prog*), NULL, &data)); @@ -114,6 +115,7 @@ create_solver_external_fluid_prog fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity; fluid_shader.volumic_mass = fluid_prog_get_volumic_mass; fluid_shader.temperature = fluid_prog_get_temperature; + fluid_shader.t0 = stardis->initial_time; /* temperature has to be provided by h_boundary_prog */ ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*), ALIGNOF(struct fluid_prog*), NULL, &data)); diff --git a/src/stardis-fluid-prog.h b/src/stardis-fluid-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-fluid.c b/src/stardis-fluid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -52,12 +52,12 @@ fluid_get_temperature struct sdis_data* data) { const struct fluid* const* fluid_props = sdis_data_cget(data); - if((*fluid_props)->imposed_temperature >= 0) + if(SDIS_TEMPERATURE_IS_KNOWN((*fluid_props)->imposed_temperature)) /* If there is an imposed temp, it is imposed regardless of time */ return (*fluid_props)->imposed_temperature; if(vtx->time <= (*fluid_props)->t0) { /* If time is <= t0: use tinit */ - if((*fluid_props)->tinit < 0) { + if(SDIS_TEMPERATURE_IS_UNKNOWN((*fluid_props)->tinit)) { if(str_is_empty(&(*fluid_props)->name)) { FATAL("fluid_get_temperature: getting undefined Tinit\n"); } else { @@ -67,7 +67,7 @@ fluid_get_temperature } return (*fluid_props)->tinit; } - return -1; /* Unknown temperature */ + return SDIS_TEMPERATURE_NONE; /* Unknown temperature */ } /******************************************************************************* @@ -88,6 +88,7 @@ create_solver_fluid fluid_shader.calorific_capacity = fluid_get_calorific_capacity; fluid_shader.volumic_mass = fluid_get_volumic_mass; fluid_shader.temperature = fluid_get_temperature; + fluid_shader.t0 = stardis->initial_time; ERR(sdis_data_create(stardis->dev, sizeof(struct fluid*), ALIGNOF(struct fluid*), NULL, &data)); @@ -122,8 +123,8 @@ init_fluid(struct mem_allocator* allocator, struct fluid** dst) str_initialized = 1; (*dst)->rho = 1; (*dst)->cp = 1; - (*dst)->tinit = -1; - (*dst)->imposed_temperature = -1; + (*dst)->tinit = SDIS_TEMPERATURE_NONE; + (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; (*dst)->t0 = 0; (*dst)->is_outside = 0; (*dst)->is_green = 0; @@ -154,10 +155,10 @@ str_print_fluid(struct str* str, const struct fluid* f) ASSERT(str && f); ERR(str_append_printf(str, "Fluid '%s': rho=%g cp=%g", str_cget(&f->name), f->rho, f->cp)); - if(f->tinit >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(f->tinit)) { ERR(str_append_printf(str, " Tinit=%g", f->tinit)); } - if(f->imposed_temperature >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(f->imposed_temperature)) { ERR(str_append_printf(str, " Temp=%g", f->imposed_temperature)); } ERR(str_append_printf(str, " (it is medium %u)", f->fluid_id)); diff --git a/src/stardis-fluid.h b/src/stardis-fluid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-green-types.h.in b/src/stardis-green-types.h.in @@ -21,8 +21,8 @@ /* The number of the file format as presented thereafter */ #define GREEN_FILE_FORMAT_VERSION @STARDIS_GREEN_TYPES_VERSION@ -/* The max length for a description name */ -#define DESC_NAME_MAX_LEN 63 +/* The max length for a description name *WITHOUT* null char */ +#define DESC_NAME_MAX_LEN @STARDIS_MAX_NAME_LENGTH@ /* The string at the beginning of a binary Green file that identifies it */ #define BIN_FILE_IDENT_STRING "GREEN_BIN_FILE:" diff --git a/src/stardis-hbound-prog.c b/src/stardis-hbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-hbound-prog.h b/src/stardis-hbound-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -41,8 +41,10 @@ struct h_boundary_prog { (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*ref_temp)(const struct stardis_interface_fragment*, void*); - double (*emissivity)(const struct stardis_interface_fragment*, void*); - double (*alpha)(const struct stardis_interface_fragment*, void*); + double (*emissivity) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); + double (*alpha) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); double (*hc)(const struct stardis_interface_fragment*, void*); double (*hmax)(void*); double* (*t_range)(void*, double trange[2]); diff --git a/src/stardis-hbound.c b/src/stardis-hbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -44,7 +44,7 @@ init_h_boundary } str_init(allocator, &(*dst)->name); str_initialized = 1; - (*dst)->imposed_temperature = -1; + (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; (*dst)->mat_id = UINT_MAX; end: return res; diff --git a/src/stardis-hbound.h b/src/stardis-hbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-hfbound-prog.c b/src/stardis-hfbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-hfbound-prog.h b/src/stardis-hfbound-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -41,8 +41,10 @@ struct hf_boundary_prog { (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*ref_temp)(const struct stardis_interface_fragment*, void*); - double (*emissivity)(const struct stardis_interface_fragment*, void*); - double (*alpha)(const struct stardis_interface_fragment*, void*); + double (*emissivity) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); + double (*alpha) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); double (*hc)(const struct stardis_interface_fragment*, void*); double (*hmax)(void*); double* (*t_range)(void*, double trange[2]); diff --git a/src/stardis-hfbound.c b/src/stardis-hfbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -44,7 +44,7 @@ init_hf_boundary } str_init(allocator, &(*dst)->name); str_initialized = 1; - (*dst)->imposed_temperature = -1; + (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; (*dst)->mat_id = UINT_MAX; end: return res; diff --git a/src/stardis-hfbound.h b/src/stardis-hfbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-intface.c b/src/stardis-intface.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -80,20 +80,22 @@ interface_get_ref_temperature static double interface_get_emissivity (const struct sdis_interface_fragment* frag, + const unsigned source_id, struct sdis_data* data) { const struct intface* interface_props = sdis_data_cget(data); - (void)frag; + (void)frag, (void)source_id; return interface_props->emissivity; } static double interface_get_alpha (const struct sdis_interface_fragment* frag, + const unsigned source_id, struct sdis_data* data) { const struct intface* interface_props = sdis_data_cget(data); - (void)frag; + (void)frag, (void)source_id; return interface_props->alpha; } @@ -110,12 +112,13 @@ interface_get_tcr static double emissivity_1 (const struct stardis_interface_fragment* frag, + const unsigned src_id, void* data) { - (void)frag, (void)data; + (void)frag, (void)src_id, (void)data; return 1; } - + static double intface_prog_get_temp (const struct sdis_interface_fragment* frag, @@ -167,33 +170,39 @@ intface_prog_get_hc static double intface_prog_get_emissivity (const struct sdis_interface_fragment* frag, + const unsigned source_id, struct sdis_data* data) { const struct intface* interface_props = sdis_data_cget(data); struct stardis_interface_fragment f; + (void)source_id; d3_set(f.P, frag->P); d3_set(f.Ng, frag->Ng); d3_set(f.uv, frag->uv); f.time = frag->time; ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; - return interface_props->get_emissivity(&f, interface_props->prog_data); + return interface_props->get_emissivity + (&f, source_id, interface_props->prog_data); } static double intface_prog_get_alpha (const struct sdis_interface_fragment* frag, + const unsigned source_id, struct sdis_data* data) { const struct intface* interface_props = sdis_data_cget(data); struct stardis_interface_fragment f; + (void)source_id; d3_set(f.P, frag->P); d3_set(f.Ng, frag->Ng); d3_set(f.uv, frag->uv); f.time = frag->time; ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK); f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK; - return interface_props->get_alpha(&f, interface_props->prog_data); + return interface_props->get_alpha + (&f, source_id, interface_props->prog_data); } static double @@ -283,7 +292,7 @@ create_intface ERR(sdis_data_create(stardis->dev, sizeof(struct intface), ALIGNOF(struct intface), NULL, &data)); interface_props = sdis_data_get(data); - interface_props->imposed_temperature = -1; + interface_props->imposed_temperature = SDIS_TEMPERATURE_NONE; interface_props->imposed_flux = SDIS_FLUX_NONE; interface_props->front_medium_id = UINT_MAX; interface_props->back_medium_id = UINT_MAX; @@ -366,7 +375,7 @@ create_intface goto error; } for_fluid = 1; - ASSERT(intface->d.h_boundary->imposed_temperature >= 0); + ASSERT(SDIS_TEMPERATURE_IS_KNOWN(intface->d.h_boundary->imposed_temperature)); interface_props->imposed_temperature = intface->d.h_boundary->imposed_temperature; ASSERT(fluid_side_shader); @@ -544,7 +553,7 @@ create_intface * a possible external fluid to 'see' the imposed T */ fluid_side_shader->emissivity = interface_get_emissivity; interface_props->emissivity = 1; - ASSERT(intface->d.t_boundary->imposed_temperature >= 0); + ASSERT(SDIS_TEMPERATURE_IS_KNOWN(intface->d.t_boundary->imposed_temperature)); interface_props->imposed_temperature = intface->d.t_boundary->imposed_temperature; break; @@ -632,9 +641,9 @@ create_intface } ASSERT(fluid_side_shader); fluid_side_shader->reference_temperature = interface_get_ref_temperature; + fluid_side_shader->specular_fraction = interface_get_alpha; if(intface->d.sf_connect->emissivity > 0) { fluid_side_shader->emissivity = interface_get_emissivity; - fluid_side_shader->specular_fraction = interface_get_alpha; } break; case DESC_SOLID_FLUID_CONNECT_PROG: diff --git a/src/stardis-intface.h b/src/stardis-intface.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -28,13 +28,16 @@ struct stardis_interface_fragment; ******************************************************************************/ struct intface { /* programmed interfaces */ - double (*get_temp)(const struct stardis_interface_fragment*, void*); - double (*get_flux)(const struct stardis_interface_fragment*, void*); - double (*get_hc)(const struct stardis_interface_fragment*, void*); - double (*get_emissivity)(const struct stardis_interface_fragment*, void*); - double (*get_alpha)(const struct stardis_interface_fragment*, void*); - double (*get_ref_temp)(const struct stardis_interface_fragment*, void*); - double (*get_tcr)(const struct stardis_interface_fragment*, void*); + double (*get_temp)(const struct stardis_interface_fragment*, void*); + double (*get_flux)(const struct stardis_interface_fragment*, void*); + double (*get_hc)(const struct stardis_interface_fragment*, void*); + double (*get_ref_temp)(const struct stardis_interface_fragment*, void*); + double (*get_tcr)(const struct stardis_interface_fragment*, void*); + double (*get_emissivity) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); + double (*get_alpha) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); + void* prog_data; /* fluid - solid */ double hc; diff --git a/src/stardis-main.c b/src/stardis-main.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -24,6 +24,7 @@ #include <rsys/logger.h> #include <rsys/clock_time.h> +#include <rsys/str.h> #include <stdlib.h> #include <stdio.h> @@ -32,21 +33,26 @@ #endif int -main - (int argc, - char** argv) +main(int argc, char** argv) { struct args* args = NULL; struct stardis stardis; - int logger_initialized = 0, allocator_initialized = 0, - args_initialized = 0, stardis_initialized = 0; int err = EXIT_SUCCESS; struct mem_allocator allocator; struct logger logger; int mode = 0; struct time start; + FILE* f = NULL; + struct str name; res_T res = RES_OK; + /* Initialisation statuses */ + int logger_initialized = 0; + int allocator_initialized = 0; + int args_initialized = 0; + int stardis_initialized = 0; + int name_initialized = 0; + time_current(&start); #ifdef STARDIS_ENABLE_MPI @@ -58,6 +64,8 @@ main ERR(logger_init(&allocator, &logger)); logger_initialized = 1; + str_init(&allocator, &name); + name_initialized = 1; /* Active loggin for args parsing */ logger_set_stream(&logger, LOG_ERROR, log_err_fn, NULL); logger_set_stream(&logger, LOG_WARNING, log_warn_fn, NULL); @@ -69,7 +77,7 @@ main mode = (int)args->mode; if(mode & MODE_DUMP_HELP) { - short_help(stdout, argv[0]); + usage(stdout); goto exit; } else if(mode & MODE_DUMP_VERSION) { @@ -90,17 +98,28 @@ main release_args(args); args_initialized = 0; - if(mode & MODE_DUMP_VTK) { + if(mode & MODE_DUMP_MODEL) { + ERR(str_copy(&name, &stardis.dump_model_filename)); + ERR(str_append(&name, ".vtk")); + f = fopen(str_cget(&name), "w"); + if(!f) { + logger_print(stardis.logger, LOG_ERROR, + "cannot open file '%s' for writing.\n", str_cget(&name)); + res = RES_IO_ERR; + goto error; + } + /* Dump all the app-independent information */ - ERR(sg3d_geometry_dump_as_vtk(stardis.geometry.sg3d, stdout)); + ERR(sg3d_geometry_dump_as_vtk(stardis.geometry.sg3d, f)); /* Dump boundaries * Should we dump connections too? */ - ERR(dump_boundaries_at_the_end_of_vtk(&stardis, stdout)); + ERR(dump_boundaries_at_the_end_of_vtk(&stardis, f)); /* Dump the compute region if any */ if(mode & REGION_COMPUTE_MODES) { - ERR(dump_compute_region_at_the_end_of_vtk(&stardis, stdout)); + ERR(dump_compute_region_at_the_end_of_vtk(&stardis, f)); } - ERR(dump_enclosure_related_stuff_at_the_end_of_vtk(&stardis, stdout)); + ERR(dump_enclosure_related_stuff_at_the_end_of_vtk(&stardis, f)); + fclose(f); f = NULL; /* If dump, exit after dump done */ goto exit; @@ -115,6 +134,8 @@ main ERR(stardis_compute(&stardis, &start)); exit: + if(name_initialized) str_release(&name); + if(f) fclose(f); if(args_initialized) release_args(args); if(stardis_initialized) stardis_release(&stardis); if(logger_initialized) logger_release(&logger); diff --git a/src/stardis-output.c b/src/stardis-output.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -274,7 +274,7 @@ dump_path stream = fopen(name, "w"); if(!stream) { logger_print(dump_ctx->stardis->logger, LOG_ERROR, - "cannot open file '%s'\n", name); + "cannot open file '%s' for writing.\n", name); res = RES_IO_ERR; goto error; } @@ -648,82 +648,82 @@ medium_get_t0 } static res_T -dump_sample_end - (struct sdis_green_path* path, - void* ctx) +dump_sample_end(struct sdis_green_path* path, void* ctx) { - res_T res = RES_OK; + /* Stardis */ + struct sdis_green_path_end end = SDIS_GREEN_PATH_END_NULL; + struct sdis_data* data = NULL; + enum sdis_medium_type type; + + /* Stream */ struct e_ctx* e_ctx = ctx; - enum sdis_green_path_end_type end_type; FILE* stream; + + /* Miscellaneous */ + const struct description* descs; + double* pos; double elapsed; size_t sz; unsigned trad_id; + unsigned id; + res_T res = RES_OK; CHK(path && ctx); stream = e_ctx->stream; ERR(sdis_green_path_get_elapsed_time(path, &elapsed)); - ERR(sdis_green_path_get_end_type(path, &end_type)); + ERR(sdis_green_path_get_end(path, &end)); + sz = darray_descriptions_size_get(e_ctx->desc); - if(sz > UINT_MAX) goto abort; + if(sz > UINT_MAX) { res = RES_BAD_ARG; goto error; } trad_id = (unsigned)sz; - if(end_type == SDIS_GREEN_PATH_END_RADIATIVE) { - /* End, End ID, X, Y, Z, Elapsed time */ - fprintf(stream, "TRAD, %u, 0, 0, 0, %g\n", trad_id, elapsed); - } else { - struct sdis_point pt = SDIS_POINT_NULL; - struct sdis_data* data = NULL; - enum sdis_medium_type type; - const struct description* descs; - double* pos; - unsigned id; - - ERR(sdis_green_path_get_limit_point(path, &pt)); - - descs = darray_descriptions_cdata_get(e_ctx->desc); - switch(pt.type) { - case SDIS_FRAGMENT: { - struct intface* d__; - data = sdis_interface_get_data(pt.data.itfrag.intface); - pos = pt.data.itfrag.fragment.P; - d__ = sdis_data_get(data); - id = d__->desc_id; - CHK(DESC_IS_T(descs+id) || DESC_IS_H(descs+id)); - break; - } - case SDIS_VERTEX: - type = sdis_medium_get_type(pt.data.mdmvert.medium); - data = sdis_medium_get_data(pt.data.mdmvert.medium); - pos = pt.data.mdmvert.vertex.P; - if(pt.data.mdmvert.vertex.P[0] == INF) { - /* Radiative output (Trad) */ - id = trad_id; - } - else if(type == SDIS_FLUID) { - struct fluid** pfluid = sdis_data_get(data); - id = (*pfluid)->desc_id; - } else { - struct solid** psolid = sdis_data_get(data); - ASSERT(type == SDIS_SOLID); - ASSERT(!(*psolid)->is_outside); /* FIXME: what if in external solid? */ - id = (*psolid)->desc_id; - } - break; - default: FATAL("Unreachable code.\n"); break; + + descs = darray_descriptions_cdata_get(e_ctx->desc); + switch(end.type) { + case SDIS_GREEN_PATH_END_AT_RADIATIVE_ENV: + /* End, End ID, X, Y, Z, Elapsed time */ + fprintf(stream, "TRAD, %u, 0, 0, 0, %g\n", trad_id, elapsed); + break; + case SDIS_GREEN_PATH_END_AT_INTERFACE: { + struct intface* d__; + data = sdis_interface_get_data(end.data.itfrag.intface); + pos = end.data.itfrag.fragment.P; + d__ = sdis_data_get(data); + id = d__->desc_id; + CHK(DESC_IS_T(descs+id) || DESC_IS_H(descs+id)); + /* End, End ID, X, Y, Z, Elapsed time */ + fprintf(stream, "%s, %u, %g, %g, %g, %g\n", + str_cget(get_description_name(descs + id)), id, SPLIT3(pos), elapsed); + break; } - /* End, End ID, X, Y, Z, Elapsed time */ - fprintf(stream, "%s, %u, %g, %g, %g, %g\n", - str_cget(get_description_name(descs + id)), id, SPLIT3(pos), elapsed); + case SDIS_GREEN_PATH_END_IN_VOLUME: + type = sdis_medium_get_type(end.data.mdmvert.medium); + data = sdis_medium_get_data(end.data.mdmvert.medium); + pos = end.data.mdmvert.vertex.P; + if(end.data.mdmvert.vertex.P[0] == INF) { + /* Radiative output (Trad) */ + id = trad_id; + } + else if(type == SDIS_FLUID) { + struct fluid** pfluid = sdis_data_get(data); + id = (*pfluid)->desc_id; + } else { + struct solid** psolid = sdis_data_get(data); + ASSERT(type == SDIS_SOLID); + ASSERT(!(*psolid)->is_outside); /* FIXME: what if in external solid? */ + id = (*psolid)->desc_id; + } + /* End, End ID, X, Y, Z, Elapsed time */ + fprintf(stream, "%s, %u, %g, %g, %g, %g\n", + str_cget(get_description_name(descs + id)), id, SPLIT3(pos), elapsed); + break; + default: FATAL("Unreachable code.\n"); break; } end: return res; error: goto end; -abort: - res = RES_BAD_ARG; - goto error; } static res_T @@ -731,75 +731,75 @@ dump_sample (struct sdis_green_path* path, void* ctx) { - res_T res = RES_OK; - struct htable_weigth_iterator it, end; - struct green_sample_header header; + /* Stardis variables */ + struct sdis_green_path_end path_end = SDIS_GREEN_PATH_END_NULL; + struct sdis_data* data = NULL; + enum sdis_medium_type type; + + /* Miscellaneous variables */ struct w_ctx* w_ctx = ctx; - enum sdis_green_path_end_type end_type; FILE* stream; + const struct description* descs; + struct htable_weigth_iterator it, end; + struct green_sample_header header; unsigned* ids = NULL; double* weights = NULL; + double t0; size_t sz, i; unsigned trad_id; + res_T res = RES_OK; + CHK(path && ctx); stream = w_ctx->stream; - ERR(sdis_green_path_get_end_type(path, &end_type)); + ERR(sdis_green_path_get_end(path, &path_end)); sz = darray_descriptions_size_get(w_ctx->desc); - if(sz > UINT_MAX) goto abort; + if(sz > UINT_MAX) { res = RES_BAD_ARG; goto error; } trad_id = (unsigned)sz; - if(end_type == SDIS_GREEN_PATH_END_RADIATIVE) { - header.at_initial = 0; - header.sample_end_description_id = trad_id; - } else { - struct sdis_point pt = SDIS_POINT_NULL; - struct sdis_data* data = NULL; - enum sdis_medium_type type; - const struct description* descs; - double t0; - - ERR(sdis_green_path_get_limit_point(path, &pt)); - - /* For each path, dump: - * # end_id #power_terms #flux_terms - * power_id_1 ... power_id_n flux_id_1 ... flux_id_n - * power_factor_1 ... power_factor_n flux_factor_1 ... flux_factor_n - */ - - descs = darray_descriptions_cdata_get(w_ctx->desc); - switch(pt.type) { - case SDIS_FRAGMENT: { - struct intface* d__; - unsigned desc_id; - data = sdis_interface_get_data(pt.data.itfrag.intface); - d__ = sdis_data_get(data); - desc_id = d__->desc_id; - CHK(DESC_IS_T(descs+desc_id) || DESC_IS_H(descs+desc_id)); - header.sample_end_description_id = desc_id; - header.at_initial = 0; - break; - } - case SDIS_VERTEX: - type = sdis_medium_get_type(pt.data.mdmvert.medium); - data = sdis_medium_get_data(pt.data.mdmvert.medium); - t0 = medium_get_t0(pt.data.mdmvert.medium); - header.at_initial = (pt.data.mdmvert.vertex.time <= t0); - if(pt.data.mdmvert.vertex.P[0] == INF) { - /* Radiative output (Trad) */ - header.sample_end_description_id = trad_id; - } - else if(type == SDIS_FLUID) { - struct fluid** pfluid = sdis_data_get(data); - header.sample_end_description_id = (*pfluid)->desc_id; - } else { - struct solid** psolid = sdis_data_get(data); - ASSERT(type == SDIS_SOLID); - ASSERT(!(*psolid)->is_outside); /* FIXME: what if in external solid? */ - header.sample_end_description_id = (*psolid)->desc_id; - } - break; - default: FATAL("Unreachable code.\n"); break; + + /* For each path, dump: + * # end_id #power_terms #flux_terms + * power_id_1 ... power_id_n flux_id_1 ... flux_id_n + * power_factor_1 ... power_factor_n flux_factor_1 ... flux_factor_n + */ + + descs = darray_descriptions_cdata_get(w_ctx->desc); + switch(path_end.type) { + case SDIS_GREEN_PATH_END_AT_RADIATIVE_ENV: + header.at_initial = 0; + header.sample_end_description_id = trad_id; + break; + case SDIS_GREEN_PATH_END_AT_INTERFACE: { + struct intface* d__; + unsigned desc_id; + data = sdis_interface_get_data(path_end.data.itfrag.intface); + d__ = sdis_data_get(data); + desc_id = d__->desc_id; + CHK(DESC_IS_T(descs+desc_id) || DESC_IS_H(descs+desc_id)); + header.sample_end_description_id = desc_id; + header.at_initial = 0; + break; } + case SDIS_GREEN_PATH_END_IN_VOLUME: + type = sdis_medium_get_type(path_end.data.mdmvert.medium); + data = sdis_medium_get_data(path_end.data.mdmvert.medium); + t0 = medium_get_t0(path_end.data.mdmvert.medium); + header.at_initial = (path_end.data.mdmvert.vertex.time <= t0); + if(path_end.data.mdmvert.vertex.P[0] == INF) { + /* Radiative output (Trad) */ + header.sample_end_description_id = trad_id; + } + else if(type == SDIS_FLUID) { + struct fluid** pfluid = sdis_data_get(data); + header.sample_end_description_id = (*pfluid)->desc_id; + } else { + struct solid** psolid = sdis_data_get(data); + ASSERT(type == SDIS_SOLID); + ASSERT(!(*psolid)->is_outside); /* FIXME: what if in external solid? */ + header.sample_end_description_id = (*psolid)->desc_id; + } + break; + default: FATAL("Unreachable code.\n"); break; } /* Merge power and flux terms */ @@ -808,10 +808,10 @@ dump_sample ERR(sdis_green_path_for_each_power_term(path, merge_power_terms, w_ctx)); ERR(sdis_green_path_for_each_flux_term(path, merge_flux_terms, w_ctx)); sz = htable_weigth_size_get(&w_ctx->pw); - if(sz > UINT_MAX) goto abort; + if(sz > UINT_MAX) { res = RES_BAD_ARG; goto error; } header.pw_count = (unsigned)sz; sz = htable_weigth_size_get(&w_ctx->flux); - if(sz > UINT_MAX) goto abort; + if(sz > UINT_MAX) { res = RES_BAD_ARG; goto error; } header.fx_count = (unsigned)sz; /* Write path's header */ @@ -863,9 +863,6 @@ end: return res; error: goto end; -abort: - res = RES_BAD_ARG; - goto error; } res_T @@ -874,15 +871,21 @@ dump_green_bin const struct stardis* stardis, FILE* stream) { - res_T res = RES_OK; - size_t sz, i; - struct w_ctx w_ctx; - int table_initialized = 0; /* The following type must be identical to its stardis-green counterpart! */ struct green_file_header header; + const struct radiative_env_const* radenv_const = NULL; + struct w_ctx w_ctx; + size_t sz, i; + int table_initialized = 0; + res_T res = RES_OK; ASSERT(green && stardis && stream); + /* Stardis can produce the green function on systems + * with constant properties only */ + ASSERT(stardis->radenv.type == RADIATIVE_ENV_CONST); + radenv_const = &stardis->radenv.data.cst; + /* Init header */ strcpy(header.green_string, BIN_FILE_IDENT_STRING); header.file_format_version = GREEN_FILE_FORMAT_VERSION; @@ -903,8 +906,9 @@ dump_green_bin + stardis->counts.fbound_count + stardis->counts.sfconnect_count + stardis->counts.ssconnect_count)); header.description_count = (unsigned)sz; - header.ambient_radiative_temperature = stardis->trad; - header.ambient_radiative_temperature_reference = stardis->trad_ref; + header.ambient_radiative_temperature = radenv_const->temperature; + header.ambient_radiative_temperature_reference = + radenv_const->reference_temperature; d2_set(header.time_range, stardis->time_range); /* Write header */ @@ -967,7 +971,7 @@ print_sample void* ctx) { res_T res = RES_OK; - struct sdis_point pt = SDIS_POINT_NULL; + struct sdis_green_path_end path_end = SDIS_GREEN_PATH_END_NULL; struct sdis_data* data = NULL; enum sdis_medium_type type; struct htable_weigth_iterator it, end; @@ -977,7 +981,7 @@ print_sample const struct description* descs; CHK(path && ctx); - ERR(sdis_green_path_get_limit_point(path, &pt)); + ERR(sdis_green_path_get_end(path, &path_end)); /* For each path, prints: * # end #power_terms #flux_terms power_term_1 ... power_term_n flux_term_1 ... flux_term_n @@ -988,10 +992,10 @@ print_sample */ descs = darray_descriptions_cdata_get(w_ctx->desc); - switch (pt.type) { - case SDIS_FRAGMENT: { + switch (path_end.type) { + case SDIS_GREEN_PATH_END_AT_INTERFACE: { struct intface* d__; - data = sdis_interface_get_data(pt.data.itfrag.intface); + data = sdis_interface_get_data(path_end.data.itfrag.intface); d__ = sdis_data_get(data); desc_id = d__->desc_id; switch (descs[desc_id].type) { @@ -1009,10 +1013,10 @@ print_sample } break; } - case SDIS_VERTEX: - type = sdis_medium_get_type(pt.data.mdmvert.medium); - data = sdis_medium_get_data(pt.data.mdmvert.medium); - if(pt.data.mdmvert.vertex.P[0] == INF) { + case SDIS_GREEN_PATH_END_IN_VOLUME: + type = sdis_medium_get_type(path_end.data.mdmvert.medium); + data = sdis_medium_get_data(path_end.data.mdmvert.medium); + if(path_end.data.mdmvert.vertex.P[0] == INF) { /* Radiative output (Trad)*/ size_t sz = darray_descriptions_size_get(w_ctx->desc); if(sz > UINT_MAX) goto abort; @@ -1085,6 +1089,7 @@ dump_green_ascii FILE* stream) { res_T res = RES_OK; + const struct radiative_env_const* radenv_const = NULL; unsigned ok_count, failed_count; size_t sz; struct w_ctx w_ctx; @@ -1094,6 +1099,11 @@ dump_green_ascii ASSERT(green && stardis && stream); + /* Stardis can produce the green function on systems + * with constant properties only */ + ASSERT(stardis->radenv.type == RADIATIVE_ENV_CONST); + radenv_const = &stardis->radenv.data.cst; + ERR(sdis_green_function_get_paths_count(green, &sz)); if(sz > UINT_MAX) goto abort; ok_count = (unsigned)sz; @@ -1128,12 +1138,12 @@ dump_green_ascii sl = desc->d.solid; fprintf(stream, "%u\t%s\t%g\t%g\t%g\t%g", i, str_cget(&sl->name), sl->lambda, sl->rho, sl->cp, sl->vpower); - if(sl->tinit >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(sl->tinit)) { fprintf(stream, "\t%g", sl->tinit); } else { fprintf(stream, "\tNONE"); } - if(sl->imposed_temperature >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(sl->imposed_temperature)) { fprintf(stream, "\t%g\n", sl->imposed_temperature); } else { fprintf(stream, "\tNONE\n"); @@ -1148,19 +1158,19 @@ dump_green_ascii const struct fluid* fl; if(desc->type != DESC_MAT_FLUID) continue; fl = desc->d.fluid; - if(fl->imposed_temperature >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(fl->imposed_temperature)) { fprintf(stream, "%u\t%s\t%g\t%g", i, str_cget(&fl->name), fl->rho, fl->cp); } else { fprintf(stream, "%u\t%s\t%g\t%g", i, str_cget(&fl->name), fl->rho, fl->cp); } - if(fl->tinit >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(fl->tinit)) { fprintf(stream, "\t%g", fl->tinit); } else { fprintf(stream, "\tNONE"); } - if(fl->imposed_temperature >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(fl->imposed_temperature)) { fprintf(stream, "\t%g\n", fl->imposed_temperature); } else { fprintf(stream, "\tNONE\n"); @@ -1211,7 +1221,7 @@ dump_green_ascii fprintf(stream, "# Radiative Temperatures\n"); fprintf(stream, "# ID Trad Trad_Ref\n"); fprintf(stream, "%u\t%g\t%g\n", - szd, stardis->trad, stardis->trad_ref); + szd, radenv_const->temperature, radenv_const->reference_temperature); fprintf(stream, "# Samples\n"); fprintf(stream, @@ -1285,9 +1295,11 @@ dump_enclosure_related_stuff_at_the_end_of_vtk unsigned tsz, e, s, t, scount, ecount, ocount; int* enc_status = NULL; const struct description* descriptions; - int invalid_enclosures_count = 0; + int undef_count = 0, multi_count = 0; + struct str msg; ASSERT(stardis && stream); + str_init(stardis->allocator, &msg); descriptions = darray_descriptions_cdata_get(&stardis->descriptions); ERR(sg3d_geometry_get_unique_triangles_count(stardis->geometry.sg3d, &tsz)); trgs = MEM_CALLOC(stardis->allocator, tsz, sizeof(*trgs)); @@ -1376,6 +1388,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk if(properties_conflict_status == NO_PROPERTY_CONFLICT) med = stardis->undefined_medium_behind_boundary_id; else { + if(!(enc_status[e] & ENCLOSURE_WITH_UNDEF_MEDIUM)) undef_count++; enc_status[e] |= ENCLOSURE_WITH_UNDEF_MEDIUM; continue; /* Don't flag N_MEDIA at the same time */ } @@ -1384,18 +1397,37 @@ dump_enclosure_related_stuff_at_the_end_of_vtk is_fst_med = 0; enc_fst_med = med; } else { - if(enc_fst_med != med) + if(enc_fst_med != med) { + /* The external (infinite) enclosure can have multiple media */ + if(!header.is_infinite && !(enc_status[e] & ENCLOSURE_WITH_N_MEDIA)) + multi_count++; enc_status[e] |= ENCLOSURE_WITH_N_MEDIA; + } } } - /* The external (infinite) enclosure is always valid */ - if(enc_status[e] != NO_ENCLOSURE_ERROR && !header.is_infinite) - invalid_enclosures_count++; ERR(senc3d_enclosure_ref_put(enc)); } - if(invalid_enclosures_count) { - logger_print(stardis->logger, LOG_WARNING, - "Found %d invalid enclosure(s).\n", invalid_enclosures_count); + if(multi_count) { + int fst = 1; + str_printf(&msg, + "Found %d enclosure(s) with more than 1 medium:", multi_count); + FOR_EACH(e, 0, ecount) { + if(!(enc_status[e] & ENCLOSURE_WITH_N_MEDIA)) continue; + str_append_printf(&msg, (fst ? " %u" : ", %u"), e); + fst = 0; + } + logger_print(stardis->logger, LOG_OUTPUT, "%s.\n", str_cget(&msg)); + } + if(undef_count) { + int fst = 1; + str_printf(&msg, + "Found %d enclosure(s) with undefined medium:", undef_count); + FOR_EACH(e, 0, ecount) { + if(!(enc_status[e] & ENCLOSURE_WITH_UNDEF_MEDIUM)) continue; + str_append_printf(&msg, (fst ? " %u" : ", %u"), e); + fst = 0; + } + logger_print(stardis->logger, LOG_OUTPUT, "%s.\n", str_cget(&msg)); } fprintf(stream, "FIELD EnclosuresData 2\n"); fprintf(stream, "Enclosures %d %d unsigned_char\n", ecount, tsz); @@ -1519,6 +1551,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk #undef ENC_MEMBER_NO_MEDIUM exit: + str_release(&msg); MEM_RM(stardis->allocator, trgs); MEM_RM(stardis->allocator, enc_status); return res; @@ -1528,15 +1561,13 @@ error: res_T print_computation_time - (struct sdis_estimator* estimator, + (struct sdis_mc* time_per_realisation, struct stardis* stardis, struct time* start, struct time* compute_start, struct time* compute_end, struct time* output_end) { - res_T res = RES_OK; - struct sdis_mc time; struct time tmp; char buf[128]; const int flag = TIME_MSEC | TIME_SEC | TIME_MIN | TIME_HOUR | TIME_DAY; @@ -1561,16 +1592,13 @@ print_computation_time "Result output time = %s\n", buf); } - if(estimator) { - ERR(sdis_estimator_get_realisation_time(estimator, &time)); + if(time_per_realisation) { logger_print(stardis->logger, LOG_OUTPUT, - "Time per realisation (in usec) = %g +/- %g\n", time.E, time.SE); + "Time per realisation (in usec) = %g +/- %g\n", + time_per_realisation->E, time_per_realisation->SE); } -exit: - return res; -error: - goto exit; + return RES_OK; } res_T @@ -1621,24 +1649,13 @@ print_single_MC_result else fprintf(stream, "%g %g %lu %lu\n", result.E, result.SE, nfailures, nsamples); break; - case MODE_PROBE_COMPUTE_ON_INTERFACE: - if(stardis->mode & MODE_EXTENDED_RESULTS) { - if(stardis->time_range[0] == stardis->time_range[1]) - fprintf(stream, - "Boundary temperature at [%g, %g, %g] at t=%g = %g K +/- %g\n", - SPLIT3(stardis->probe), stardis->time_range[0], - result.E, /* Expected value */ - result.SE); /* Standard error */ - else - fprintf(stream, - "Boundary temperature at [%g, %g, %g] with t in [%g %g] = %g K +/- %g\n", - SPLIT3(stardis->probe), SPLIT2(stardis->time_range), - result.E, /* Expected value */ - result.SE); /* Standard error */ + case MODE_PROBE_COMPUTE_ON_INTERFACE: { + const struct stardis_probe_boundary* probe = NULL; + probe = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list); + ERR(print_single_MC_result_probe_boundary + (stardis, probe, estimator, stream)); + break; } - else fprintf(stream, "%g %g %lu %lu\n", - result.E, result.SE, nfailures, nsamples); - break; case MODE_MEDIUM_COMPUTE: if(stardis->mode & MODE_EXTENDED_RESULTS) { if(stardis->time_range[0] == stardis->time_range[1]) @@ -1778,6 +1795,61 @@ abort: } res_T +print_single_MC_result_probe_boundary + (struct stardis* stardis, + const struct stardis_probe_boundary* probe, + const struct sdis_estimator* estimator, + FILE* stream) +{ + struct sdis_mc result = SDIS_MC_NULL; + size_t nfailures = 0; + size_t nsamples = 0; + res_T res = RES_OK; + + ASSERT(stardis && probe && estimator); + ASSERT((stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE) + || (stardis->mode & MODE_PROBE_LIST_COMPUTE_ON_INTERFACE)); + + /* Only master prints or reads estimators */ + ASSERT(!stardis->mpi_initialized || stardis->mpi_rank == 0); + + /* Fetch the estimation data */ + ERR(sdis_estimator_get_temperature(estimator, &result)); + ERR(sdis_estimator_get_failure_count(estimator, &nfailures)); + nsamples = stardis->samples; + + if(nfailures == nsamples) { + logger_print(stardis->logger, LOG_ERROR, + "All the %lu samples failed. No result to display.\n", nsamples); + res = RES_BAD_OP; + goto error; + } + + /* Raw output */ + if((stardis->mode & MODE_EXTENDED_RESULTS) == 0) { + fprintf(stream, "%g %g %lu %lu\n", + result.E, result.SE, (unsigned long)nfailures, (unsigned long)nsamples); + + /* Extended output */ + } else if(stardis->time_range[0] == stardis->time_range[1]) { + fprintf(stream, + "Boundary temperature at [%g, %g, %g] at t=%g = %g K +/- %g\n", + SPLIT3(probe->position), probe->time[0], result.E, result.SE); + + /* Extended output with time range */ + } else { + fprintf(stream, + "Boundary temperature at [%g, %g, %g] with t in [%g %g] = %g K +/- %g\n", + SPLIT3(probe->position), SPLIT2(probe->time), result.E, result.SE); + } + +exit: + return res; +error: + goto exit; +} + +res_T dump_map (const struct stardis* stardis, const struct darray_estimators* estimators, @@ -1933,7 +2005,8 @@ dump_compute_region_at_the_end_of_vtk const struct description* descriptions; unsigned medium_id; ASSERT(stardis->mode & MODE_MEDIUM_COMPUTE); - medium = find_medium_by_name(stardis, &stardis->solve_name, &medium_id); + medium = find_medium_by_name + (stardis, str_cget(&stardis->solve_name), &medium_id); ASSERT(medium != NULL); (void)medium; descriptions = darray_descriptions_cdata_get(&stardis->descriptions); FOR_EACH(i, 0, tsz) { diff --git a/src/stardis-output.h b/src/stardis-output.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -23,11 +23,13 @@ struct sdis_green_path; struct sdis_heat_path; struct sdis_estimator_buffer; struct sdis_green_function; +struct sdis_mc; struct counts; struct description; struct mem_allocator; struct sdis_estimator; struct stardis; +struct stardis_probe_boundary; struct geometry; struct vertex; struct darray_estimators; @@ -38,72 +40,82 @@ struct dump_path_context { unsigned long rank; struct stardis* stardis; }; +#define DUMP_PATH_CONTEXT_NULL__ {0,NULL} +static const struct dump_path_context DUMP_PATH_CONTEXT_NULL = + DUMP_PATH_CONTEXT_NULL__; -res_T +extern LOCAL_SYM res_T dump_path (const struct sdis_heat_path* path, void* context); -res_T +extern LOCAL_SYM res_T print_sample (struct sdis_green_path* path, void* ctx); -res_T +extern LOCAL_SYM res_T dump_vtk_image (const struct sdis_estimator_buffer* buf, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_ht_image (const struct sdis_estimator_buffer* buf, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_green_ascii (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_green_bin (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_paths_end (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_enclosure_related_stuff_at_the_end_of_vtk (struct stardis* stardis, FILE* stream); -res_T +extern LOCAL_SYM res_T print_computation_time - (struct sdis_estimator* estimator, /* Can be NULL */ + (struct sdis_mc* time_per_realisation, /* Can be NULL */ struct stardis* stardis, - struct time* start, - struct time* computation_start, - struct time* computation_end, - struct time* output_end); /* Can be NULL */ + struct time* start, + struct time* computation_start, + struct time* computation_end, + struct time* output_end); /* Can be NULL */ -res_T +extern LOCAL_SYM res_T print_single_MC_result (struct sdis_estimator* estimator, struct stardis* stardis, FILE* stream); -res_T +extern LOCAL_SYM res_T +print_single_MC_result_probe_boundary + (struct stardis* stardis, + const struct stardis_probe_boundary* probe, + const struct sdis_estimator* estimator, + FILE* stream); + +extern LOCAL_SYM res_T dump_map (const struct stardis* stardis, const struct darray_estimators* estimators, FILE* stream); -res_T +extern LOCAL_SYM res_T dump_boundaries_at_the_end_of_vtk (const struct stardis* stardis, FILE* stream); diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -45,10 +45,10 @@ #include <rsys/text_reader.h> #include <rsys/library.h> +#include <star/sg3d.h> #include <wordexp.h> #include <stdlib.h> #include <stdio.h> -#include <ctype.h> #include <string.h> #ifdef COMPILER_GCC #include <strings.h> /* strcasecmp */ @@ -102,12 +102,14 @@ read_sides_and_files unsigned current_merge_errors; struct sg3d_geometry_add_callbacks callbacks = SG3D_ADD_CALLBACKS_NULL__; struct darray_uint degenerated; - struct str str; + struct str str, name; + FILE* f = NULL; res_T res = RES_OK; ASSERT(stardis && pwordexp && idx); darray_uint_init(stardis->allocator, &degenerated); + str_init(stardis->allocator, &name); str_init(stardis->allocator, &str); callbacks.get_indices = add_geom_ctx_indices; callbacks.get_properties = add_geom_ctx_properties; @@ -217,7 +219,21 @@ read_sides_and_files stardis->geometry.sg3d, &merge_errors)); if(current_merge_errors != merge_errors) { int is_for_compute = - (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_VTK); + (stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_MODEL); + if(!str_is_empty(&stardis->dump_model_filename)) { + ERR(str_copy(&name, &stardis->dump_model_filename)); + ERR(str_append(&name, "_merge_conflits.obj")); + f = fopen(str_cget(&name), "w"); + if(!f) { + logger_print(stardis->logger, LOG_ERROR, + "cannot open file '%s' for writing.\n", str_cget(&name)); + res = RES_IO_ERR; + goto error; + } + ERR(sg3d_geometry_dump_as_obj(stardis->geometry.sg3d, f, + SG3D_OBJ_DUMP_MERGE_CONFLICTS)); + fclose(f); f = NULL; + } logger_print(stardis->logger, (is_for_compute ? LOG_ERROR : LOG_WARNING), "Merge conflicts found reading file '%s' (%u triangles).\n", arg, merge_errors - current_merge_errors); @@ -230,6 +246,8 @@ read_sides_and_files } end: + if(f) fclose(f); + str_release(&name); darray_uint_release(&degenerated); str_release(&str); if(sstl) SSTL(ref_put(sstl)); @@ -285,8 +303,8 @@ description_set_name "H_BOUNDARY_FOR_SOLID", "H_BOUNDARY_FOR_SOLID_PROG", "PROGRAM", "PROG_PARAMS", "SCALE", "SOLID", "SOLID_PROG", "SOLID_FLUID_CONNECTION", "SOLID_FLUID_CONNECTION_PROG", "SOLID_SOLID_CONNECTION", - "SOLID_SOLID_CONNECTION_PROG", "TRAD", "T_BOUNDARY_FOR_SOLID", - "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" }; + "SOLID_SOLID_CONNECTION_PROG", "SPHERICAL_SOURCE", "SPHERICAL_SOURCE_PROG", + "TRAD", "T_BOUNDARY_FOR_SOLID", "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" }; const char* reason = NULL; size_t i; ASSERT(name && arg); @@ -382,9 +400,7 @@ process_h CHK_ARG(idx, "ref_temperature"); res = cstr_to_double(arg, &h_boundary->ref_temperature); - if(res != RES_OK - || h_boundary->ref_temperature < 0) - { + if(res != RES_OK || h_boundary->ref_temperature < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -395,9 +411,8 @@ process_h CHK_ARG(idx, "emissivity"); res = cstr_to_double(arg, &h_boundary->emissivity); if(res != RES_OK - || h_boundary->emissivity < 0 - || h_boundary->emissivity > 1) - { + || h_boundary->emissivity < 0 + || h_boundary->emissivity > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -405,9 +420,8 @@ process_h CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &h_boundary->specular_fraction); if(res != RES_OK - || h_boundary->specular_fraction < 0 - || h_boundary->specular_fraction > 1) - { + || h_boundary->specular_fraction < 0 + || h_boundary->specular_fraction > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -415,9 +429,7 @@ process_h } CHK_ARG(idx, "Convection coefficient"); res = cstr_to_double(arg, &h_boundary->hc); - if(res != RES_OK - || h_boundary->hc < 0) - { + if(res != RES_OK || h_boundary->hc < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid Convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -426,8 +438,7 @@ process_h CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &h_boundary->imposed_temperature); if(res != RES_OK - || h_boundary->imposed_temperature < 0) - { + || SDIS_TEMPERATURE_IS_UNKNOWN(h_boundary->imposed_temperature)) { logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -447,6 +458,7 @@ process_h ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; fluid->imposed_temperature = h_boundary->imposed_temperature; + fluid->t0 = stardis->initial_time; fluid->is_outside = 1; fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); ERR(create_solver_fluid(stardis, fluid)); @@ -503,9 +515,7 @@ process_hf CHK_ARG(idx, "ref_temperature"); res = cstr_to_double(arg, &hf_boundary->ref_temperature); - if(res != RES_OK - || hf_boundary->ref_temperature < 0) - { + if(res != RES_OK || hf_boundary->ref_temperature < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -516,9 +526,8 @@ process_hf CHK_ARG(idx, "emissivity"); res = cstr_to_double(arg, &hf_boundary->emissivity); if(res != RES_OK - || hf_boundary->emissivity < 0 - || hf_boundary->emissivity > 1) - { + || hf_boundary->emissivity < 0 + || hf_boundary->emissivity > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -526,9 +535,8 @@ process_hf CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &hf_boundary->specular_fraction); if(res != RES_OK - || hf_boundary->specular_fraction < 0 - || hf_boundary->specular_fraction > 1) - { + || hf_boundary->specular_fraction < 0 + || hf_boundary->specular_fraction > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -536,9 +544,7 @@ process_hf } CHK_ARG(idx, "convection coefficient"); res = cstr_to_double(arg, &hf_boundary->hc); - if(res != RES_OK - || hf_boundary->hc < 0) - { + if(res != RES_OK || hf_boundary->hc < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -547,8 +553,7 @@ process_hf CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &hf_boundary->imposed_temperature); if(res != RES_OK - || hf_boundary->imposed_temperature < 0) - { + || SDIS_TEMPERATURE_IS_UNKNOWN(hf_boundary->imposed_temperature)) { logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -574,6 +579,7 @@ process_hf ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; fluid->imposed_temperature = hf_boundary->imposed_temperature; + fluid->t0 = stardis->initial_time; fluid->is_outside = 1; fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); ERR(create_solver_fluid(stardis, fluid)); @@ -610,6 +616,18 @@ set_argc_argv goto error; } *argc = pwordexp->we_wordc - idx; + /* Review: why allocate an extra argument? In fact, it's necessary because + * this function is called even if there are no arguments to analyze. In this + * case, allocation would fail, as the size to be allocated would be zero. + * This +1 therefore guarantees that at least one element will be allocated. + * But this could be eliminated by checking that there are no arguments + * (argc==0) and, if necessary, returning before any allocation. + * + * Nevertheless, this extra argument makes sense. It should be the first + * argument and contain the program name. In this way, the argument list would + * respect the C convention for declaring an argument list. And so, anyone + * could use the getopt analysis function without having to declare a dummy + * argument as the program's first parameter */ *argv = MEM_CALLOC(allocator, 1 + *argc, sizeof(char *)); if(*argv == NULL) { res = RES_MEM_ERR; @@ -729,7 +747,7 @@ process_program ERR(init_program(stardis->allocator, &desc->d.program)); program = desc->d.program; desc->type = DESC_PROGRAM; - + CHK_ARG(idx, "program name"); ERR(description_set_name(stardis, &program->name, arg)); if(find_description_by_name(stardis, &program->name, desc)) { @@ -839,6 +857,7 @@ process_h_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double h_bound_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct h_boundary_prog* h_boundary_prog; struct stardis_description_create_context ctx; @@ -855,7 +874,7 @@ process_h_prog ERR(init_h_boundary_prog(stardis->allocator, &desc->d.h_boundary_prog)); h_boundary_prog = desc->d.h_boundary_prog; desc->type = type; - + CHK_ARG(idx, "programmed h boundary name"); ERR(description_set_name(stardis, &h_boundary_prog->name, arg)); if(find_description_by_name(stardis, &h_boundary_prog->name, desc)) { @@ -894,7 +913,9 @@ process_h_prog ctx.name = desc_name; CREATE_DESC_DATA(h_boundary_prog); - h_boundary_prog->t_range(h_boundary_prog->prog_data, stardis->t_range); + h_boundary_prog->t_range(h_boundary_prog->prog_data, h_bound_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], h_bound_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], h_bound_t_range[1]); /* create the media behind the interface */ if(type == DESC_BOUND_H_FOR_FLUID_PROG) { @@ -933,6 +954,7 @@ process_hf_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double hf_bound_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct hf_boundary_prog* hf_boundary_prog; struct stardis_description_create_context ctx; @@ -951,7 +973,7 @@ process_hf_prog ERR(init_hf_boundary_prog(stardis->allocator, &desc->d.hf_boundary_prog)); hf_boundary_prog = desc->d.hf_boundary_prog; desc->type = type; - + CHK_ARG(idx, "programmed hf boundary name"); ERR(description_set_name(stardis, &hf_boundary_prog->name, arg)); if(find_description_by_name(stardis, &hf_boundary_prog->name, desc)) { @@ -987,7 +1009,9 @@ process_hf_prog ctx.name = desc_name; CREATE_DESC_DATA(hf_boundary_prog); - hf_boundary_prog->t_range(hf_boundary_prog->prog_data, stardis->t_range); + hf_boundary_prog->t_range(hf_boundary_prog->prog_data, hf_bound_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], hf_bound_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], hf_bound_t_range[1]); /* create the media behind the interface */ ERR(init_fluid_prog(stardis->allocator, &fluid_prog)); @@ -1036,7 +1060,7 @@ process_t ERR(get_dummy_fluid_id(stardis, &t_boundary->mat_id)); - + CHK_ARG(idx, "temperature boundary name"); ERR(description_set_name(stardis, &t_boundary->name, arg)); if(find_description_by_name(stardis, &t_boundary->name, desc)) { @@ -1049,7 +1073,7 @@ process_t CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &t_boundary->imposed_temperature); if(res != RES_OK - || t_boundary->imposed_temperature < 0) + || SDIS_TEMPERATURE_IS_UNKNOWN(t_boundary->imposed_temperature)) { logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -1076,6 +1100,7 @@ process_t_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double t_bound_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct t_boundary_prog* t_boundary_prog; struct stardis_description_create_context ctx; @@ -1094,7 +1119,7 @@ process_t_prog desc->type = DESC_BOUND_T_FOR_SOLID_PROG; ERR(get_dummy_fluid_id(stardis, &t_boundary_prog->mat_id)); - + CHK_ARG(idx, "programmed t boundary name"); ERR(description_set_name(stardis, &t_boundary_prog->name, arg)); if(find_description_by_name(stardis, &t_boundary_prog->name, desc)) { @@ -1124,7 +1149,9 @@ process_t_prog ctx.name = desc_name; CREATE_DESC_DATA(t_boundary_prog); - t_boundary_prog->t_range(t_boundary_prog->prog_data, stardis->t_range); + t_boundary_prog->t_range(t_boundary_prog->prog_data, t_bound_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], t_bound_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], t_bound_t_range[1]); end: return res; @@ -1170,7 +1197,7 @@ process_flx CHK_ARG(idx, "flux"); res = cstr_to_double(arg, &f_boundary->imposed_flux); if(res != RES_OK - || f_boundary->imposed_flux == SDIS_FLUX_NONE) { + || f_boundary->imposed_flux == SDIS_FLUX_NONE) { /* Flux can be < 0 but not undefined */ if(res == RES_OK) res = RES_BAD_ARG; logger_print(stardis->logger, LOG_ERROR, "Invalid flux: %s\n", arg); @@ -1221,7 +1248,7 @@ process_flx_prog desc->type = DESC_BOUND_F_FOR_SOLID_PROG; ERR(get_dummy_fluid_id(stardis, &f_boundary_prog->mat_id)); - + CHK_ARG(idx, "programmed t boundary name"); ERR(description_set_name(stardis, &f_boundary_prog->name, arg)); if(find_description_by_name(stardis, &f_boundary_prog->name, desc)) { @@ -1297,9 +1324,7 @@ process_sfc CHK_ARG(idx, "ref_temperature"); res = cstr_to_double(arg, &sf_connect->ref_temperature); - if(res != RES_OK - || sf_connect->ref_temperature < 0) - { + if(res != RES_OK || sf_connect->ref_temperature < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -1310,9 +1335,8 @@ process_sfc CHK_ARG(idx, "emissivity"); res = cstr_to_double(arg, &sf_connect->emissivity); if(res != RES_OK - || sf_connect->emissivity < 0 - || sf_connect->emissivity > 1) - { + || sf_connect->emissivity < 0 + || sf_connect->emissivity > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -1320,9 +1344,8 @@ process_sfc CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &sf_connect->specular_fraction); if(res != RES_OK - || sf_connect->specular_fraction < 0 - || sf_connect->specular_fraction > 1) - { + || sf_connect->specular_fraction < 0 + || sf_connect->specular_fraction > 1) { logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -1330,9 +1353,7 @@ process_sfc } CHK_ARG(idx, "convection coefficient"); res = cstr_to_double(arg, &sf_connect->hc); - if(res != RES_OK - || sf_connect->hc < 0) - { + if(res != RES_OK || sf_connect->hc < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -1357,6 +1378,7 @@ process_sfc_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double sf_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct solid_fluid_connect_prog* sf_connect_prog; struct stardis_description_create_context ctx; @@ -1407,7 +1429,9 @@ process_sfc_prog ctx.name = desc_name; CREATE_DESC_DATA(sf_connect_prog); - sf_connect_prog->t_range(sf_connect_prog->prog_data, stardis->t_range); + sf_connect_prog->t_range(sf_connect_prog->prog_data, sf_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], sf_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], sf_t_range[1]); end: return res; @@ -1455,9 +1479,7 @@ process_ssc CHK_ARG(idx, "contact resistance"); res = cstr_to_double(arg, &ss_connect->tcr); - if(res != RES_OK - || ss_connect->tcr < 0) - { + if(res != RES_OK || ss_connect->tcr < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid contact resistance: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; @@ -1560,21 +1582,12 @@ read_imposed_temperature str_init(stardis->allocator, &keep); CHK_ARG((*idx), "imposed temperature"); ERR(str_set(&keep, arg)); - if(RES_OK == cstr_to_double(arg, imposed_temperature)) { - /* Was a number */ - if(*imposed_temperature < 0) { - res = RES_BAD_ARG; - goto error; - } - } else { - /* Could be 'unknown' */ - if(0 == strcasecmp(arg, "UNKNOWN")) { - *imposed_temperature = UNKNOWN_MEDIUM_TEMPERATURE; - } else { - res = RES_BAD_ARG; - goto error; - } + if(0 == strcasecmp(arg, "UNKNOWN")) { + *imposed_temperature = UNKNOWN_MEDIUM_TEMPERATURE; + } else if((res = cstr_to_double(arg, imposed_temperature)) != RES_OK) { + goto error; } + end: str_release(&keep); return res; @@ -1603,7 +1616,7 @@ read_delta goto error; } } else { - /* Could be 'auto' */ + /* Could be 'auto' */ if(0 == strcasecmp(arg, "AUTO")) { /* Set to DELTA_AUTO until actual value is substituted */ *delta = DELTA_AUTO; @@ -1644,10 +1657,11 @@ process_solid desc->type = DESC_MAT_SOLID; solid->solid_id = allocate_stardis_medium_id(stardis); solid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + solid->t0 = stardis->initial_time; solid->is_outside = 0; ASSERT(sz <= UINT_MAX); solid->desc_id = (unsigned)sz; - + CHK_ARG(idx, "solid name"); ERR(description_set_name(stardis, &solid->name, arg)); if(find_description_by_name(stardis, &solid->name, desc)) { @@ -1687,9 +1701,7 @@ process_solid ERR(read_delta(stardis, &solid->delta, pwordexp, &idx)); CHK_ARG(idx, "Tinit"); res = cstr_to_double(arg, &solid->tinit); - if(res != RES_OK - || solid->tinit < 0) - { + if(res != RES_OK || SDIS_TEMPERATURE_IS_UNKNOWN(solid->tinit)) { logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -1698,8 +1710,8 @@ process_solid stardis->t_range[1] = MMAX(stardis->t_range[1], solid->tinit); ERR(read_imposed_temperature(stardis, &solid->imposed_temperature, pwordexp, &idx)); - if(solid->imposed_temperature >= 0 - && solid->imposed_temperature != solid->tinit) + if(SDIS_TEMPERATURE_IS_KNOWN(solid->imposed_temperature) + && solid->imposed_temperature != solid->tinit) { logger_print(stardis->logger, LOG_ERROR, "Imposed temperature, if defined, must match initial temperature " @@ -1708,8 +1720,9 @@ process_solid res = RES_BAD_ARG; goto end; } - if(solid->imposed_temperature >= 0) + if(SDIS_TEMPERATURE_IS_KNOWN(solid->imposed_temperature)) stardis->t_range[0] = MMIN(stardis->t_range[0], solid->imposed_temperature); + stardis->t_range[1] = MMAX(stardis->t_range[1], solid->imposed_temperature); CHK_ARG(idx, "volumic power"); res = cstr_to_double(arg, &solid->vpower); @@ -1747,6 +1760,7 @@ process_solid_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double solid_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct solid_prog* solid_prog; struct stardis_description_create_context ctx; @@ -1766,7 +1780,7 @@ process_solid_prog solid_prog->solid_id = allocate_stardis_medium_id(stardis); ASSERT(sz <= UINT_MAX); solid_prog->desc_id = (unsigned)sz; - + CHK_ARG(idx, "programmed solid name"); ERR(description_set_name(stardis, &solid_prog->name, arg)); if(find_description_by_name(stardis, &solid_prog->name, desc)) { @@ -1800,7 +1814,9 @@ process_solid_prog ctx.name = desc_name; CREATE_DESC_DATA(solid_prog); - solid_prog->t_range(solid_prog->prog_data, stardis->t_range); + solid_prog->t_range(solid_prog->prog_data, solid_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], solid_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], solid_t_range[1]); ERR(create_solver_solid_prog(stardis, solid_prog)); @@ -1833,11 +1849,12 @@ process_fluid ERR(init_fluid(stardis->allocator, &desc->d.fluid)); fluid = desc->d.fluid; desc->type = DESC_MAT_FLUID; + fluid->t0 = stardis->initial_time; fluid->fluid_id = allocate_stardis_medium_id(stardis); fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; - + CHK_ARG(idx, "fluid name"); ERR(description_set_name(stardis, &fluid->name, arg)); if(find_description_by_name(stardis, &fluid->name, desc)) { @@ -1867,9 +1884,7 @@ process_fluid } CHK_ARG(idx, "Tinit"); res = cstr_to_double(arg, &fluid->tinit); - if(res != RES_OK - || fluid->tinit < 0) - { + if(res != RES_OK || SDIS_TEMPERATURE_IS_UNKNOWN(fluid->tinit)) { logger_print(stardis->logger, LOG_ERROR, "Invalid Tinit: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; @@ -1878,9 +1893,8 @@ process_fluid stardis->t_range[1] = MMAX(stardis->t_range[1], fluid->tinit); ERR(read_imposed_temperature(stardis, &fluid->imposed_temperature, pwordexp, &idx)); - if(fluid->imposed_temperature >= 0 - && fluid->imposed_temperature != fluid->tinit) - { + if(SDIS_TEMPERATURE_IS_KNOWN(fluid->imposed_temperature) + && fluid->imposed_temperature != fluid->tinit) { logger_print(stardis->logger, LOG_ERROR, "Imposed temperature, if defined, must match initial temperature " "(initial: %g; imposed: %g)\n", @@ -1888,7 +1902,7 @@ process_fluid res = RES_BAD_ARG; goto end; } - if(fluid->imposed_temperature >= 0) + if(SDIS_TEMPERATURE_IS_KNOWN(fluid->imposed_temperature)) stardis->t_range[0] = MMIN(stardis->t_range[0], fluid->imposed_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], fluid->imposed_temperature); @@ -1911,6 +1925,7 @@ process_fluid_prog char* arg = NULL; struct description* desc; const char *lib_name, *desc_name; + double fluid_t_range[2] = {DBL_MAX, -DBL_MAX}; size_t sz; struct fluid_prog* fluid_prog; struct stardis_description_create_context ctx; @@ -1930,7 +1945,7 @@ process_fluid_prog fluid_prog->fluid_id = allocate_stardis_medium_id(stardis); ASSERT(sz <= UINT_MAX); fluid_prog->desc_id = (unsigned)sz; - + CHK_ARG(idx, "programmed fluid name"); ERR(description_set_name(stardis, &fluid_prog->name, arg)); if(find_description_by_name(stardis, &fluid_prog->name, desc)) { @@ -1961,7 +1976,9 @@ process_fluid_prog ctx.name = desc_name; CREATE_DESC_DATA(fluid_prog); - fluid_prog->t_range(fluid_prog->prog_data, stardis->t_range); + fluid_prog->t_range(fluid_prog->prog_data, fluid_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], fluid_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], fluid_t_range[1]); ERR(create_solver_fluid_prog(stardis, fluid_prog)); @@ -2012,46 +2029,269 @@ process_radiative (struct stardis* stardis, wordexp_t* pwordexp) { + double trad = 0; + double tref = 0; char* arg = NULL; size_t idx = 1; res_T res = RES_OK; ASSERT(stardis && pwordexp); - if(stardis->trad_def) { + if(stardis->radenv_def) { logger_print(stardis->logger, LOG_ERROR, - "TRAD cannot be specified twice\n"); + "Radiative environment cannot be specified twice\n"); res = RES_BAD_ARG; - goto end; + goto error; } + + res = radiative_env_init_const(stardis->allocator, &stardis->radenv); + if(res != RES_OK) goto error; + CHK_ARG(idx, "Trad"); - res = cstr_to_double(arg, &stardis->trad); - if(res != RES_OK - || stardis->trad < 0) - { + res = cstr_to_double(arg, &trad); + if(res != RES_OK || SDIS_TEMPERATURE_IS_UNKNOWN(trad)) { logger_print(stardis->logger, LOG_ERROR, "Invalid Trad: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } CHK_ARG(idx, "Trad reference"); - res = cstr_to_double(arg, &stardis->trad_ref); - if(res != RES_OK - || stardis->trad_ref < 0) - { + res = cstr_to_double(arg, &tref); + if(res != RES_OK || tref < 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid Trad reference: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } - stardis->trad_def = 1; + + stardis->radenv.data.cst.temperature = trad; + stardis->radenv.data.cst.reference_temperature = tref; + stardis->radenv_def = 1; end: return res; error: + radiative_env_release(&stardis->radenv); + stardis->radenv = RADIATIVE_ENV_DEFAULT; goto end; } +static res_T +process_radiative_prog(struct stardis* stardis, wordexp_t* pwordexp) +{ + struct stardis_description_create_context ctx; + struct radiative_env_prog* radenv = NULL; + double radenv_t_range[2] = {DBL_MAX, -DBL_MAX}; + char* lib_name = NULL; + char* arg = NULL; + size_t idx = 1; + res_T res = RES_OK; + + ASSERT(stardis && pwordexp); + + radenv = &stardis->radenv.data.prg; + + if(stardis->radenv_def) { + logger_print(stardis->logger, LOG_ERROR, + "Radiative environment cannot be specified twice\n"); + res = RES_BAD_ARG; + goto error; + } + + res = radiative_env_init_prog(stardis->allocator, &stardis->radenv); + + CHK_ARG(idx, "program name"); + ERR(str_set(&radenv->prog_name, arg)); + lib_name = arg; + + if(idx < pwordexp->we_wordc + && strcasecmp(pwordexp->we_wordv[idx], "PROG_PARAMS")) { + logger_print(stardis->logger, LOG_ERROR, + "Expecting PROG_PARAMS keyword while parsing `%s'.\n", + pwordexp->we_wordv[idx]); + res = RES_BAD_ARG; + goto error; + } + + ERR(set_argc_argv + (stardis->allocator, &radenv->argc, &radenv->argv, pwordexp, idx)); + ERR(get_prog_common + (lib_name, stardis, &radenv->program, &radenv->create, &radenv->release)); + GET_LIB_SYMBOL(radenv, temperature, + stardis_radiative_env_temperature); + GET_LIB_SYMBOL(radenv, reference_temperature, + stardis_radiative_env_reference_temperature); + GET_LIB_SYMBOL(radenv, t_range, + stardis_t_range); + + ctx.name = "Radiative environment"; + radenv->data = radenv->create + (&ctx, radenv->program->prog_data, radenv->argc, radenv->argv); + if(!radenv->data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create data for the radiative environment\n"); + res = RES_UNKNOWN_ERR; + goto error; + } + + radenv->t_range(radenv->data, radenv_t_range); + stardis->t_range[0] = MMIN(stardis->t_range[0], radenv_t_range[0]); + stardis->t_range[1] = MMAX(stardis->t_range[1], radenv_t_range[1]); + +exit: + return res; +error: + radiative_env_release(&stardis->radenv); + stardis->radenv = RADIATIVE_ENV_DEFAULT; + goto exit; +} + +static res_T +process_spherical_source + (struct stardis* stardis, + wordexp_t* pwordexp) +{ + struct spherical_source* src = NULL; + char* arg = NULL; + size_t idx = 1; + res_T res = RES_OK; + ASSERT(stardis && pwordexp); + + src = &stardis->extsrc.data.sphere; + + if(stardis->extsrc.type != EXTERN_SOURCE_NONE__) { + logger_print(stardis->logger, LOG_ERROR, + "Only one external source can be defined\n"); + res = RES_BAD_ARG; + goto error; + } + + res = extern_source_init_sphere(stardis->allocator, &stardis->extsrc); + if(res != RES_OK) goto error; + + CHK_ARG(idx, "radius"); + res = cstr_to_double(arg, &src->radius); + if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Invalid spherical source radius: %s\n", arg); + goto error; + } + + #define PARSE_POS(Name, Id) { \ + CHK_ARG(idx, "position "Name); \ + res = cstr_to_double(arg, &src->position[Id]); \ + if(res != RES_OK) { \ + logger_print(stardis->logger, LOG_ERROR, \ + "Invalid spherical source "Name" coordinate: %s\n", arg); \ + goto error; \ + } \ + } (void)0 + PARSE_POS("X", 0); + PARSE_POS("Y", 1); + PARSE_POS("Z", 2); + #undef PARSE_POS + + CHK_ARG(idx, "power"); + res = cstr_to_double(arg, &src->power); + if(res == RES_OK && src->power < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Invalid spherical source power: %s\n", arg); + goto error; + } + + CHK_ARG(idx, "diffuse radiance"); + res = cstr_to_double(arg, &src->diffuse_radiance); + if(res == RES_OK && src->diffuse_radiance < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Invalid diffuse radiance for the spherical source: %s\n", arg); + goto error; + } + + res = extern_source_create_solver_source(&stardis->extsrc, stardis); + if(res != RES_OK) goto error; + +exit: + return res; +error: + extern_source_release(&stardis->extsrc); + stardis->extsrc = EXTERN_SOURCE_NULL; + goto exit; +} + +static res_T +process_spherical_source_prog(struct stardis* stardis, wordexp_t* pwordexp) +{ + struct stardis_description_create_context ctx; + struct spherical_source_prog* src = NULL; + char* lib_name = NULL; + char* arg = NULL; + size_t idx = 1; + res_T res = RES_OK; + ASSERT(stardis && pwordexp); + + src = &stardis->extsrc.data.sphere_prog; + + if(stardis->extsrc.type != EXTERN_SOURCE_NONE__) { + logger_print(stardis->logger, LOG_ERROR, + "Only one external source can be defined\n"); + res = RES_BAD_ARG; + goto error; + } + + res = extern_source_init_sphere_prog(stardis->allocator, &stardis->extsrc); + if(res != RES_OK) goto error; + + CHK_ARG(idx, "radius"); + res = cstr_to_double(arg, &src->radius); + if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Invalid spherical source radius: %s\n", arg); + goto error; + } + + CHK_ARG(idx, "program name"); + ERR(str_set(&src->prog_name, arg)); + lib_name = arg; + + if(idx < pwordexp->we_wordc + && strcasecmp(pwordexp->we_wordv[idx], "PROG_PARAMS")) { + logger_print(stardis->logger, LOG_ERROR, + "Expecting PROG_PARAMS keyword while parsing `%s'.\n", + pwordexp->we_wordv[idx]); + res = RES_BAD_ARG; + goto error; + } + + ERR(set_argc_argv(stardis->allocator, &src->argc, &src->argv, pwordexp, idx)); + ERR(get_prog_common(lib_name, stardis, &src->program, &src->create, &src->release)); + GET_LIB_SYMBOL(src, position, stardis_spherical_source_position); + GET_LIB_SYMBOL(src, power, stardis_spherical_source_power); + GET_LIB_SYMBOL(src, diffuse_radiance, stardis_spherical_source_diffuse_radiance); + + ctx.name = "External spherical source"; + src->data = src->create(&ctx, src->program->prog_data, src->argc, src->argv); + if(!src->data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create data for the external spherical source\n"); + res = RES_UNKNOWN_ERR; + goto error; + } + + res = extern_source_create_solver_source(&stardis->extsrc, stardis); + if(res != RES_OK) goto error; + +exit: + return res; +error: + extern_source_release(&stardis->extsrc); + stardis->extsrc = EXTERN_SOURCE_NULL; + goto exit; +} + /* Read medium or boundary line; should be one of: * SOLID Name lambda rho cp delta Tinit Timposed volumic_power STL_sides_filenames * FLUID Name rho cp Tinit Timposed STL_filenames @@ -2090,7 +2330,7 @@ process_model_line ASSERT(file_name && line && pwordexp && stardis); CHK_ARG(idx, "model line type"); - + if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_SOLID")) ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, pwordexp)); else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_SOLID_PROG")) @@ -2133,6 +2373,12 @@ process_model_line ERR(process_scale(stardis, pwordexp)); else if(0 == strcasecmp(arg, "TRAD")) ERR(process_radiative(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "TRAD_PROG")) + ERR(process_radiative_prog(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE")) + ERR(process_spherical_source(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE_PROG")) + ERR(process_spherical_source_prog(stardis, pwordexp)); else { logger_print(stardis->logger, LOG_ERROR, "Unknown description type: %s\n", arg); @@ -2171,6 +2417,7 @@ get_dummy_solid_id dummies->stardis_solid = dummy; dummies->dummy_solid_id = allocate_stardis_medium_id(stardis); dummy->solid_id = dummies->dummy_solid_id; + dummy->t0 = stardis->initial_time; dummy->is_outside = 1; dummy->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); create_solver_solid(stardis, dummy); @@ -2204,6 +2451,7 @@ get_dummy_fluid_id dummies->stardis_fluid = dummy; dummies->dummy_fluid_id = allocate_stardis_medium_id(stardis); dummy->fluid_id = dummies->dummy_fluid_id; + dummy->t0 = stardis->initial_time; dummy->is_outside = 1; dummy->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); create_solver_fluid(stardis, dummy); @@ -2296,10 +2544,14 @@ exp_error: stardis->scale_factor = STARDIS_DEFAULT_SCALE_FACTOR; logger_print(stardis->logger, LOG_OUTPUT, "Scaling factor is %g\n", stardis->scale_factor); - logger_print(stardis->logger, LOG_OUTPUT, - "Trad is %g, Trad reference is %g\n", stardis->trad, stardis->trad_ref); - stardis->t_range[0] = MMIN(stardis->t_range[0], stardis->trad_ref); - stardis->t_range[1] = MMAX(stardis->t_range[1], stardis->trad_ref); + if(stardis->radenv.type == RADIATIVE_ENV_CONST) { + const double trad = stardis->radenv.data.cst.temperature; + const double trad_ref = stardis->radenv.data.cst.reference_temperature; + logger_print(stardis->logger, LOG_OUTPUT, + "Trad is %g, Trad reference is %g\n", trad, trad_ref); + stardis->t_range[0] = MMIN(stardis->t_range[0], trad_ref); + stardis->t_range[1] = MMAX(stardis->t_range[1], trad_ref); + } logger_print(stardis->logger, LOG_OUTPUT, "System T range is [%g %g]\n", SPLIT2(stardis->t_range)); logger_print(stardis->logger, LOG_OUTPUT, diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in @@ -4,12 +4,12 @@ * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -26,6 +26,12 @@ #include <stddef.h> +#if defined(__GNUC__) + #define STARDIS_API extern __attribute__((visibility("default"))) +#else + #define STARDIS_API extern +#endif + /*****************************************************************************/ /* API types. */ /* The various functions defining programmed descriptions receive arguments */ @@ -36,6 +42,8 @@ struct stardis_vertex { double P[3]; /* World space position */ double time; /* "Time" of the vertex */ }; +#define STARDIS_VERTEX_NULL__ {{0,0,0}, 0} +static const struct stardis_vertex STARDIS_VERTEX_NULL = STARDIS_VERTEX_NULL__; enum stardis_side { FRONT, @@ -71,6 +79,10 @@ struct stardis_description_create_context { const char* name; /* Description name */ }; +#ifdef __cplusplus +extern "C" { +#endif + /******************************************************************************/ /* Optional functions for any programmed library. */ /* Either all 3 or none of the 3 following functions must be defined. */ @@ -83,7 +95,7 @@ struct stardis_description_create_context { * processed. * argc + argv describe the (possibly zero) arguments coming from the stardis * input file in the main-like standard way. */ -extern void* +STARDIS_API void* stardis_create_library_data (const struct stardis_program_context* ctx, size_t argc, @@ -96,7 +108,7 @@ stardis_create_library_data * starts. * lib_data is the pointer returned by stardis_create_library_data for this * library. */ -enum stardis_return_status +STARDIS_API enum stardis_return_status stardis_finalize_library_data (void* lib_data); @@ -105,7 +117,7 @@ stardis_finalize_library_data * descriptions data. * lib_data is the pointer returned by stardis_create_library_data for this * library. */ -extern void +STARDIS_API void stardis_release_library_data (void* lib_data); @@ -114,14 +126,14 @@ stardis_release_library_data /******************************************************************************/ /* Create the data attached to a given description. - * A NULL result is interpreted as an error and ends the program. + * A NULL result is interpreted as an error and ends the program. * This function is called every time a description using this library is * processed. * lib_data is the pointer returned by stardis_create_library_data for the * library or NULL if stardis_create_library_data is not defined. * argc + argv describe the (possibly zero) arguments coming from the stardis * input file in the main-like standard way. */ -extern void* +STARDIS_API void* stardis_create_data (const struct stardis_description_create_context *ctx, void* lib_data, @@ -131,28 +143,28 @@ stardis_create_data /* Release the data created by stardis_create_data. * This function is called after the simulation finished. * data is the pointer returned by stardis_create_data for the description. */ -extern void +STARDIS_API void stardis_release_data (void* data); /* Get the copyright notice. * A NULL result is interpreted as an error and ends the program. * data is the pointer returned by stardis_create_data for the description. */ -const char* +STARDIS_API const char* get_copyright_notice (void* data); /* Get single-line (name and link?) version of the license. * A NULL result is interpreted as an error and ends the program. * data is the pointer returned by stardis_create_data for the description. */ -const char* +STARDIS_API const char* get_license_short (void* data); /* Get full license text. * A NULL result is interpreted as an error and ends the program. * data is the pointer returned by stardis_create_data for the description. */ -const char* +STARDIS_API const char* get_license_text (void* data); @@ -170,7 +182,7 @@ get_license_text * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_calorific_capacity (const struct stardis_vertex* vtx, void* data); @@ -179,7 +191,7 @@ stardis_calorific_capacity * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_volumic_mass (const struct stardis_vertex* vtx, void* data); @@ -188,7 +200,7 @@ stardis_volumic_mass * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_conductivity (const struct stardis_vertex* vtx, void* data); @@ -197,7 +209,7 @@ stardis_conductivity * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_delta_solid (const struct stardis_vertex* vtx, void* data); @@ -206,7 +218,7 @@ stardis_delta_solid * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_volumic_power (const struct stardis_vertex* vtx, void* data); @@ -216,7 +228,7 @@ stardis_volumic_power * This functions is called at every vertex of every path of the computation * crossing this solid. * data is the pointer returned by stardis_create_data for this solid. */ -extern double +STARDIS_API double stardis_medium_temperature (const struct stardis_vertex* vtx, void* data); @@ -225,7 +237,7 @@ stardis_medium_temperature * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this solid. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -238,7 +250,7 @@ stardis_t_range * This functions is called at every vertex of every path of the computation * crossing this fluid. * data is the pointer returned by stardis_create_data for this fluid. */ -extern double +STARDIS_API double stardis_calorific_capacity (const struct stardis_vertex* vtx, void* data); @@ -247,7 +259,7 @@ stardis_calorific_capacity * This functions is called at every vertex of every path of the computation * crossing this fluid. * data is the pointer returned by stardis_create_data for this fluid. */ -extern double +STARDIS_API double stardis_volumic_mass (const struct stardis_vertex* vtx, void* data); @@ -257,7 +269,7 @@ stardis_volumic_mass * This functions is called at every vertex of every path of the computation * crossing this fluid. * data is the pointer returned by stardis_create_data for this fluid. */ -extern double +STARDIS_API double stardis_medium_temperature (const struct stardis_vertex* vtx, void* data); @@ -266,7 +278,7 @@ stardis_medium_temperature * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this fluid. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -279,7 +291,7 @@ stardis_t_range * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_boundary_temperature (const struct stardis_interface_fragment* frag, void* data); @@ -288,25 +300,27 @@ stardis_boundary_temperature * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_emissivity (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the specular fraction at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_specular_fraction (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the convection coefficient at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_convection_coefficient (const struct stardis_interface_fragment* frag, void* data); @@ -317,7 +331,7 @@ stardis_convection_coefficient * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_reference_temperature (const struct stardis_interface_fragment* frag, void* data); @@ -325,7 +339,7 @@ stardis_reference_temperature /* Returns the upper bound of the convection coefficient accross this boundary. * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_max_convection_coefficient (void* data); @@ -333,7 +347,7 @@ stardis_max_convection_coefficient * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -346,25 +360,27 @@ stardis_t_range * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_emissivity (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the specular fraction at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_specular_fraction (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the convection coefficient at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_convection_coefficient (const struct stardis_interface_fragment* frag, void* data); @@ -375,7 +391,7 @@ stardis_convection_coefficient * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_reference_temperature (const struct stardis_interface_fragment* frag, void* data); @@ -386,7 +402,7 @@ stardis_reference_temperature * This functions is called at every vertex of every path of the computation * crossing this fluid. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_medium_temperature (const struct stardis_vertex* vtx, void* data); @@ -394,7 +410,7 @@ stardis_medium_temperature /* Returns the upper bound of the convection coefficient accross this boundary. * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_max_convection_coefficient (void* data); @@ -402,7 +418,7 @@ stardis_max_convection_coefficient * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -415,7 +431,7 @@ stardis_t_range * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_boundary_temperature (const struct stardis_interface_fragment* frag, void* data); @@ -424,7 +440,7 @@ stardis_boundary_temperature * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -437,25 +453,27 @@ stardis_t_range * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_emissivity (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the specular fraction at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_specular_fraction (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the convection coefficient at a given fragment. * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_convection_coefficient (const struct stardis_interface_fragment* frag, void* data); @@ -464,7 +482,7 @@ stardis_convection_coefficient * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_boundary_flux (const struct stardis_interface_fragment* frag, void* data); @@ -475,7 +493,7 @@ stardis_boundary_flux * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_reference_temperature (const struct stardis_interface_fragment* frag, void* data); @@ -486,7 +504,7 @@ stardis_reference_temperature * This functions is called at every vertex of every path of the computation * crossing this fluid. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_medium_temperature (const struct stardis_vertex* vtx, void* data); @@ -494,7 +512,7 @@ stardis_medium_temperature /* Returns the upper bound of the convection coefficient accross this boundary. * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_max_convection_coefficient (void* data); @@ -502,7 +520,7 @@ stardis_max_convection_coefficient * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this boundary. * Returns its modified range argument. */ -extern double* +STARDIS_API double* stardis_t_range (void* data, double range[2]); @@ -515,7 +533,7 @@ stardis_t_range * This functions is called every time a path of the computation reaches * this boundary. * data is the pointer returned by stardis_create_data for this boundary. */ -extern double +STARDIS_API double stardis_boundary_flux (const struct stardis_interface_fragment* frag, void* data); @@ -528,7 +546,7 @@ stardis_boundary_flux * This functions is called every time a path of the computation reaches * this connection. * data is the pointer returned by stardis_create_data for this connection. */ -extern double +STARDIS_API double stardis_thermal_contact_resistance (const struct stardis_interface_fragment* frag, void* data); @@ -541,25 +559,27 @@ stardis_thermal_contact_resistance * This functions is called every time a path of the computation reaches * this connection. * data is the pointer returned by stardis_create_data for this connection. */ -extern double +STARDIS_API double stardis_emissivity (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the specular fraction at a given fragment. * This functions is called every time a path of the computation reaches * this connection. * data is the pointer returned by stardis_create_data for this connection. */ -extern double +STARDIS_API double stardis_specular_fraction (const struct stardis_interface_fragment* frag, + const unsigned source_id, void* data); /* Returns the convection coefficient at a given fragment. * This functions is called every time a path of the computation reaches * this connection. * data is the pointer returned by stardis_create_data for this connection. */ -extern double +STARDIS_API double stardis_convection_coefficient (const struct stardis_interface_fragment* frag, void* data); @@ -567,18 +587,93 @@ stardis_convection_coefficient /* Returns the upper bound of the convection coefficient accross this connection. * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this connection. */ -extern double +STARDIS_API double stardis_max_convection_coefficient (void* data); +/* Returns the reference temperature at a given fragment. + * This temperature is used as a reference to linearize radiative transfer + * in Picard computations. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +STARDIS_API double +stardis_reference_temperature + (const struct stardis_interface_fragment* frag, + void* data); + /* Computes the expected temperature range for this connection. * This functions is called once when initializing the computation. * data is the pointer returned by stardis_create_data for this connection. * Returns its modified range argument. */ -extern double* +STARDIS_API double* +stardis_t_range + (void* data, + double range[2]); + +/******************************************************************************/ +/* Additional mandatory functions for a programmed spherical source */ +/* These functions are used to calculate the external flux at the boundaries. */ +/******************************************************************************/ + +/* Retrieve the position of the spherical source center. + * This function is used to calculate the external flux at the boundaries. + * Returns its modified position argument */ +STARDIS_API double* +stardis_spherical_source_position + (const double time, /* [s] */ + double position[3], + void* data); + +/* Retrieve the power of the spherical source. */ +STARDIS_API double /* [W] */ +stardis_spherical_source_power + (const double time, + void* data); + +/* Describes the diffuse part of the source's radiance, i.e. the radiance + * emitted by the source and scattered at least once in the environment. This + * parameter is actually used to approximate a semi-transparent medium. Its + * value can be 0, meaning that the source has not been scattered by the + * environment, or, to put it another way, that the source is in a vacuum. */ +STARDIS_API double /* [W/m^2/sr] */ +stardis_spherical_source_diffuse_radiance + (const double time, + const double dir[3], + void* data); + +/******************************************************************************/ +/* Additional mandatory functions for a programmed radiative environment */ +/******************************************************************************/ + +/* Retrieve the temperature of radiative paths that reach infinity */ +STARDIS_API double +stardis_radiative_env_temperature + (const double time, /* [s] */ + const double dir[3], + void* data); + +/* Recover the reference temperature of radiative paths that reach + * infinity. It is used to linearize radiative transfer */ +STARDIS_API double +stardis_radiative_env_reference_temperature + (const double time, /* [s] */ + const double dir[3], + void* data); + +/* Computes the expected temperature range for this radiative + * environment. + * This functions is called once when initializing the computation. + * data is the pointer returned by stardis_create_data for this + * radiative environment. + * Returns its modified range argument. */ +STARDIS_API double* stardis_t_range (void* data, double range[2]); +#ifdef __cplusplus +} /* extern "C" */ #endif +#endif diff --git a/src/stardis-program.c b/src/stardis-program.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-program.h b/src/stardis-program.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -17,8 +17,7 @@ #define STARDIS_PROGRAM_H #include "stardis-app.h" - -#include <stardis-prog-properties.h> +#include "stardis-prog-properties.h" #include <rsys/rsys.h> #include <rsys/str.h> diff --git a/src/stardis-radiative-env.c b/src/stardis-radiative-env.c @@ -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/>. */ + +#include "stardis-app.h" +#include "stardis-radiative-env.h" + +#include <sdis.h> +#include <rsys/cstr.h> +#include <rsys/logger.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static double +radenv_get_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_const* props = sdis_data_cget(data); + (void)ray; + return props->temperature; +} + +static double +radenv_get_reference_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_const* props = sdis_data_cget(data); + (void)ray; + return props->reference_temperature; +} + +static res_T +create_radenv_const + (struct radiative_env* radenv, + struct stardis* stardis) +{ + struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; + struct sdis_data* data = NULL; + struct radiative_env_const* props = NULL; + res_T res = RES_OK; + ASSERT(radenv && radenv->type == RADIATIVE_ENV_CONST && stardis); + + res = sdis_data_create(stardis->dev, sizeof(struct radiative_env_const), + ALIGNOF(struct radiative_env_const), NULL, &data); + if(res != RES_OK) goto error; + props = sdis_data_get(data); + *props = radenv->data.cst; + + shader.temperature = radenv_get_temperature; + shader.reference_temperature = radenv_get_reference_temperature; + res = sdis_radiative_env_create + (stardis->dev, &shader, data, &radenv->sdis_radenv); + if(res != RES_OK) goto error; + +exit: + /* Release the local reference on the data: it is kept by the sdis radenv */ + if(data) SDIS(data_ref_put(data)); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the radiative environment for the solver -- %s\n", + res_to_cstr(res)); + goto exit; +} + +static double +radenv_prog_get_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_prog* radenv = NULL; + + radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); + return radenv->temperature(ray->time, ray->dir, radenv->data); +} + +static double +radenv_prog_get_reference_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_prog* radenv = NULL; + + radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); + return radenv->reference_temperature(ray->time, ray->dir, radenv->data); +} + +static res_T +create_radenv_prog + (struct radiative_env* radenv, + struct stardis* stardis) +{ + struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; + struct sdis_data* data = NULL; + res_T res = RES_OK; + ASSERT(radenv && radenv->type == RADIATIVE_ENV_PROG && stardis); + + /* Register a pointer to the radiative environment with the solver radiative + * environment */ + res = sdis_data_create(stardis->dev, sizeof(struct radiative_env_prog*), + ALIGNOF(struct radiative_env_prog*), NULL, &data); + if(res != RES_OK) goto error; + *((struct radiative_env_prog**)sdis_data_get(data)) = &radenv->data.prg; + + /* Create the radiative environment */ + shader.temperature = radenv_prog_get_temperature; + shader.reference_temperature = radenv_prog_get_reference_temperature; + res = sdis_radiative_env_create + (stardis->dev, &shader, data, &radenv->sdis_radenv); + if(res != RES_OK) goto error; + +exit: + /* Release the local reference on the data: it is kept by the sdis radenv */ + if(data) SDIS(data_ref_put(data)); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the radiative environment for the solver -- %s\n", + res_to_cstr(res)); + goto exit; +} + +/******************************************************************************* + * Local function + ******************************************************************************/ +res_T +radiative_env_init_const + (struct mem_allocator* allocator, + struct radiative_env* radenv) +{ + ASSERT(radenv); + (void)allocator; + radenv->type = RADIATIVE_ENV_CONST; + radenv->data.cst = RADIATIVE_ENV_CONST_DEFAULT; + return RES_OK; +} + +res_T +radiative_env_init_prog + (struct mem_allocator* allocator, + struct radiative_env* radenv) +{ + ASSERT(radenv); + radenv->type = RADIATIVE_ENV_PROG; + radenv->data.prg = RADIATIVE_ENV_PROG_NULL; + radenv->data.prg.allocator = allocator; + str_init(allocator, &radenv->data.prg.prog_name); + return RES_OK; +} + +void +radiative_env_release(struct radiative_env* radenv) +{ + ASSERT(radenv); + + if(radenv->type == RADIATIVE_ENV_PROG) { + struct radiative_env_prog* radenv_prog = &radenv->data.prg; + size_t i = 0; + + if(radenv_prog->data) { + ASSERT(radenv_prog->release); + radenv_prog->release(radenv_prog->data); + } + + str_release(&radenv_prog->prog_name); + FOR_EACH(i, 0, radenv_prog->argc) { + MEM_RM(radenv_prog->allocator, radenv_prog->argv[i]); + } + MEM_RM(radenv_prog->allocator, radenv_prog->argv); + } + + if(radenv->sdis_radenv) SDIS(radiative_env_ref_put(radenv->sdis_radenv)); + radenv->sdis_radenv = NULL; +} + +res_T +radiative_env_create_solver_radiative_env + (struct radiative_env* radenv, + struct stardis* stardis) +{ + res_T res = RES_OK; + ASSERT(radenv && stardis); + + switch(radenv->type) { + case RADIATIVE_ENV_CONST: + res = create_radenv_const(radenv, stardis); + if(res != RES_OK) goto error; + break; + case RADIATIVE_ENV_PROG: + res = create_radenv_prog(radenv, stardis); + if(res != RES_OK) goto error; + break; + default: FATAL("Unreachable code\n"); break; + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/stardis-radiative-env.h b/src/stardis-radiative-env.h @@ -0,0 +1,118 @@ +/* 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/>. */ + +#ifndef STARDIS_RADIATIVE_ENV_H +#define STARDIS_RADIATIVE_ENV_H + +#include "stardis-default.h" +#include <rsys/rsys.h> + +/* Forward declaration */ +struct stardis; + +enum radiative_env_type { + RADIATIVE_ENV_CONST, + RADIATIVE_ENV_PROG +}; + +struct radiative_env_const { + double temperature; + double reference_temperature; +}; +#define RADIATIVE_ENV_CONST_DEFAULT__ { \ + STARDIS_DEFAULT_TRAD, \ + STARDIS_DEFAULT_TRAD_REFERENCE \ +} +static const struct radiative_env_const RADIATIVE_ENV_CONST_DEFAULT = + RADIATIVE_ENV_CONST_DEFAULT__; + +struct radiative_env_prog { + struct str prog_name; + struct program* program; + void* data; /* Pointer toward the program data */ + struct mem_allocator* allocator; + + /* Input arguments */ + size_t argc; + char** argv; + + void* + (*create) + (const struct stardis_description_create_context* ctx, + void* lib_data, + size_t argc, + char* argv[]); + + void + (*release) + (void* data); + + double + (*temperature) + (const double time, /* [s] */ + const double dir[3], + void* data); + + double + (*reference_temperature) + (const double time, /* [s] */ + const double dir[3], + void* data); + + double* + (*t_range) + (void* data, + double t_range[2]); +}; +#define RADIATIVE_ENV_PROG_NULL__ \ + {{0}, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL} +static const struct radiative_env_prog RADIATIVE_ENV_PROG_NULL = + RADIATIVE_ENV_PROG_NULL__; + +struct radiative_env { + enum radiative_env_type type; + union { + struct radiative_env_const cst; + struct radiative_env_prog prg; + } data; + struct sdis_radiative_env* sdis_radenv; +}; +#define RADIATIVE_ENV_DEFAULT__ { \ + RADIATIVE_ENV_CONST, \ + {RADIATIVE_ENV_CONST_DEFAULT__}, \ + NULL \ +} +static const struct radiative_env RADIATIVE_ENV_DEFAULT = RADIATIVE_ENV_DEFAULT__; + +extern LOCAL_SYM res_T +radiative_env_init_const + (struct mem_allocator* allocator, + struct radiative_env* radenv); + +extern LOCAL_SYM res_T +radiative_env_init_prog + (struct mem_allocator* allocator, + struct radiative_env* radenv); + +extern LOCAL_SYM void +radiative_env_release + (struct radiative_env* radenv); + +extern LOCAL_SYM res_T +radiative_env_create_solver_radiative_env + (struct radiative_env* radenv, + struct stardis* stardis); + +#endif /* STARDIS_RADIATIVE_ENV_H */ diff --git a/src/stardis-sfconnect-prog.c b/src/stardis-sfconnect-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-sfconnect-prog.h b/src/stardis-sfconnect-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -43,8 +43,10 @@ struct solid_fluid_connect_prog { (const struct stardis_description_create_context*, void*, size_t, char**); void (*release)(void*); double (*ref_temp)(const struct stardis_interface_fragment*, void*); - double (*emissivity)(const struct stardis_interface_fragment*, void*); - double (*alpha)(const struct stardis_interface_fragment*, void*); + double (*emissivity) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); + double (*alpha) + (const struct stardis_interface_fragment*, const unsigned src_id, void*); double (*hc)(const struct stardis_interface_fragment*, void*); double (*hmax)(void*); double* (*t_range)(void*, double trange[2]); diff --git a/src/stardis-sfconnect.c b/src/stardis-sfconnect.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-sfconnect.h b/src/stardis-sfconnect.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -120,6 +120,7 @@ create_solver_solid_prog solid_shader.delta= solid_prog_get_delta; solid_shader.volumic_power = solid_prog_get_volumic_power; solid_shader.temperature = solid_prog_get_temperature; + solid_shader.t0 = stardis->initial_time; ERR(sdis_data_create(stardis->dev, sizeof(struct solid_prog*), ALIGNOF(struct solid_prog*), NULL, &data)); diff --git a/src/stardis-solid-prog.h b/src/stardis-solid-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-solid.c b/src/stardis-solid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -83,12 +83,12 @@ solid_get_temperature struct sdis_data* data) { const struct solid* const* solid_props = sdis_data_cget(data); - if((*solid_props)->imposed_temperature >= 0) + if(SDIS_TEMPERATURE_IS_KNOWN((*solid_props)->imposed_temperature)) /* If there is an imposed temp, it is imposed regardless of time */ return (*solid_props)->imposed_temperature; if(vtx->time <= (*solid_props)->t0) { /* If time is <= t0: use tinit */ - if((*solid_props)->tinit < 0) { + if(SDIS_TEMPERATURE_IS_UNKNOWN((*solid_props)->tinit)) { if(str_is_empty(&(*solid_props)->name)) { FATAL("solid_get_temperature: getting undefined Tinit\n"); } else { @@ -98,7 +98,7 @@ solid_get_temperature } return (*solid_props)->tinit; } - return -1; /* Unknown temperature */ + return SDIS_TEMPERATURE_NONE; } static double @@ -135,6 +135,7 @@ create_solver_solid solid_shader.delta_boundary = solid_get_delta_boundary; #endif solid_shader.temperature = solid_get_temperature; + solid_shader.t0 = stardis->initial_time; ERR(sdis_data_create(stardis->dev, sizeof(struct solid), ALIGNOF(struct solid), NULL, &data)); @@ -171,8 +172,8 @@ init_solid(struct mem_allocator* allocator, struct solid** dst) (*dst)->rho = 1; (*dst)->cp = 1; (*dst)->delta = 1; - (*dst)->tinit = -1; - (*dst)->imposed_temperature = -1; + (*dst)->tinit = SDIS_TEMPERATURE_NONE; + (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; (*dst)->vpower = SDIS_VOLUMIC_POWER_NONE; (*dst)->t0 = 0; (*dst)->is_outside = 0; @@ -207,10 +208,10 @@ str_print_solid(struct str* str, const struct solid* s) if(s->vpower != 0) { ERR(str_append_printf(str, " VPower=%g", s->vpower)); } - if(s->tinit >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(s->tinit)) { ERR(str_append_printf(str, " Tinit=%g", s->tinit)); } - if(s->imposed_temperature >= 0) { + if(SDIS_TEMPERATURE_IS_KNOWN(s->imposed_temperature)) { ERR(str_append_printf(str, " Temp=%g", s->imposed_temperature)); } ERR(str_append_printf(str, " (it is medium %u)", s->solid_id)); diff --git a/src/stardis-solid.h b/src/stardis-solid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -32,7 +32,7 @@ struct solid { double cp; /* Calorific capacity */ double delta; /* Numerical parameter */ double tinit; /* Initial temperature */ - double imposed_temperature; /* allow to impose a T; -1 if unset */ + double imposed_temperature; /* Impose a T; SDIS_TEMPERATURE_NONE if unset */ double vpower; double t0; /* End time of tinit */ int is_outside; /* the solid is used for a boundary */ diff --git a/src/stardis-ssconnect-prog.c b/src/stardis-ssconnect-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-ssconnect-prog.h b/src/stardis-ssconnect-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-ssconnect.c b/src/stardis-ssconnect.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-ssconnect.h b/src/stardis-ssconnect.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-tbound-prog.c b/src/stardis-tbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-tbound-prog.h b/src/stardis-tbound-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-tbound.c b/src/stardis-tbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 @@ -44,7 +44,7 @@ init_t_boundary } str_init(allocator, &(*dst)->name); str_initialized = 1; - (*dst)->imposed_temperature = -1; + (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; (*dst)->mat_id = UINT_MAX; end: return res; diff --git a/src/stardis-tbound.h b/src/stardis-tbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) +/* 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 diff --git a/src/stardis-version.h.in b/src/stardis-version.h.in @@ -16,9 +16,9 @@ #ifndef STARDIS_APP_VERSION_H #define STARDIS_APP_VERSION_H -#define STARDIS_APP_VERSION_MAJOR @SDIS_VERSION_MAJOR@ -#define STARDIS_APP_VERSION_MINOR @SDIS_VERSION_MINOR@ -#define STARDIS_APP_VERSION_PATCH @SDIS_VERSION_PATCH@ +#define STARDIS_APP_VERSION_MAJOR @STARDIS_APP_VERSION_MAJOR@ +#define STARDIS_APP_VERSION_MINOR @STARDIS_APP_VERSION_MINOR@ +#define STARDIS_APP_VERSION_PATCH @STARDIS_APP_VERSION_PATCH@ #endif /* STARDIS_APP_VERSION_H */ diff --git a/stardis-green-types/stardis-green-types-config-version.cmake.in b/stardis-green-types/stardis-green-types-config-version.cmake.in @@ -1,22 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -SET(PACKAGE_VERSION @STARDIS_GREEN_TYPES_VERSION@) - -IF (${PACKAGE_FIND_VERSION_MAJOR} EQUAL @STARDIS_GREEN_TYPES_VERSION@) - SET(PACKAGE_VERSION_COMPATIBLE 1) -ELSE() - SET(PACKAGE_VERSION_UNSUITABLE 1) -ENDIF() diff --git a/stardis-green-types/stardis-green-types-config.cmake b/stardis-green-types/stardis-green-types-config.cmake @@ -1,28 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.1) -include(SelectLibraryConfigurations) - -# Try to find stardis-green-types - -# Look for stardis-green-types header -find_path(SGT_INCLUDE_DIR stardis/stardis-green-types.h) - -# Check the package -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(stardis-green-types DEFAULT_MSG - SGT_INCLUDE_DIR) - diff --git a/stardis-prog-properties/stardis-prog-properties-config-version.cmake.in b/stardis-prog-properties/stardis-prog-properties-config-version.cmake.in @@ -1,22 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -SET(PACKAGE_VERSION @STARDIS_PROG_PROPERTIES_VERSION@) - -IF (${PACKAGE_FIND_VERSION_MAJOR} EQUAL @STARDIS_PROG_PROPERTIES_VERSION@) - SET(PACKAGE_VERSION_COMPATIBLE 1) -ELSE() - SET(PACKAGE_VERSION_UNSUITABLE 1) -ENDIF() diff --git a/stardis-prog-properties/stardis-prog-properties-config.cmake b/stardis-prog-properties/stardis-prog-properties-config.cmake @@ -1,28 +0,0 @@ -# Copyright (C) 2018-2023 |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/>. - -cmake_minimum_required(VERSION 3.1) -include(SelectLibraryConfigurations) - -# Try to find stardis-prog-properties - -# Look for stardis-prog-properties header -find_path(SPROG_INCLUDE_DIR stardis/stardis-prog-properties.h) - -# Check the package -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(stardis-prog-properties DEFAULT_MSG - SPROG_INCLUDE_DIR) -