stardis

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

commit 32f5d5d05281567626cb77589266622bd4a22868
parent e3f87ace9381dacad39e9189c5aefc2391c9e6e6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 14 Nov 2025 14:22:51 +0100

Merge branch 'release_0.12'

Diffstat:
MMakefile | 80+++++++++++++++++++++++++++++++++++++++----------------------------------------
MREADME.md | 37++++++++++++++++++++++++++++++++++++-
Mconfig.mk | 57++++++++++++---------------------------------------------
Mdoc/stardis-input.5.in | 17+++++++++++++++--
Mdoc/stardis-output.5 | 18+++++++++++++++++-
Mdoc/stardis.1.in | 40++++++++++++++++++++++++++++++++++------
Msrc/stardis-app.c | 14++++++++------
Msrc/stardis-app.h | 2+-
Msrc/stardis-args.c | 146++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/stardis-args.h.in | 83+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/stardis-compute-probe-boundary.c | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/stardis-compute.c | 129+++++++++++++++++++++++++++----------------------------------------------------
Msrc/stardis-compute.h | 51++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/stardis-description.c | 2+-
Msrc/stardis-description.h | 2+-
Msrc/stardis-extern-source.c | 2+-
Msrc/stardis-extern-source.h | 2+-
Msrc/stardis-fbound-prog.c | 2+-
Msrc/stardis-fbound-prog.h | 2+-
Msrc/stardis-fbound.c | 2+-
Msrc/stardis-fbound.h | 2+-
Msrc/stardis-fluid-prog.c | 2+-
Msrc/stardis-fluid-prog.h | 2+-
Msrc/stardis-fluid.c | 2+-
Msrc/stardis-fluid.h | 2+-
Msrc/stardis-hbound-prog.c | 2+-
Msrc/stardis-hbound-prog.h | 2+-
Msrc/stardis-hbound.c | 2+-
Msrc/stardis-hbound.h | 2+-
Msrc/stardis-hfbound-prog.c | 2+-
Msrc/stardis-hfbound-prog.h | 2+-
Msrc/stardis-hfbound.c | 2+-
Msrc/stardis-hfbound.h | 2+-
Msrc/stardis-intface.c | 12+++++++++++-
Msrc/stardis-intface.h | 2+-
Msrc/stardis-main.c | 2+-
Msrc/stardis-output.c | 122++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/stardis-output.h | 2+-
Msrc/stardis-parsing.c | 194+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/stardis-parsing.h | 2+-
Msrc/stardis-prog-properties.h.in | 5+++--
Msrc/stardis-program.c | 2+-
Msrc/stardis-program.h | 2+-
Msrc/stardis-radiative-env.c | 2+-
Msrc/stardis-radiative-env.h | 2+-
Msrc/stardis-sfconnect-prog.c | 3+--
Msrc/stardis-sfconnect-prog.h | 3++-
Msrc/stardis-sfconnect.c | 3++-
Msrc/stardis-sfconnect.h | 3++-
Msrc/stardis-solid-prog.c | 2+-
Msrc/stardis-solid-prog.h | 3++-
Msrc/stardis-solid.c | 4++--
Msrc/stardis-solid.h | 2+-
Msrc/stardis-ssconnect-prog.c | 2+-
Msrc/stardis-ssconnect-prog.h | 2+-
Msrc/stardis-ssconnect.c | 2+-
Msrc/stardis-ssconnect.h | 2+-
Msrc/stardis-tbound-prog.c | 2+-
Msrc/stardis-tbound-prog.h | 2+-
Msrc/stardis-tbound.c | 2+-
Msrc/stardis-tbound.h | 2+-
61 files changed, 866 insertions(+), 462 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# Copyright (C) 2018-2025 |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 @@ -68,31 +68,24 @@ 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 + @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f "$${i}"; done) stardis -$(DEP) $(OBJ): config.mk +stardis $(DEP) $(OBJ): config.mk stardis: $(OBJ) - $(CC) $(CFLAGS) $(DPDC_CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(DPDC_LIBS) + $(CC) $(CFLAGS) $(INCS) -o $@ $(OBJ) $(LDFLAGS) $(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 + if [ "$(DISTRIB_PARALLELISM)" = "MPI" ]; then \ + $(PKG_CONFIG) --atleast-version $(MPI_VERSION) $(MPI_PC); \ + fi + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d + $(PKG_CONFIG) --atleast-version $(SDIS_VERSION) sdis + $(PKG_CONFIG) --atleast-version $(SENC3D_VERSION) senc3d + $(PKG_CONFIG) --atleast-version $(SG3D_VERSION) sg3d + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SSTL_VERSION) sstl @echo "config done" > $@ src/stardis-default.h: config.mk src/stardis-default.h.in @@ -135,11 +128,11 @@ src/stardis-prog-properties.h: config.mk src/stardis-prog-properties.h.in .SUFFIXES: .c .d .o .c.d: - @$(CC) $(CFLAGS) $(DPDC_CFLAGS) $($(DISTRIB_PARALLELISM)_DEF) -MM -MT \ + @$(CC) $(CFLAGS) $(INCS) $($(DISTRIB_PARALLELISM)_DEF) -MM -MT \ "$(@:.d=.o) $@" $< -MF $@ .c.o: - $(CC) $(CFLAGS) $(DPDC_CFLAGS) $($(DISTRIB_PARALLELISM)_DEF) -c $< -o $@ + $(CC) $(CFLAGS) $(INCS) $($(DISTRIB_PARALLELISM)_DEF) -c $< -o $@ ################################################################################ # Man pages @@ -176,35 +169,40 @@ pkg: stardis.pc.in > stardis.pc install: all pkg - @$(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)/lib/pkgconfig" stardis.pc - @$(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 + install() { mode="$$1"; prefix="$$2"; shift 2; \ + mkdir -p "$${prefix}"; \ + cp "$$@" "$${prefix}"; \ + for i in "$$@"; do \ + chmod "$${mode}" "$${prefix}/$$(basename "$${i}")";\ + done; \ + }; \ + install 755 "$(DESTDIR)$(BINPREFIX)" stardis; \ + install 644 "$(DESTDIR)$(INCPREFIX)/stardis" src/stardis-green-types.h; \ + install 644 "$(DESTDIR)$(INCPREFIX)/stardis" src/stardis-prog-properties.h; \ + install 644 "$(DESTDIR)$(LIBPREFIX)/pkgconfig" stardis.pc; \ + install 644 "$(DESTDIR)$(PREFIX)/share/doc/stardis" COPYING README.md; \ + install 644 "$(DESTDIR)$(MANPREFIX)/man1" doc/stardis.1; \ + install 644 "$(DESTDIR)$(MANPREFIX)/man5" doc/stardis-input.5; \ + install 644 "$(DESTDIR)$(MANPREFIX)/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)/lib/pkgconfig/stardis.pc" + rm -f "$(DESTDIR)$(BINPREFIX)/stardis" + rm -f "$(DESTDIR)$(INCPREFIX)/stardis/stardis-green-types.h" + rm -f "$(DESTDIR)$(INCPREFIX)/stardis/stardis-prog-properties.h" + rm -f "$(DESTDIR)$(LIBPREFIX)/pkgconfig/stardis.pc" 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" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/stardis.1" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/stardis-input.5" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/stardis-output.5" ################################################################################ # Miscellaneous targets ################################################################################ clean: rm -f $(HDR) $(OBJ) .config stardis stardis.pc - rm -f doc/stardis.1 doc/stardis-input.5 - -distclean: clean rm -f $(DEP) + rm -f doc/stardis.1 doc/stardis-input.5 lint: man shellcheck -o all make.sh diff --git a/README.md b/README.md @@ -33,6 +33,41 @@ Edit config.mk as needed, then run: ## Release notes +### Version 0.12 + +- Add a new solid/fluid connection with imposed flux. + The new directives `F_SOLID_FLUID_CONNECTION` and + `F_SOLID_FLUID_CONNECTION_PROG` describe a connection between a solid + and a fluid with imposed flux at their common interface, the latter + using programmable properties. +- Add the `-f` and `-l` options to calculate the flux density for a + probe or a list of probes, respectively. +- Add the missing inclusion of the `limits.h` header to the programmable + properties file. + This is necessary in order to use the `UINT_MAX` constant. +- Partial correction of the calculation of a system's temperature range. + Only the temperature ranges of the connection conditions and boundary + conditions were used. + Now, programmable solids are also taken into account. + Regular solids and fluids should also be taken into account. + However, this more significant correction requires further review and + additional testing to ensure that the new method for calculating the + temperature range does not disrupt existing simulations. + Hence this limited correction, sufficient to verify that it corrects + the problem on the system that highlighted it, but not overly + optimistic as to what it corrects versus what it could deteriorate. +- Fix the `-L` option, which defines a list of surface probes to be + calculated. + It was not working correctly with a list containing only one probe. +- Fix the definition of solid properties. + The size and alignment of the allocated memory were incorrect. +- Fix an invalid memory access when handling errors in the analysis of + input files with variable expansion. +- Fix an invalid memory access when writing the green function. +- Small improvement of the build system. + Simplify it by doing everything in one place (the Makefile). + Add macros to control installation subdirectories + ### Version 0.11.1 - Corrects the writing of the RNG state when resolving a probe @@ -334,7 +369,7 @@ parameters: ## License -Copyright (C) 2018-2024 |Méso|Star> (<contact@meso-star.com>) +Copyright (C) 2018-2025 |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 diff --git a/config.mk b/config.mk @@ -1,6 +1,6 @@ VERSION_MAJOR = 0 -VERSION_MINOR = 11 -VERSION_PATCH = 1 +VERSION_MINOR = 12 +VERSION_PATCH = 0 VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) PREFIX = /usr/local @@ -13,6 +13,11 @@ LIB_TYPE = SHARED BUILD_TYPE = RELEASE #BUILD_TYPE = DEBUG +BINPREFIX = $(PREFIX)/bin +LIBPREFIX = $(PREFIX)/lib +INCPREFIX = $(PREFIX)/include +MANPREFIX = $(PREFIX)/share/man + # Defines whether distributed parallelism is supported. Any value other # than MPI disables its supports. So, simply comment the macro to # deactivate it. @@ -63,56 +68,18 @@ 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.16 -SDIS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sdis) -SDIS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sdis) - SENC3D_VERSION = 0.7.2 -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 + +INCS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags\ + rsys s3d sdis senc3d sg3d star-sp sstl $($(DISTRIB_PARALLELISM)_PC)) +LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs\ + rsys s3d sdis senc3d sg3d star-sp sstl $($(DISTRIB_PARALLELISM)_PC)) -lm ################################################################################ # Compilation options diff --git a/doc/stardis-input.5.in b/doc/stardis-input.5.in @@ -1,4 +1,4 @@ -.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2018-2025 |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 @@ -185,8 +185,11 @@ that changes at .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Ss Connection .Bl -column (description-line) (::) () -.It Ao Va connection Ac Ta ::= Ta Ao Va solid-fluid Ac | Ao Va solid-solid Ac +.It Ao Va connection Ac Ta ::= Ta Ao Va solid-fluid Ac +.It Ta \& \& | Ta Ao Va solid-solid Ac +.It Ta \& \& | Ta Ao Va solid-fluid-flux Ac .It \ Ta Ta +.\" Solid/fluid connection .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 @@ -194,12 +197,22 @@ that changes at .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 +.\" Solid/solid connection .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 +.\" Solid/fluid connection with flux +.It Ao Va solid-fluid-flux Ac Ta :: Ta Ao Va sf-flux-const Ac | Ao Va s-flux-prog Ac +.It Ao Va sf-flux-const Ac Ta :: Ta Li F_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 flux Ac Ao Va triangles Ac ... +.It Ao Va sf-flux-prog Ac Ta :: Ta Li F_SOLID_FLUID_CONNECTION_PROG \e +.It Ta Ta Ao Va connect-name Ac Ao Va prog-desc Ac +.It \ Ta Ta +.\" Miscellaneous .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] diff --git a/doc/stardis-output.5 b/doc/stardis-output.5 @@ -1,4 +1,4 @@ -.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2018-2025 |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 @@ -112,6 +112,7 @@ or an extended format that mixes numbers and their descriptions .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 +.It Ta \& \& | Ta Ao Va flux-density Ac # Option Fl f .It \ Ta Ta .\" Probe temperature .It Ao Va probe-temp Ac Ta ::= Ta Ao Va probe-temp-raw Ac | Ao Va probe-temp-ext Ac @@ -133,8 +134,11 @@ or an extended format that mixes numbers and their descriptions .It \ Ta Ta .\" Mean flux .It Ao Va mean-flux Ac Ta ::= Ta Ao Va mean-flux-raw Ac | Ao Va mean-flux-ext Ac +.It Ao Va flux-density Ac Ta ::= Ta Ao Va flux-density-raw Ac | Ao Va flux-density-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 flux-density-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 @@ -146,11 +150,23 @@ or an extended format that mixes numbers and their descriptions .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 +.It Ao Va flux-density-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 +.It Ta Ta Li Convective flux density at Ao Va position Ac Ao Va time Ac \e +.It Ta Ta Ao Va estimate-f-dsity-ext Ac +.It Ta Ta Li Radiative flux density at Ao Va position Ac Ao Va time Ac \e +.It Ta Ta Ao Va estimate-f-dsity-ext Ac +.It Ta Ta Li Imposed flux density at Ao Va position Ac Ao Va time Ac \e +.It Ta Ta Ao Va estimate-f-dsity-ext Ac +.It Ta Ta Li Total flux density at Ao Va position Ac Ao Va time Ac \e +.It Ta Ta Ao Va estimate-f-dsity-ext Ac +.It Ta Ta Ao Va failures-ext Ac .It \ Ta Ta .\" Miscellaneous .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 estimate-f-dsity-ext Ac Ta ::= Ta Ao Va expected-value Ac Li W/m² +/- 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 .It \ Ta Ta diff --git a/doc/stardis.1.in b/doc/stardis.1.in @@ -1,4 +1,4 @@ -.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2018-2025 |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,9 +27,11 @@ .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 f Ar x , Ns Ar y , Ns Ar z 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 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 @@ -180,6 +182,9 @@ and possibly followed by .Ql _err for failure paths .Pq e.g. Pa prefix00000000.vtk , Pa prefix00000001_err.vtk +.Pp +Can only be used in conjunction with some options that sample heat paths +.Pq Fl m , Fl p , Fl P , Fl R, Fl s No or Fl S . .It Fl d Ar file_base_name Write the geometry to a file in VTK format along with various properties, including possible errors. @@ -199,14 +204,21 @@ 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. +Compute the flux through a given 2D surface at a given time, the surface being +defined by the triangles in a STL file. +The flux can only be computed on a solid-fluid interface and is accounted +positive from the solid to the fluid. 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 f Ar x , Ns Ar y , Ns Ar z Ns Op , Ns Ar time Ns Op , Ns Ar time +Compute the flux density at a given probe on an interface at a given 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 flux density can only be computed on a solid-fluid interface and is +accounted positive from the solid to the fluid. +The probe coordinates must be in the same system as the geometry. +By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. .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 @@ -258,6 +270,22 @@ 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 l Pa interface_probes +Defines a set of interface probes for which +.Nm +calculates the flux density. +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 f No option . +In addition to this syntax, characters behind the hash mark +.Pq Ql # +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 +This option allows the calculation of the probe list while reading and +constructing the system only once. .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. diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -321,14 +321,16 @@ stardis_init ERR(str_set(&stardis->dump_model_filename, args->dump_model_filename)); } - if(args->mode & MODE_IR_COMPUTE) { + if(args->mode & MODE_COMPUTE_IMAGE_IR) { ERR(parse_camera(stardis->logger, args->camera, stardis)); } - else if(args->mode & MODE_MEDIUM_COMPUTE) { + else if(args->mode & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM) { 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)) { + else if((args->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF) + || (args->mode & MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF) + || (args->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF) + || (args->mode & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF)) { ERR(darray_probe_boundary_copy (&stardis->probe_boundary_list, &args->probe_boundary_list)); } @@ -493,7 +495,7 @@ stardis_init } /* If computation is on a volume, check medium is known */ - if(args->mode & MODE_MEDIUM_COMPUTE) { + if(args->mode & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM) { 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)); diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-args.c b/src/stardis-args.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -112,20 +112,22 @@ mode_option(const int m) 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_COMPUTE_FLUX_THROUGH_SURF) { found++; res = 'F'; } + if(m & MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF) { found++; res = 'f'; } + if(m & MODE_GREEN_ASCII) { found++; res = 'g'; } + if(m & MODE_GREEN_BIN) { 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'; } - if(m & MODE_IR_COMPUTE) { found++; res = 'R'; } - if(m & MODE_BOUNDARY_COMPUTE) { found++; res = 's'; } - if(m & MODE_MAP_COMPUTE) { found++; res = 'S'; } + if(m & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF) { found++; res = 'L'; } + if(m & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF) { found++; res = 'l'; } + if(m & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM) { found++; res = 'm'; } + if(m & MODE_COMPUTE_PROBE_TEMP_ON_VOL) { found++; res = 'p'; } + if(m & MODE_COMPUTE_PROBE_TEMP_ON_SURF) { found++; res = 'P'; } + if(m & MODE_COMPUTE_IMAGE_IR) { found++; res = 'R'; } + if(m & MODE_COMPUTE_TEMP_MEAN_ON_SURF) { found++; res = 's'; } + if(m & MODE_COMPUTE_TEMP_MAP_ON_SURF) { found++; res = 'S'; } if(m & MODE_VERBOSITY) { found++; res = 'V'; } if(m & MODE_DUMP_VERSION) { found++; res = 'v'; } - ASSERT(found == 1); + ASSERT(found == 1);(void)found; return res; } @@ -267,7 +269,10 @@ error: } static res_T -parse_probe_boundary(const char* str, struct stardis_probe_boundary* probe) +parse_probe_boundary + (const char* str, + int with_sides, + struct stardis_probe_boundary* probe) { char buf[128]; char* pos_and_time = NULL; @@ -285,12 +290,12 @@ parse_probe_boundary(const char* str, struct stardis_probe_boundary* probe) strncpy(buf, str, sizeof(buf)); pos_and_time = strtok_r(buf, ":", &ctx); - side = strtok_r(NULL, "", &ctx); + if(with_sides) 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) { + if(with_sides && side) { res = parse_side_indicator(side, probe->side); if(res != RES_OK) goto error; } @@ -333,6 +338,7 @@ parse_probe_boundary_list (const char* filename, struct logger* logger, struct mem_allocator* allocator, + int with_sides, struct darray_probe_boundary* list) { struct txtrdr* txtrdr = NULL; @@ -357,7 +363,7 @@ parse_probe_boundary_list if(!(line = txtrdr_get_cline(txtrdr))) goto exit; /* No line to parse */ - res = parse_probe_boundary(line, &probe); + res = parse_probe_boundary(line, with_sides, &probe); if(res != RES_OK) goto error; res = darray_probe_boundary_push_back(list, &probe); @@ -416,7 +422,7 @@ init_args struct args* args = NULL; ASSERT(logger && allocator && out_args); - args = calloc(sizeof(struct args), 1); + args = calloc(1, sizeof(struct args)); if(!args) { res = RES_MEM_ERR; goto error; @@ -459,10 +465,10 @@ usage(FILE* stream) #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(" [-f x,y,z[,time[,time]]] [-G green_bin[,green_ascii]]\n"); + PRINT(" [-I initial_time] [-L interface_probes] [-l interface_probes]\n"); + PRINT(" [-m medium_name[,time[,time]]] [-n samples_count]\n"); + PRINT(" [-o picard_order] [-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"); @@ -525,7 +531,7 @@ parse_args { int opt = 0, n_used = 0, o_used = 0; size_t len = 0; - 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:"; + const char option_list[] = "a:c:d:D:ef:F:gG:hiI:L:l:m:M:n:o:p:P:R:s:S:t:vV:x:X:"; char buf[128]; struct str keep; char** line = NULL; @@ -609,36 +615,55 @@ parse_args args->mode |= MODE_EXTENDED_RESULTS; break; + case 'f': + { + struct stardis_probe_boundary* probe = NULL; + + if(args->mode & EXCLUSIVE_MODES) { + logger_print(args->logger, LOG_ERROR, + "Options -%c and -%c are exclusive.\n", + (char)opt, mode_option(args->mode)); + res = RES_BAD_ARG; + goto error; + } + args->mode |= MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF; + res = allocate_probe_boundary(args, &probe); + if(res != RES_OK) goto error; + res = parse_probe_boundary(optarg, 0, probe); + if(res != RES_OK) goto error; + break; + } + /*case 'F': see 's' */ case 'g': - if(args->mode & MODE_BIN_GREEN) { + if(args->mode & MODE_GREEN_BIN) { res = RES_BAD_ARG; logger_print(args->logger, LOG_ERROR, "Options -%c and -%c are exclusive.\n", - (char)opt, mode_option(MODE_BIN_GREEN)); + (char)opt, mode_option(MODE_GREEN_BIN)); goto error; } - args->mode |= MODE_GREEN; + args->mode |= MODE_GREEN_ASCII; break; case 'G': { char* ptr = strrchr(optarg, ','); if(ptr && ptr != strchr(optarg, ',')) res = RES_BAD_ARG; /* Expecting 1 or 0 ',' */ - if(args->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { res = RES_BAD_ARG; - if(args->mode & MODE_BIN_GREEN) + if(args->mode & MODE_GREEN_BIN) logger_print(args->logger, LOG_ERROR, "Option -%c cannot be used twice.\n", (char)opt); else logger_print(args->logger, LOG_ERROR, "Options -%c and -%c are exclusive.\n", - (char)opt, mode_option(MODE_GREEN)); + (char)opt, mode_option(MODE_GREEN_ASCII)); goto error; } - args->mode |= MODE_BIN_GREEN; + args->mode |= MODE_GREEN_BIN; if(ptr) { args->end_paths_filename = ptr + 1; *ptr = '\0'; @@ -675,9 +700,22 @@ parse_args (char)opt, mode_option(args->mode)); goto error; } - args->mode |= MODE_PROBE_LIST_COMPUTE_ON_INTERFACE; + args->mode |= MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF; + res = parse_probe_boundary_list + (optarg, args->logger, args->allocator, 1, &args->probe_boundary_list); + if(res != RES_OK) goto error; + 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_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF; res = parse_probe_boundary_list - (optarg, args->logger, args->allocator, &args->probe_boundary_list); + (optarg, args->logger, args->allocator, 0, &args->probe_boundary_list); if(res != RES_OK) goto error; break; @@ -690,7 +728,7 @@ parse_args (char)opt, mode_option(args->mode)); goto error; } - args->mode |= MODE_MEDIUM_COMPUTE; + args->mode |= MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM; GET_STR_AND_OPTIONAL_TIME_RANGE(args->medium_name, args->pos_and_time + 3); break; } @@ -745,7 +783,7 @@ parse_args (char)opt, mode_option(args->mode)); goto error; } - args->mode |= MODE_PROBE_COMPUTE; + args->mode |= MODE_COMPUTE_PROBE_TEMP_ON_VOL; GET_POS_AND_OPTIONAL_TIME_RANGE(optarg, args->pos_and_time, optarg); break; @@ -759,10 +797,10 @@ parse_args res = RES_BAD_ARG; goto error; } - args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE; + args->mode |= MODE_COMPUTE_PROBE_TEMP_ON_SURF; res = allocate_probe_boundary(args, &probe); if(res != RES_OK) goto error; - res = parse_probe_boundary(optarg, probe); + res = parse_probe_boundary(optarg, 1, probe); if(res != RES_OK) goto error; break; } @@ -775,7 +813,7 @@ parse_args (char)opt, mode_option(args->mode)); goto error; } - args->mode |= MODE_IR_COMPUTE; + args->mode |= MODE_COMPUTE_IMAGE_IR; args->camera = optarg; break; @@ -792,13 +830,13 @@ parse_args } switch (opt) { case 's': - args->mode |= MODE_BOUNDARY_COMPUTE; + args->mode |= MODE_COMPUTE_TEMP_MEAN_ON_SURF; break; case 'S': - args->mode |= MODE_MAP_COMPUTE; + args->mode |= MODE_COMPUTE_TEMP_MAP_ON_SURF; break; case 'F': - args->mode |= MODE_FLUX_BOUNDARY_COMPUTE; + args->mode |= MODE_COMPUTE_FLUX_THROUGH_SURF; break; } GET_STR_AND_OPTIONAL_TIME_RANGE(args->solve_filename, args->pos_and_time + 3); @@ -900,29 +938,29 @@ parse_args goto error; } - if(args->mode & (MODE_BIN_GREEN | MODE_GREEN) + if(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII) && !(args->mode & GREEN_COMPATIBLE_MODES)) { print_multiple_modes(buf, sizeof(buf), GREEN_COMPATIBLE_MODES, 0); logger_print(args->logger, LOG_ERROR, "Option -%c can only be used in conjunction with: %s\n", - mode_option(args->mode & (MODE_BIN_GREEN | MODE_GREEN)), buf); + mode_option(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)), buf); res = RES_BAD_ARG; goto error; } - if(args->mode & (MODE_BIN_GREEN | MODE_GREEN) + if(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII) && o_used && args->picard_order > 1) { logger_print(args->logger, LOG_ERROR, "Option -%c cannot be used if Picard order is not 1 (here order is %u)\n", - mode_option(args->mode & (MODE_BIN_GREEN | MODE_GREEN)), + mode_option(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)), args->picard_order); res = RES_BAD_ARG; goto error; } - if(args->mode & MODE_IR_COMPUTE && n_used) { + if(args->mode & MODE_COMPUTE_IMAGE_IR && n_used) { logger_print(args->logger, LOG_ERROR, "The -n option has no effect in rendering mode;" " use rendering's SPP suboption instead.\n"); @@ -931,21 +969,21 @@ parse_args } if(args->mode & MODE_DUMP_PATHS) { - if(!(args->mode & COMPUTE_MODES)) { + if(!(args->mode & CAN_DUMP_PATHS)) { res = RES_BAD_ARG; - print_multiple_modes(buf, sizeof(buf), COMPUTE_MODES, 0); + print_multiple_modes(buf, sizeof(buf), CAN_DUMP_PATHS, 0); logger_print(args->logger, LOG_ERROR, - "Option -%c can only be used in conjunction with an option" - " that samples heat paths (%s).\n", + "Option -%c can only be used in conjunction with some options" + " that sample heat paths (%s).\n", mode_option(MODE_DUMP_PATHS), buf); goto error; } - if(args->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { res = RES_BAD_ARG; logger_print(args->logger, LOG_ERROR, "Option -%c cannot be used in conjunction with -%c nor -%c.\n", - mode_option(MODE_DUMP_PATHS), mode_option(MODE_GREEN) - , mode_option(MODE_BIN_GREEN)); + mode_option(MODE_DUMP_PATHS), mode_option(MODE_GREEN_ASCII) + , mode_option(MODE_GREEN_BIN)); goto error; } } @@ -960,12 +998,12 @@ parse_args mode_option(MODE_EXTENDED_RESULTS), buf); goto error; } - if(args->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(args->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { res = RES_BAD_ARG; logger_print(args->logger, LOG_ERROR, "Option -%c cannot be used in conjunction with -%c nor -%c.\n", - mode_option(MODE_EXTENDED_RESULTS), mode_option(MODE_GREEN) - , mode_option(MODE_BIN_GREEN)); + mode_option(MODE_EXTENDED_RESULTS), mode_option(MODE_GREEN_ASCII) + , mode_option(MODE_GREEN_BIN)); goto error; } } diff --git a/src/stardis-args.h.in b/src/stardis-args.h.in @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -49,45 +49,50 @@ enum stardis_mode { 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 */ + MODE_COMPUTE_FLUX_THROUGH_SURF= BIT(4), /* -F */ + MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF = BIT(5), /* -f */ + MODE_GREEN_BIN = BIT(6), /* -G */ + MODE_GREEN_ASCII = BIT(7), /* -g */ + MODE_DUMP_HELP = BIT(8), /* -h */ + MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF = BIT(9), /* -L */ + MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF = BIT(10), /* -l */ + MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM = BIT(11), /* -m */ + MODE_COMPUTE_PROBE_TEMP_ON_SURF = BIT(12), /* -P */ + MODE_COMPUTE_PROBE_TEMP_ON_VOL = BIT(13), /* -p */ + MODE_COMPUTE_IMAGE_IR = BIT(14), /* -R */ + MODE_COMPUTE_TEMP_MAP_ON_SURF = BIT(15), /* -S */ + MODE_COMPUTE_TEMP_MEAN_ON_SURF = BIT(16), /* -s */ + MODE_VERBOSITY = BIT(17), /* -V */ + MODE_DUMP_VERSION = BIT(18), /* -v */ GREEN_COMPATIBLE_MODES = - MODE_PROBE_COMPUTE - | MODE_PROBE_COMPUTE_ON_INTERFACE - | MODE_MEDIUM_COMPUTE - | MODE_BOUNDARY_COMPUTE, + MODE_COMPUTE_PROBE_TEMP_ON_VOL + | MODE_COMPUTE_PROBE_TEMP_ON_SURF + | MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM + | MODE_COMPUTE_TEMP_MEAN_ON_SURF, SURFACE_COMPUTE_MODES = - MODE_BOUNDARY_COMPUTE - | MODE_FLUX_BOUNDARY_COMPUTE - | MODE_MAP_COMPUTE, + MODE_COMPUTE_TEMP_MEAN_ON_SURF + | MODE_COMPUTE_FLUX_THROUGH_SURF + | MODE_COMPUTE_TEMP_MAP_ON_SURF, EXT_COMPATIBLE_MODES = GREEN_COMPATIBLE_MODES - | MODE_MEDIUM_COMPUTE - | MODE_FLUX_BOUNDARY_COMPUTE, + | MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM + | MODE_COMPUTE_FLUX_THROUGH_SURF + | MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF, REGION_COMPUTE_MODES = SURFACE_COMPUTE_MODES - | MODE_MEDIUM_COMPUTE, + | MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM, COMPUTE_MODES = GREEN_COMPATIBLE_MODES - | MODE_IR_COMPUTE + | MODE_COMPUTE_IMAGE_IR | SURFACE_COMPUTE_MODES - | MODE_PROBE_LIST_COMPUTE_ON_INTERFACE, + | MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF + | MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF + | MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF, EXCLUSIVE_MODES = COMPUTE_MODES, @@ -99,16 +104,26 @@ enum stardis_mode { MODE_DUMP_C_CHUNKS | MODE_DUMP_HELP | MODE_DUMP_VERSION - | MODE_IR_COMPUTE - | MODE_GREEN, + | MODE_COMPUTE_IMAGE_IR + | MODE_GREEN_ASCII, 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 + MODE_COMPUTE_PROBE_TEMP_ON_VOL + | MODE_COMPUTE_PROBE_TEMP_ON_SURF + | MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF + | MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF + | MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM + | MODE_COMPUTE_TEMP_MEAN_ON_SURF + | MODE_COMPUTE_FLUX_THROUGH_SURF + | MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF, + + CAN_DUMP_PATHS = + MODE_COMPUTE_PROBE_TEMP_ON_VOL | + MODE_COMPUTE_IMAGE_IR | + MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM | + MODE_COMPUTE_TEMP_MEAN_ON_SURF | + MODE_COMPUTE_TEMP_MAP_ON_SURF | + MODE_COMPUTE_PROBE_TEMP_ON_SURF }; STATIC_ASSERT(GREEN_COMPATIBLE_MODES == (COMPUTE_MODES & GREEN_COMPATIBLE_MODES), diff --git a/src/stardis-compute-probe-boundary.c b/src/stardis-compute-probe-boundary.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -235,7 +235,8 @@ check_move_to_solid_boundary 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 */ + const double distance, /* Move distance */ + const int advice) { struct stardis_vertex vtx = STARDIS_VERTEX_NULL; const char* prefix = ""; @@ -261,7 +262,7 @@ check_move_to_solid_boundary vtx.P[2] = pos[2]; vtx.time = time; delta = desc->d.solid_prog->delta(&vtx, desc->d.solid_prog->prog_data); - prefix = "programmed"; + prefix = "programmed "; break; default: FATAL("Unreachable code.\n"); @@ -271,7 +272,7 @@ check_move_to_solid_boundary logger_print(stardis->logger, LOG_OUTPUT, "Probe was in %ssolid '%s'.\n", prefix, solid_name); - /* The position is closed from the triangle */ + /* The position is close from the triangle */ if(distance < 0.5*delta) { logger_print(stardis->logger, LOG_OUTPUT, "Probe was %g delta from closest boundary.\n", @@ -280,9 +281,9 @@ check_move_to_solid_boundary /* 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); + "Probe was %g delta from closest boundary.%s\n", + distance/delta, + (advice ? " Consider using -p instead of -P.\n" : "")); /* The position is too far from the triangle */ } else { @@ -316,7 +317,7 @@ check_move_to_fluid_boundary switch(desc->type) { case DESC_MAT_FLUID: prefix = ""; break; - case DESC_MAT_FLUID_PROG: prefix = "programmed"; break; + case DESC_MAT_FLUID_PROG: prefix = "programmed "; break; default: FATAL("Unreachable code.\n"); } @@ -334,6 +335,7 @@ move_to_boundary (struct stardis* stardis, const double pos[3], const double time, /* [s] */ + const int is_probe_temp_computation, size_t* out_iprim, double uv[2]) { @@ -342,7 +344,6 @@ move_to_boundary double proj_pos[3] = {0,0,0}; size_t iprim = 0; - /* Miscellaneous */ size_t nvertices_close = 0; res_T res = RES_OK; @@ -376,7 +377,8 @@ move_to_boundary case DESC_MAT_SOLID: case DESC_MAT_SOLID_PROG: ERR(check_move_to_solid_boundary - (stardis, pos, time, desc, iprim, uv, filter_ctx.distance)); + (stardis, pos, time, desc, iprim, uv, filter_ctx.distance, + is_probe_temp_computation)); break; case DESC_MAT_FLUID: case DESC_MAT_FLUID_PROG: @@ -734,6 +736,84 @@ error: } static res_T +setup_solve_probe_boundary_flux_args + (struct stardis* stardis, + const struct stardis_probe_boundary* probe, + struct sdis_solve_probe_boundary_flux_args* args) +{ + 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], 0, &iprim, uv)); + + ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, + (unsigned)iprim, desc_ids)); + + d3_set(stardis->probe, probe->position); + /* Setup of solve input parameters */ + + args->nrealisations = stardis->samples; + args->iprim = iprim; + d2_set(args->uv, uv); + args->picard_order = stardis->picard_order; + d2_set(args->time_range, stardis->time_range); + args->diff_algo = stardis->diff_algo; + +exit: + return res; +error: + goto exit; +} + +static res_T +solve_flux_list + (struct stardis* stardis, + struct time* start, + const struct stardis_probe_boundary* probes, + size_t nprobes) +{ + struct time t0, t1; + struct sdis_mc time = SDIS_MC_NULL; /* Time per realisation */ + struct sdis_estimator_buffer* buffer = NULL; + size_t i = 0; + struct sdis_estimator* estimator = NULL; + FILE* stream_r = NULL; + struct sdis_solve_probe_boundary_flux_args args; + res_T res = RES_OK; + ASSERT(stardis && start); + + /* Input random state? */ + READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); + + time_current(&t0); + for(i = 0; i < nprobes; i++) { + args = SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT; + ERR(setup_solve_probe_boundary_flux_args(stardis, &probes[i], &args)); + /* Run the calculation */ + ERR(sdis_solve_probe_boundary_flux(stardis->sdis_scn, &args, &estimator)); + /* Print the estimated temperature */ + ERR(print_single_MC_result(estimator, stardis, stdout)); + ERR(sdis_estimator_ref_put(estimator)); + } + time_current(&t1); + + /* Output random state? */ + WRITE_RANDOM_STATE(&stardis->rndgen_state_out_filename); + + ERR(print_computation_time(&time, stardis, start, &t0, &t1, NULL)); + +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, @@ -762,7 +842,7 @@ solve_green } /* Try to open output files to detect errors early */ - if(is_master_process && (stardis->mode & MODE_BIN_GREEN)) { + if(is_master_process && (stardis->mode & MODE_GREEN_BIN)) { const char* green_filename = str_cget(&stardis->bin_green_filename); const char* path_filename = str_cget(&stardis->end_paths_filename); @@ -792,12 +872,12 @@ solve_green if(is_master_process) goto exit; /* Write ASCII Green */ - if(stardis->mode & MODE_GREEN) { + if(stardis->mode & MODE_GREEN_ASCII) { ERR(dump_green_ascii(green, stardis, stdout)); } /* Write binary Green */ - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { ERR(dump_green_bin(green, stardis, fp_green)); if(fp_path) { ERR(dump_paths_end(green, stardis, fp_path)); @@ -826,6 +906,53 @@ error: } static res_T +compute_single_flux_probe_on_interface + (struct stardis* stardis, + struct time* start, + const struct stardis_probe_boundary* probe) +{ + res_T res = RES_OK; + struct sdis_green_function* green = NULL; + struct sdis_estimator* estimator = NULL; + struct sdis_solve_probe_boundary_flux_args args + = SDIS_SOLVE_PROBE_BOUNDARY_FLUX_ARGS_DEFAULT; + FILE* stream_r = NULL; + struct time compute_start, compute_end; + + ASSERT(stardis && start && probe); + + ERR(setup_solve_probe_boundary_flux_args(stardis, probe, &args)); + + /* Input random state? */ + READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); + + if(stardis->mpi_initialized && stardis->mpi_rank != 0) { + ERR(sdis_solve_probe_boundary_flux(stardis->sdis_scn, &args, &estimator)); + } else { + struct sdis_mc time = SDIS_MC_NULL; + time_current(&compute_start); + ERR(sdis_solve_probe_boundary_flux(stardis->sdis_scn, &args, &estimator)); + time_current(&compute_end); + ERR(sdis_estimator_get_realisation_time(estimator, &time)); + ERR(print_computation_time + (&time, stardis, start, &compute_start, &compute_end, NULL)); + + ERR(print_single_MC_result(estimator, stardis, stdout)); + } + + /* Output random state? */ + WRITE_RANDOM_STATE(&stardis->rndgen_state_out_filename); + +end: + 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 setup_solve_probe_boundary_args (struct stardis* stardis, const struct stardis_probe_boundary* probe, @@ -836,10 +963,10 @@ setup_solve_probe_boundary_args size_t iprim = SIZE_MAX; unsigned desc_ids[SG3D_PROP_TYPES_COUNT__]; res_T res = RES_OK; - ASSERT(stardis && probe && args); + ASSERT(stardis && probe && args && (stardis->mode && MODE_COMPUTE_TEMP_MAP_ON_SURF)); /* Calculate the probe position on the boundary */ - ERR(move_to_boundary(stardis, probe->position, probe->time[0], &iprim, uv)); + ERR(move_to_boundary(stardis, probe->position, probe->time[0], 1, &iprim, uv)); ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, (unsigned)iprim, desc_ids)); @@ -888,7 +1015,7 @@ compute_single_probe_on_interface ERR(setup_solve_probe_boundary_args(stardis, probe, &args)); /* Run the calculation */ - if(stardis->mode & (MODE_GREEN | MODE_BIN_GREEN)) { + if(stardis->mode & (MODE_GREEN_ASCII | MODE_GREEN_BIN)) { ERR(solve_green(stardis, start, &args)); } else { ERR(solve(stardis, start, &args, output_status)); @@ -953,32 +1080,65 @@ error: goto exit; } +static res_T +compute_multiple_flux_probes_on_interface + (struct stardis* stardis, + struct time* start) +{ + /* Probes */ + const struct stardis_probe_boundary* probes = NULL; + size_t nprobes = 0; + res_T res = RES_OK; + 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); + + /* Run calculations */ + ERR(solve_flux_list(stardis, start, probes, nprobes)); + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ res_T compute_probe_on_interface(struct stardis* stardis, struct time* start) { + int temp_flags = MODE_COMPUTE_PROBE_TEMP_ON_SURF + | MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF; + int flux_flags = MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF + | MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF; 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); + ASSERT((stardis->mode & temp_flags) != (stardis->mode & flux_flags)); /* xor */ - 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; + if(stardis->mode & temp_flags) { + if(darray_probe_boundary_size_get(&stardis->probe_boundary_list) > 1) { + res = compute_multiple_probes_on_interface(stardis, start); + if(res != RES_OK) goto error; + } else { + const struct stardis_probe_boundary* 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; + } + } else if(stardis->mode & flux_flags) { + if(darray_probe_boundary_size_get(&stardis->probe_boundary_list) > 1) { + res = compute_multiple_flux_probes_on_interface(stardis, start); + if(res != RES_OK) goto error; + } else { + const struct stardis_probe_boundary* probe + = darray_probe_boundary_cdata_get(&stardis->probe_boundary_list); + res = compute_single_flux_probe_on_interface(stardis, start, probe); + if(res != RES_OK) goto error; + } } exit: diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -333,50 +333,6 @@ error: goto end; } -#define READ_RANDOM_STATE(Name) \ - if(!stardis->mpi_initialized || stardis->mpi_rank == 0) { \ - if(str_is_empty(Name)) { \ - /* Force using threefry independently of the default RNG type */ \ - args.rng_type = SSP_RNG_THREEFRY; \ - } else { \ - const char* name = str_cget(Name); \ - stream_r = fopen(name, "r"); \ - if(!stream_r) { \ - res = RES_IO_ERR; \ - logger_print(stardis->logger, LOG_ERROR, \ - "Cannot open generator's state file ('%s').\n", \ - name); \ - goto error; \ - } \ - ERR(ssp_rng_create(stardis->allocator, SSP_RNG_THREEFRY, &args.rng_state)); \ - res = read_random_generator_state(args.rng_state, stream_r); \ - if(res != RES_OK) { \ - logger_print(stardis->logger, LOG_ERROR, \ - "Cannot read random generator's state ('%s').\n", \ - name); \ - goto error; \ - } \ - fclose(stream_r); stream_r = NULL; \ - } \ - } - -#define WRITE_RANDOM_STATE(Name) \ - if(!stardis->mpi_initialized || stardis->mpi_rank == 0) { \ - if(!str_is_empty(Name)) { \ - const char* name = str_cget(Name); \ - stream_r = fopen(name, "wb"); \ - if(!stream_r) { \ - res = RES_IO_ERR; \ - logger_print(stardis->logger, LOG_ERROR, \ - "Cannot write random generator's state ('%s').\n", \ - name); \ - goto error; \ - } \ - ERR(write_random_generator_state(estimator, stream_r)); \ - fclose(stream_r); stream_r = NULL; \ - } \ - } - static res_T compute_probe(struct stardis* stardis, struct time* start) { @@ -392,7 +348,7 @@ compute_probe(struct stardis* stardis, struct time* start) FILE* stream_p = NULL; struct time compute_start, compute_end; - ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE)); + ASSERT(stardis && start && (stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_VOL)); ERR(check_probe_conform_to_type(stardis, stardis->probe, stardis->time_range[0], &iprim, uv)); @@ -405,12 +361,12 @@ compute_probe(struct stardis* stardis, struct time* start) /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); - if(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_probe_green_function(stardis->sdis_scn, &args, &green)); } else { /* Try to open output files to detect errors early */ - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { ASSERT(!str_is_empty(&stardis->bin_green_filename)); stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { @@ -437,7 +393,7 @@ compute_probe(struct stardis* stardis, struct time* start) time_current(&compute_start); ERR(sdis_solve_probe_green_function(stardis->sdis_scn, &args, &green)); time_current(&compute_end); - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { struct time output_end; ERR(dump_green_bin(green, stardis, stream_g)); if(stream_p) { @@ -447,7 +403,7 @@ compute_probe(struct stardis* stardis, struct time* start) ERR(print_computation_time(NULL, stardis, start, &compute_start, &compute_end, &output_end)); } - if(stardis->mode & MODE_GREEN) { + if(stardis->mode & MODE_GREEN_ASCII) { ERR(dump_green_ascii(green, stardis, stdout)); } } @@ -585,8 +541,8 @@ compute_camera(struct stardis* stardis, struct time* start) struct time compute_start, compute_end, output_end; ASSERT(stardis && start - && !(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)) - && (stardis->mode & MODE_IR_COMPUTE)); + && !(stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) + && (stardis->mode & MODE_COMPUTE_IMAGE_IR)); width = (size_t)stardis->camera.img_width; height = (size_t)stardis->camera.img_height; @@ -683,7 +639,7 @@ compute_medium(struct stardis* stardis, struct time* start) FILE* stream_p = NULL; struct time compute_start, compute_end; - ASSERT(stardis && start && (stardis->mode & MODE_MEDIUM_COMPUTE)); + ASSERT(stardis && start && (stardis->mode & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM)); /* Find medium */ medium = find_medium_by_name(stardis, str_cget(&stardis->solve_name), NULL); @@ -703,12 +659,12 @@ compute_medium(struct stardis* stardis, struct time* start) /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); - if(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_medium_green_function(stardis->sdis_scn, &args, &green)); } else { /* Try to open output files to detect errors early */ - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { ASSERT(!str_is_empty(&stardis->bin_green_filename)); stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { @@ -735,7 +691,7 @@ compute_medium(struct stardis* stardis, struct time* start) time_current(&compute_start); ERR(sdis_solve_medium_green_function(stardis->sdis_scn, &args, &green)); time_current(&compute_end); - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { struct time output_end; ASSERT(!str_is_empty(&stardis->bin_green_filename)); ERR(dump_green_bin(green, stardis, stream_g)); @@ -746,7 +702,7 @@ compute_medium(struct stardis* stardis, struct time* start) ERR(print_computation_time(NULL, stardis, start, &compute_start, &compute_end, &output_end)); } - if(stardis->mode & MODE_GREEN) { + if(stardis->mode & MODE_GREEN_ASCII) { ERR(dump_green_ascii(green, stardis, stdout)); } } @@ -851,7 +807,7 @@ compute_boundary(struct stardis* stardis, struct time* start) FILE* stream_p = NULL; struct time compute_start, compute_end; - ASSERT(stardis && start && (stardis->mode & MODE_BOUNDARY_COMPUTE)); + ASSERT(stardis && start && (stardis->mode & MODE_COMPUTE_TEMP_MEAN_ON_SURF)); args.nrealisations = stardis->samples; args.primitives @@ -865,12 +821,12 @@ compute_boundary(struct stardis* stardis, struct time* start) /* Input random state? */ READ_RANDOM_STATE(&stardis->rndgen_state_in_filename); - if(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN)) { + if(stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII)) { if(stardis->mpi_initialized && stardis->mpi_rank != 0) { ERR(sdis_solve_boundary_green_function(stardis->sdis_scn, &args, &green)); } else { /* Try to open output files to detect errors early */ - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { ASSERT(!str_is_empty(&stardis->bin_green_filename)); stream_g = fopen(str_cget(&stardis->bin_green_filename), "wb"); if(!stream_g) { @@ -897,7 +853,7 @@ compute_boundary(struct stardis* stardis, struct time* start) time_current(&compute_start); ERR(sdis_solve_boundary_green_function(stardis->sdis_scn, &args, &green)); time_current(&compute_end); - if(stardis->mode & MODE_BIN_GREEN) { + if(stardis->mode & MODE_GREEN_BIN) { struct time output_end; ERR(dump_green_bin(green, stardis, stream_g)); if(stream_p) { @@ -907,7 +863,7 @@ compute_boundary(struct stardis* stardis, struct time* start) ERR(print_computation_time(NULL, stardis, start, &compute_start, &compute_end, &output_end)); } - if(stardis->mode & MODE_GREEN) { + if(stardis->mode & MODE_GREEN_ASCII) { ERR(dump_green_ascii(green, stardis, stdout)); } } @@ -962,7 +918,7 @@ compute_flux_boundary(struct stardis* stardis, struct time* start) FILE* stream_r = NULL; struct time compute_start, compute_end; - ASSERT(stardis && start && (stardis->mode & MODE_FLUX_BOUNDARY_COMPUTE)); + ASSERT(stardis && start && (stardis->mode & MODE_COMPUTE_FLUX_THROUGH_SURF)); args.nrealisations = stardis->samples; args.primitives @@ -1021,8 +977,8 @@ compute_map(struct stardis* stardis, struct time* start) (void)start; ASSERT(stardis && start - && (stardis->mode & MODE_MAP_COMPUTE) - && !(stardis->mode & (MODE_BIN_GREEN | MODE_GREEN))); + && (stardis->mode & MODE_COMPUTE_TEMP_MAP_ON_SURF) + && !(stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII))); darray_estimators_init(stardis->allocator, &estimators); estimators_initialized = 1; @@ -1065,9 +1021,6 @@ error: goto end; } -#undef READ_RANDOM_STATE -#undef WRITE_RANDOM_STATE - /******************************************************************************* * Public Functions ******************************************************************************/ @@ -1182,23 +1135,29 @@ stardis_compute ASSERT(stardis && start && (stardis->mode & COMPUTE_MODES)); /* Compute */ - if(stardis->mode & MODE_PROBE_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) - ERR(compute_medium(stardis, start)); - else if(stardis->mode & MODE_BOUNDARY_COMPUTE) - ERR(compute_boundary(stardis, start)); - else if(stardis->mode & MODE_FLUX_BOUNDARY_COMPUTE) - ERR(compute_flux_boundary(stardis, start)); - else if(stardis->mode & MODE_MAP_COMPUTE) - ERR(compute_map(stardis, start)); - else FATAL("Unknown mode.\n"); + if(stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_VOL) { + ERR(compute_probe(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF) { + ERR(compute_probe_on_interface(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF) { + ERR(compute_probe_on_interface(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF) { + ERR(compute_probe_on_interface(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF) { + ERR(compute_probe_on_interface(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_IMAGE_IR) { + ERR(compute_camera(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM) { + ERR(compute_medium(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_TEMP_MEAN_ON_SURF) { + ERR(compute_boundary(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_FLUX_THROUGH_SURF) { + ERR(compute_flux_boundary(stardis, start)); + } else if(stardis->mode & MODE_COMPUTE_TEMP_MAP_ON_SURF) { + ERR(compute_map(stardis, start)); + } else { + FATAL("Unknown mode.\n"); + } end: return res; diff --git a/src/stardis-compute.h b/src/stardis-compute.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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,6 +27,50 @@ struct str; #define DARRAY_DATA struct sdis_estimator* #include <rsys/dynamic_array.h> +#define READ_RANDOM_STATE(Name) \ + if(!stardis->mpi_initialized || stardis->mpi_rank == 0) { \ + if(str_is_empty(Name)) { \ + /* Force using threefry independently of the default RNG type */ \ + args.rng_type = SSP_RNG_THREEFRY; \ + } else { \ + const char* name = str_cget(Name); \ + stream_r = fopen(name, "r"); \ + if(!stream_r) { \ + res = RES_IO_ERR; \ + logger_print(stardis->logger, LOG_ERROR, \ + "Cannot open generator's state file ('%s').\n", \ + name); \ + goto error; \ + } \ + ERR(ssp_rng_create(stardis->allocator, SSP_RNG_THREEFRY, &args.rng_state)); \ + res = read_random_generator_state(args.rng_state, stream_r); \ + if(res != RES_OK) { \ + logger_print(stardis->logger, LOG_ERROR, \ + "Cannot read random generator's state ('%s').\n", \ + name); \ + goto error; \ + } \ + fclose(stream_r); stream_r = NULL; \ + } \ + } + +#define WRITE_RANDOM_STATE(Name) \ + if(!stardis->mpi_initialized || stardis->mpi_rank == 0) { \ + if(!str_is_empty(Name)) { \ + const char* name = str_cget(Name); \ + stream_r = fopen(name, "wb"); \ + if(!stream_r) { \ + res = RES_IO_ERR; \ + logger_print(stardis->logger, LOG_ERROR, \ + "Cannot write random generator's state ('%s').\n", \ + name); \ + goto error; \ + } \ + ERR(write_random_generator_state(estimator, stream_r)); \ + fclose(stream_r); stream_r = NULL; \ + } \ + } + extern LOCAL_SYM struct sdis_medium* find_medium_by_name (struct stardis* stardis, @@ -47,4 +91,9 @@ compute_probe_on_interface (struct stardis* stardis, struct time* start); +extern LOCAL_SYM res_T +compute_flux_density_boundary + (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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-extern-source.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-fbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-fbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-fluid-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-fluid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-hbound-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-hbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-hbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-hfbound.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-hfbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -650,9 +650,14 @@ create_intface interface_props->ref_temperature = intface->d.sf_connect->ref_temperature; interface_props->emissivity = intface->d.sf_connect->emissivity; interface_props->alpha = intface->d.sf_connect->specular_fraction; + interface_props->imposed_flux = intface->d.sf_connect->flux; if(intface->d.sf_connect->hc > 0) { interface_shader.convection_coef = interface_get_convection_coef; } + if(intface->d.sf_connect->flux != SDIS_FLUX_NONE) { + interface_shader.front.flux = interface_get_flux; + interface_shader.back.flux = interface_get_flux; + } ASSERT(fluid_side_shader); fluid_side_shader->reference_temperature = interface_get_ref_temperature; fluid_side_shader->specular_fraction = interface_get_alpha; @@ -679,6 +684,11 @@ create_intface = intface->d.sf_connect_prog->emissivity; interface_props->get_alpha = intface->d.sf_connect_prog->alpha; interface_shader.convection_coef = intface_prog_get_hc; + if(intface->d.sf_connect_prog->flux) { + interface_props->get_flux = intface->d.sf_connect_prog->flux; + interface_shader.front.flux = intface_prog_get_flux; + interface_shader.back.flux = intface_prog_get_flux; + } ASSERT(fluid_side_shader); fluid_side_shader->emissivity = intface_prog_get_emissivity; fluid_side_shader->specular_fraction = intface_prog_get_alpha; diff --git a/src/stardis-intface.h b/src/stardis-intface.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-main.c b/src/stardis-main.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-output.c b/src/stardis-output.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -638,10 +638,10 @@ medium_get_t0 type = sdis_medium_get_type(medium); data = sdis_medium_get_data(medium); if(type == SDIS_FLUID) { - const struct fluid* fluid_props = sdis_data_cget(data); + const struct fluid* fluid_props = *((const struct fluid**)sdis_data_cget(data)); return fluid_props->t0; } else { - const struct solid* solid_props = sdis_data_cget(data); + const struct solid* solid_props = *((const struct solid**)sdis_data_cget(data)); ASSERT(type == SDIS_SOLID); return solid_props->t0; } @@ -1632,7 +1632,7 @@ print_single_MC_result /* Print the results */ switch (stardis->mode & COMPUTE_MODES) { - case MODE_PROBE_COMPUTE: + case MODE_COMPUTE_PROBE_TEMP_ON_VOL: if(stardis->mode & MODE_EXTENDED_RESULTS) { if(stardis->time_range[0] == stardis->time_range[1]) fprintf(stream, "Temperature at [%g, %g, %g] at t=%g = %g K +/- %g\n", @@ -1649,14 +1649,16 @@ 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: { + case MODE_COMPUTE_PROBE_TEMP_ON_SURF: + case MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF: + { 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; } - case MODE_MEDIUM_COMPUTE: + case MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM: if(stardis->mode & MODE_EXTENDED_RESULTS) { if(stardis->time_range[0] == stardis->time_range[1]) fprintf(stream, "Temperature in medium '%s' at t=%g = %g K +/- %g\n", @@ -1673,7 +1675,7 @@ print_single_MC_result else fprintf(stream, "%g %g %lu %lu\n", result.E, result.SE, nfailures, nsamples); break; - case MODE_BOUNDARY_COMPUTE: + case MODE_COMPUTE_TEMP_MEAN_ON_SURF: if(stardis->mode & MODE_EXTENDED_RESULTS) { if(stardis->time_range[0] == stardis->time_range[1]) fprintf(stream, "Temperature at boundary '%s' at t=%g = %g K +/- %g\n", @@ -1690,7 +1692,99 @@ print_single_MC_result else fprintf(stream, "%g %g %lu %lu\n", result.E, result.SE, nfailures, nsamples); break; - case MODE_FLUX_BOUNDARY_COMPUTE: { + + case MODE_COMPUTE_PROBE_FLUX_DNSTY_ON_SURF: + case MODE_COMPUTE_LIST_PROBE_FLUX_DNSTY_ON_SURF: + { + enum sdis_estimator_type type; + ERR(sdis_estimator_get_type(estimator, &type)); + ASSERT(type == SDIS_ESTIMATOR_FLUX); + + if(stardis->mode & MODE_EXTENDED_RESULTS) { + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "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, + "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 */ + ERR(sdis_estimator_get_convective_flux(estimator, &result)); + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Convective flux density at [%g, %g, %g] at t=%g = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, + "Convective flux density at [%g, %g, %g] with t in [%g %g] = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ + ERR(sdis_estimator_get_radiative_flux(estimator, &result)); + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Radiative flux density at [%g, %g, %g] at t=%g = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, + "Radiative flux density at [%g, %g, %g] with t in [%g %g] = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ + ERR(sdis_estimator_get_imposed_flux(estimator, &result)); + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Imposed flux density at [%g, %g, %g] at t=%g = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, + "Imposed flux density at [%g, %g, %g] with t in [%g %g] = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ + ERR(sdis_estimator_get_total_flux(estimator, &result)); + if(stardis->time_range[0] == stardis->time_range[1]) + fprintf(stream, "Total flux density at [%g, %g, %g] at t=%g = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), stardis->time_range[0], + result.E, /* Expected value */ + result.SE); /* Standard error */ + else + fprintf(stream, + "Total flux density at [%g, %g, %g] with t in [%g %g] = %g W/m² +/- %g\n", + SPLIT3(stardis->probe), SPLIT2(stardis->time_range), + result.E, /* Expected value */ + result.SE); /* Standard error */ + } else { + fprintf(stream, "%g %g ", result.E, result.SE); /* Temperature */ + ERR(sdis_estimator_get_convective_flux(estimator, &result)); + fprintf(stream, "%g %g ", + result.E, + result.SE); + ERR(sdis_estimator_get_radiative_flux(estimator, &result)); + fprintf(stream, "%g %g ", + result.E, + result.SE); + ERR(sdis_estimator_get_imposed_flux(estimator, &result)); + fprintf(stream, "%g %g ", + result.E, + result.SE); + ERR(sdis_estimator_get_total_flux(estimator, &result)); + fprintf(stream, "%g %g ", + result.E, + result.SE); + fprintf(stream, "%lu %lu\n", nfailures, nsamples); + } + break; + } + + case MODE_COMPUTE_FLUX_THROUGH_SURF: + { enum sdis_estimator_type type; ERR(sdis_estimator_get_type(estimator, &type)); ASSERT(type == SDIS_ESTIMATOR_FLUX); @@ -1745,13 +1839,13 @@ print_single_MC_result stardis->compute_surface.area * result.SE); /* Standard error */ ERR(sdis_estimator_get_total_flux(estimator, &result)); if(stardis->time_range[0] == stardis->time_range[1]) - fprintf(stream, "Total flux Flux at boundary '%s' at t=%g = %g W +/- %g\n", + fprintf(stream, "Total flux at boundary '%s' at t=%g = %g W +/- %g\n", str_cget(&stardis->solve_name), stardis->time_range[0], stardis->compute_surface.area * result.E, /* Expected value */ stardis->compute_surface.area * result.SE); /* Standard error */ else fprintf(stream, - "Total flux Flux at boundary '%s' with t in [%g %g] = %g W +/- %g\n", + "Total flux at boundary '%s' with t in [%g %g] = %g W +/- %g\n", str_cget(&stardis->solve_name), SPLIT2(stardis->time_range), stardis->compute_surface.area * result.E, /* Expected value */ stardis->compute_surface.area * result.SE); /* Standard error */ @@ -1777,7 +1871,7 @@ print_single_MC_result } break; } - default: FATAL("Invalid mode."); + default: FATAL("Invalid mode\n."); } if(stardis->mode & MODE_EXTENDED_RESULTS) fprintf(stream, "#failures: %lu/%lu\n", nfailures, nsamples); @@ -1807,8 +1901,8 @@ print_single_MC_result_probe_boundary 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)); + ASSERT((stardis->mode & MODE_COMPUTE_PROBE_TEMP_ON_SURF) + || (stardis->mode & MODE_COMPUTE_LIST_PROBE_TEMP_ON_SURF)); /* Only master prints or reads estimators */ ASSERT(!stardis->mpi_initialized || stardis->mpi_rank == 0); @@ -2004,7 +2098,7 @@ dump_compute_region_at_the_end_of_vtk struct sdis_medium* medium; const struct description* descriptions; unsigned medium_id; - ASSERT(stardis->mode & MODE_MEDIUM_COMPUTE); + ASSERT(stardis->mode & MODE_COMPUTE_TEMP_MEAN_IN_MEDIUM); medium = find_medium_by_name (stardis, str_cget(&stardis->solve_name), &medium_id); ASSERT(medium != NULL); (void)medium; diff --git a/src/stardis-output.h b/src/stardis-output.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-parsing.c b/src/stardis-parsing.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -395,7 +395,7 @@ process_h logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "ref_temperature"); @@ -404,7 +404,7 @@ process_h logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } stardis->t_range[0] = MMIN(stardis->t_range[0], h_boundary->ref_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], h_boundary->ref_temperature); @@ -415,7 +415,7 @@ process_h || 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; + goto error; } CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &h_boundary->specular_fraction); @@ -425,7 +425,7 @@ process_h logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "Convection coefficient"); res = cstr_to_double(arg, &h_boundary->hc); @@ -433,7 +433,7 @@ process_h logger_print(stardis->logger, LOG_ERROR, "Invalid Convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &h_boundary->imposed_temperature); @@ -441,7 +441,7 @@ process_h || 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; + goto error; } if(type == DESC_BOUND_H_FOR_FLUID) @@ -458,7 +458,7 @@ process_h 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); + fluid->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); ERR(create_solver_fluid(stardis, fluid)); logger_print(stardis->logger, LOG_OUTPUT, "External fluid created: T=%g (it is medium %u)\n", @@ -508,7 +508,7 @@ process_hf logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "ref_temperature"); @@ -517,7 +517,7 @@ process_hf logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } stardis->t_range[0] = MMIN(stardis->t_range[0], hf_boundary->ref_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], hf_boundary->ref_temperature); @@ -528,7 +528,7 @@ process_hf || 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; + goto error; } CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &hf_boundary->specular_fraction); @@ -538,7 +538,7 @@ process_hf logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "convection coefficient"); res = cstr_to_double(arg, &hf_boundary->hc); @@ -546,7 +546,7 @@ process_hf logger_print(stardis->logger, LOG_ERROR, "Invalid convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &hf_boundary->imposed_temperature); @@ -554,7 +554,7 @@ process_hf || 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; + goto error; } CHK_ARG(idx, "flux"); res = cstr_to_double(arg, &hf_boundary->imposed_flux); @@ -564,7 +564,7 @@ process_hf logger_print(stardis->logger, LOG_ERROR, "Invalid flux: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } ASSERT(type == DESC_BOUND_HF_FOR_SOLID); @@ -577,7 +577,7 @@ process_hf 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); + fluid->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); ERR(create_solver_fluid(stardis, fluid)); logger_print(stardis->logger, LOG_OUTPUT, "External fluid created: T=%g (it is medium %u)\n", @@ -698,13 +698,13 @@ get_prog_common logger_print(stardis->logger, LOG_ERROR, "Undefined PROGRAM: %s\n", lib_name); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } else if(desc->type != DESC_PROGRAM) { logger_print(stardis->logger, LOG_ERROR, "Is not a PROGRAM: %s\n", lib_name); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } *program = desc->d.program; /* get the mandatory user-defined functions from the library */ @@ -749,7 +749,7 @@ process_program logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } lib_name = arg; @@ -876,7 +876,7 @@ process_h_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -977,7 +977,7 @@ process_hf_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1066,17 +1066,16 @@ process_t logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "temperature"); res = cstr_to_double(arg, &t_boundary->imposed_temperature); if(res != RES_OK - || SDIS_TEMPERATURE_IS_UNKNOWN(t_boundary->imposed_temperature)) - { + || 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; - goto end; + goto error; } /* Temporarily use the set temperature as a reference temperature. @@ -1129,7 +1128,7 @@ process_t_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1196,7 +1195,7 @@ process_flx logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "flux"); @@ -1206,7 +1205,7 @@ process_flx /* 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); - goto end; + goto error; } if(f_boundary->imposed_flux != 0 && stardis->picard_order > 1) { logger_print(stardis->logger, LOG_ERROR, @@ -1214,7 +1213,7 @@ process_flx "is not 1 (here order is %u)\n", f_boundary->imposed_flux, stardis->picard_order); res = RES_BAD_ARG; - goto end; + goto error; } ASSERT(sz <= UINT_MAX); @@ -1260,7 +1259,7 @@ process_flx_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "program name"); @@ -1293,6 +1292,7 @@ error: static res_T process_sfc (struct stardis* stardis, + const int with_flux, wordexp_t* pwordexp) { char* arg = NULL; @@ -1324,7 +1324,7 @@ process_sfc logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "ref_temperature"); @@ -1333,7 +1333,7 @@ process_sfc logger_print(stardis->logger, LOG_ERROR, "Invalid reference temperature: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } stardis->t_range[0] = MMIN(stardis->t_range[0], sf_connect->ref_temperature); stardis->t_range[1] = MMAX(stardis->t_range[1], sf_connect->ref_temperature); @@ -1344,7 +1344,7 @@ process_sfc || 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; + goto error; } CHK_ARG(idx, "specular fraction"); res = cstr_to_double(arg, &sf_connect->specular_fraction); @@ -1354,7 +1354,7 @@ process_sfc logger_print(stardis->logger, LOG_ERROR, "Invalid specular fraction: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "convection coefficient"); res = cstr_to_double(arg, &sf_connect->hc); @@ -1362,7 +1362,17 @@ process_sfc logger_print(stardis->logger, LOG_ERROR, "Invalid convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; + } + + if(with_flux) { + CHK_ARG(idx, "flux"); + res = cstr_to_double(arg, &sf_connect->flux); + if(res != RES_OK) { + logger_print(stardis->logger, LOG_ERROR, + "Invalid flux: %s\n", arg); + goto error; + } } ASSERT(sz <= UINT_MAX); @@ -1378,6 +1388,7 @@ error: static res_T process_sfc_prog (struct stardis* stardis, + const int with_flux, wordexp_t* pwordexp) { char* arg = NULL; @@ -1407,7 +1418,7 @@ process_sfc_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1430,6 +1441,9 @@ process_sfc_prog GET_LIB_SYMBOL(sf_connect_prog, hc, stardis_convection_coefficient); GET_LIB_SYMBOL(sf_connect_prog, hmax, stardis_max_convection_coefficient); GET_LIB_SYMBOL(sf_connect_prog, t_range, stardis_t_range); + if(with_flux) { + GET_LIB_SYMBOL(sf_connect_prog, flux, stardis_boundary_flux); + } /* create and init custom data */ ctx.name = desc_name; CREATE_DESC_DATA(sf_connect_prog); @@ -1481,7 +1495,7 @@ process_ssc logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "contact resistance"); @@ -1490,7 +1504,7 @@ process_ssc logger_print(stardis->logger, LOG_ERROR, "Invalid contact resistance: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } else if(ss_connect->tcr == 0) { logger_print(stardis->logger, LOG_WARNING, @@ -1539,7 +1553,7 @@ process_ssc_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1663,7 +1677,7 @@ process_solid solid = desc->d.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->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); solid->t0 = stardis->initial_time; solid->is_outside = 0; ASSERT(sz <= UINT_MAX); @@ -1675,35 +1689,29 @@ process_solid logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "lambda"); res = cstr_to_double(arg, &solid->lambda); - if(res != RES_OK - || solid->lambda <= 0) - { + if(res != RES_OK || solid->lambda <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid lambda: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "rho"); res = cstr_to_double(arg, &solid->rho); - if(res != RES_OK - || solid->rho <= 0) - { + if(res != RES_OK || solid->rho <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "cp"); res = cstr_to_double(arg, &solid->cp); - if(res != RES_OK - || solid->cp <= 0) - { + if(res != RES_OK || solid->cp <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } ERR(read_delta(stardis, &solid->delta, pwordexp, &idx)); CHK_ARG(idx, "Tinit"); @@ -1711,19 +1719,18 @@ process_solid 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; + goto error; } ERR(read_imposed_temperature(stardis, &solid->imposed_temperature, pwordexp, &idx)); if(SDIS_TEMPERATURE_IS_KNOWN(solid->imposed_temperature) - && solid->imposed_temperature != solid->tinit) - { + && solid->imposed_temperature != solid->tinit) { logger_print(stardis->logger, LOG_ERROR, "Imposed temperature, if defined, must match initial temperature " "(initial: %g; imposed: %g)\n", solid->tinit, solid->imposed_temperature); res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "volumic power"); @@ -1731,7 +1738,7 @@ process_solid if(res != RES_OK) { /* VPower can be < 0 */ logger_print(stardis->logger, LOG_ERROR, "Invalid volumic power: %s\n", arg); - goto end; + goto error; } if(solid->vpower != 0 && stardis->picard_order > 1) { logger_print(stardis->logger, LOG_ERROR, @@ -1739,7 +1746,7 @@ process_solid "(here order is %u)\n", solid->vpower, stardis->picard_order); res = RES_BAD_ARG; - goto end; + goto error; } /* Actual solid creation is defered until geometry is read to allow @@ -1788,7 +1795,7 @@ process_solid_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1813,11 +1820,22 @@ process_solid_prog GET_LIB_SYMBOL_BASE(&solid_prog->sample_path, solid_prog->program->lib_handle, stardis_sample_conductive_path, 1); + GET_LIB_SYMBOL_BASE(&solid_prog->t_range, solid_prog->program->lib_handle, + stardis_t_range, 1); /* create and init custom data */ ctx.name = desc_name; CREATE_DESC_DATA(solid_prog); + if(solid_prog->t_range) { + double t_range[2]; + solid_prog->t_range(solid_prog->prog_data, t_range); + if(STARDIS_TEMPERATURE_IS_KNOWN(t_range[0])) + stardis->t_range[0] = MMIN(stardis->t_range[0], t_range[0]); + if(STARDIS_TEMPERATURE_IS_KNOWN(t_range[1])) + stardis->t_range[1] = MMAX(stardis->t_range[1], t_range[1]); + } + ERR(create_solver_solid_prog(stardis, solid_prog)); end: @@ -1851,7 +1869,7 @@ process_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); + fluid->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; @@ -1861,33 +1879,29 @@ process_fluid logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "rho"); res = cstr_to_double(arg, &fluid->rho); - if(res != RES_OK - || fluid->rho <= 0) - { + if(res != RES_OK || fluid->rho <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid rho: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "cp"); res = cstr_to_double(arg, &fluid->cp); - if(res != RES_OK - || fluid->cp <= 0) - { + if(res != RES_OK || fluid->cp <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid cp: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "Tinit"); res = cstr_to_double(arg, &fluid->tinit); 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; + goto error; } ERR(read_imposed_temperature(stardis, &fluid->imposed_temperature, pwordexp, &idx)); @@ -1898,7 +1912,7 @@ process_fluid "(initial: %g; imposed: %g)\n", fluid->tinit, fluid->imposed_temperature); res = RES_BAD_ARG; - goto end; + goto error; } ERR(create_solver_fluid(stardis, fluid)); @@ -1946,7 +1960,7 @@ process_fluid_prog logger_print(stardis->logger, LOG_ERROR, "Name already used: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } desc_name = arg; @@ -1993,17 +2007,15 @@ process_scale logger_print(stardis->logger, LOG_ERROR, "SCALE cannot be specified twice\n"); res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "scale factor"); res = cstr_to_double(arg, &stardis->scale_factor); - if(res != RES_OK - || stardis->scale_factor <= 0) - { + if(res != RES_OK || stardis->scale_factor <= 0) { logger_print(stardis->logger, LOG_ERROR, "Invalid scale factor: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } end: @@ -2042,7 +2054,7 @@ process_radiative logger_print(stardis->logger, LOG_ERROR, "Invalid Trad: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } CHK_ARG(idx, "Trad reference"); res = cstr_to_double(arg, &tref); @@ -2050,7 +2062,7 @@ process_radiative logger_print(stardis->logger, LOG_ERROR, "Invalid Trad reference: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; - goto end; + goto error; } stardis->radenv.data.cst.temperature = trad; @@ -2344,9 +2356,13 @@ process_model_line else if(0 == strcasecmp(arg, "F_BOUNDARY_FOR_SOLID_PROG")) ERR(process_flx_prog(stardis, pwordexp)); else if(0 == strcasecmp(arg, "SOLID_FLUID_CONNECTION")) - ERR(process_sfc(stardis, pwordexp)); + ERR(process_sfc(stardis, 0/* No flux*/, pwordexp)); + else if(0 == strcasecmp(arg, "F_SOLID_FLUID_CONNECTION")) + ERR(process_sfc(stardis, 1/* Flux */, pwordexp)); else if(0 == strcasecmp(arg, "SOLID_FLUID_CONNECTION_PROG")) - ERR(process_sfc_prog(stardis, pwordexp)); + ERR(process_sfc_prog(stardis, 0/* No flux*/, pwordexp)); + else if(0 == strcasecmp(arg, "F_SOLID_FLUID_CONNECTION_PROG")) + ERR(process_sfc_prog(stardis, 1/* Flux */, pwordexp)); else if(0 == strcasecmp(arg, "SOLID_SOLID_CONNECTION")) ERR(process_ssc(stardis, pwordexp)); else if(0 == strcasecmp(arg, "SOLID_SOLID_CONNECTION_PROG")) @@ -2411,7 +2427,7 @@ get_dummy_solid_id 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); + dummy->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); create_solver_solid(stardis, dummy); dummies->dummy_solid = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_solid_id]; @@ -2445,7 +2461,7 @@ get_dummy_fluid_id 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); + dummy->is_green = stardis->mode & (MODE_GREEN_BIN | MODE_GREEN_ASCII); create_solver_fluid(stardis, dummy); dummies->dummy_fluid = darray_media_ptr_data_get(&stardis->media)[dummies->dummy_fluid_id]; @@ -2492,29 +2508,29 @@ read_model ERR(txtrdr_read_line(txtrdr)); line = txtrdr_get_line(txtrdr); if(!line) break; - word_initialized = 1; switch(wordexp(line, &pwordexp, flags)) { case 0: /* No error */ + word_initialized = 1; break; case WRDE_NOSPACE: /* Ran out of memory. */ res = RES_MEM_ERR; goto error; case WRDE_BADCHAR: /* A metachar appears in the wrong place. */ logger_print(stardis->logger, LOG_ERROR, - "%s: word expansion error: invalid character:\n", name); + "%s: word expansion error: invalid character.\n", name); goto exp_error; case WRDE_BADVAL: /* Undefined var reference with WRDE_UNDEF. */ logger_print(stardis->logger, LOG_ERROR, - "%s: word expansion error: undefined environment variable:\n", name); + "%s: word expansion error: undefined environment variable.\n", name); goto exp_error; case WRDE_CMDSUB: /* Command substitution with WRDE_NOCMD. */ logger_print(stardis->logger, LOG_ERROR, - "%s: word expansion error: command substitution is not enabled:\n", + "%s: word expansion error: command substitution is not enabled.\n", name); goto exp_error; case WRDE_SYNTAX: /* Shell syntax error. */ logger_print(stardis->logger, LOG_ERROR, - "%s: word expansion error: syntax error:\n", name); + "%s: word expansion error: syntax error.\n", name); goto exp_error; default: FATAL("Unexpected return code.\n"); diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 Lesser General Public @@ -25,7 +25,8 @@ /* The version of the API described thereafter */ #define STARDIS_PROG_PROPERTIES_VERSION @STARDIS_PROG_PROPERTIES_VERSION@ -#include <stddef.h> +#include <limits.h> /* UINT_MAX */ +#include <stddef.h> /* size_t */ #if defined(__GNUC__) #define STARDIS_API extern __attribute__((visibility("default"))) diff --git a/src/stardis-program.c b/src/stardis-program.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-radiative-env.c b/src/stardis-radiative-env.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-radiative-env.h b/src/stardis-radiative-env.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-sfconnect-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -105,4 +105,3 @@ sf_connect_prog_get_hmax { return connect->hmax(connect->prog_data); } - diff --git a/src/stardis-sfconnect-prog.h b/src/stardis-sfconnect-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -48,6 +48,7 @@ struct solid_fluid_connect_prog { double (*alpha) (const struct stardis_interface_fragment*, const unsigned src_id, void*); double (*hc)(const struct stardis_interface_fragment*, void*); + double (*flux)(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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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,6 +43,7 @@ init_sf_connect str_init(allocator, &(*dst)->name); str_initialized = 1; (*dst)->connection_id = UINT_MAX; + (*dst)->flux = SDIS_FLUX_NONE; end: return res; error: diff --git a/src/stardis-sfconnect.h b/src/stardis-sfconnect.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -31,6 +31,7 @@ struct solid_fluid_connect { double emissivity; double specular_fraction; double hc; + double flux; /* [W/m^2] */ unsigned connection_id; }; diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-solid-prog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -48,6 +48,7 @@ struct solid_prog { double (*delta)(const struct stardis_vertex*, void*); double (*temp)(const struct stardis_vertex*, void*); double (*vpower)(const struct stardis_vertex*, void*); + double (*t_range)(void* data, double t_range[2]); /* User-defined function for sampling a conductive path */ int diff --git a/src/stardis-solid.c b/src/stardis-solid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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 @@ -136,7 +136,7 @@ create_solver_solid #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), + ERR(sdis_data_create(stardis->dev, sizeof(struct solid*), ALIGNOF(struct solid*), NULL, &data)); props = sdis_data_get(data); /* Fetch the allocated memory space */ diff --git a/src/stardis-solid.h b/src/stardis-solid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.c b/src/stardis-ssconnect-prog.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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.h b/src/stardis-tbound.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +/* Copyright (C) 2018-2025 |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