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:
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 © 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, °enerated);
+ 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(°enerated);
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)
-