commit dd65b9642430bfc3fa681f206d88f03f1228aabc
parent 881e8c803c090f48a4794222fca52f8dd95e35c6
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 14 Mar 2022 18:37:29 +0100
Merge branch 'feature_prog_properties' into develop
# Conflicts:
# cmake/CMakeLists.txt
# doc/stardis-input.5.txt
# src/stardis-app.h
# src/stardis-output.c
# src/stardis-parsing.c
Diffstat:
52 files changed, 5012 insertions(+), 1064 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -18,6 +18,7 @@ project(stardis C)
set(SDIS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
set(SDIS_SGT_DIR ${PROJECT_SOURCE_DIR}/../stardis-green-types)
+set(SDIS_PRG_DIR ${PROJECT_SOURCE_DIR}/../stardis-prog-properties)
option(ENABLE_MPI
@@ -73,12 +74,17 @@ configure_file(${SDIS_SOURCE_DIR}/stardis-version.h.in
${CMAKE_CURRENT_BINARY_DIR}/stardis-version.h @ONLY)
set(STARDIS_GREEN_TYPES_VERSION "4")
+set(STARDIS_PROG_PROPERTIES_VERSION "1")
configure_file(${SDIS_SOURCE_DIR}/stardis-green-types.h.in
${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types/stardis-green-types.h @ONLY)
+configure_file(${SDIS_SOURCE_DIR}/stardis-prog-properties.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties/stardis-prog-properties.h @ONLY)
configure_file(${SDIS_SGT_DIR}/stardis-green-types-config-version.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types/stardis-green-types-config-version.cmake @ONLY)
+configure_file(${SDIS_PRG_DIR}/stardis-prog-properties-config-version.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties/stardis-prog-properties-config-version.cmake @ONLY)
###############################################################################
# Check dependencies
@@ -110,7 +116,8 @@ include_directories(
${StarSTL_INCLUDE_DIR}
${StarSP_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types)
+ ${CMAKE_CURRENT_BINARY_DIR}/stardis-green-types
+ ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties)
if(MSVC)
include_directories(${MuslGetopt_INCLUDE_DIR})
endif()
@@ -136,6 +143,7 @@ if(NOT STARDIS_DOC STREQUAL "NONE")
endif()
add_subdirectory(stardis-green-types)
+add_subdirectory(stardis-prog-properties)
###############################################################################
# Configure and define targets
@@ -144,24 +152,53 @@ set(SDIS_FILES_SRC
stardis-app.c
stardis-args.c
stardis-compute.c
+ stardis-description.c
stardis-fluid.c
+ stardis-fluid-prog.c
+ stardis-fbound.c
+ stardis-fbound-prog.c
+ stardis-hbound.c
+ stardis-hbound-prog.c
stardis-intface.c
stardis-main.c
stardis-output.c
stardis-parsing.c
- stardis-solid.c)
+ stardis-program.c
+ stardis-sfconnect.c
+ stardis-sfconnect-prog.c
+ stardis-ssconnect.c
+ stardis-ssconnect-prog.c
+ stardis-solid.c
+ stardis-solid-prog.c
+ stardis-tbound.c
+ stardis-tbound-prog.c)
set(SDIS_FILES_INC
stardis-app.h
stardis-args.h
stardis-compute.h
+ stardis-description.h
stardis-default.h.in
stardis-fluid.h
+ stardis-fluid-prog.h
+ stardis-fbound.h
+ stardis-fbound-prog.h
stardis-green-types.h.in
+ stardis-hbound.h
+ stardis-hbound-prog.h
stardis-intface.h
stardis-output.h
stardis-parsing.h
+ stardis-program.h
+ stardis-prog-properties.h.in
+ stardis-sfconnect.h
+ stardis-sfconnect-prog.h
+ stardis-ssconnect.h
+ stardis-ssconnect-prog.h
stardis-solid.h
+ stardis-solid-prog.h
+ stardis-tbound.h
+ stardis-tbound-prog.h
stardis-version.h.in)
set(SDIS_FILES_DOC COPYING README.md)
diff --git a/cmake/stardis-prog-properties/CMakeLists.txt b/cmake/stardis-prog-properties/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+cmake_minimum_required(VERSION 3.0)
+
+set(STARDIS_SPROG_DIR ${PROJECT_SOURCE_DIR}/../stardis-prog-properties)
+
+################################################################################
+# Copy stardis-prog-properties CMake files
+################################################################################
+set(SPROG_NAMES
+ stardis-prog-properties-config)
+
+set(SPROG_FILES)
+foreach(_name IN LISTS SPROG_NAMES)
+ set(_src ${STARDIS_SPROG_DIR}/${_name}.cmake)
+ set(_dst ${CMAKE_CURRENT_BINARY_DIR}/${_name}.cmake)
+ add_custom_command(
+ OUTPUT ${_dst}
+ COMMAND ${CMAKE_COMMAND} -E copy ${_src} ${_dst}
+ DEPENDS ${_src}
+ COMMENT "Copy the CMake file ${_src}"
+ VERBATIM)
+ list(APPEND SPROG_FILES ${_dst})
+endforeach()
+add_custom_target(stardis-prog-cmake ALL DEPENDS ${SPROG_FILES})
+
+################################################################################
+# Install stardis-prog-properties CMake Files
+################################################################################
+list(APPEND SPROG_FILES ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties-config-version.cmake)
+
+install(FILES ${SPROG_FILES}
+ DESTINATION lib/cmake/stardis-prog-properties)
+
+################################################################################
+# Install stardis-prog-properties header Files
+################################################################################
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/stardis-prog-properties.h
+ DESTINATION include/stardis/)
diff --git a/doc/stardis-input.5.txt b/doc/stardis-input.5.txt
@@ -13,6 +13,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
+:sharp: #
+
:toc:
stardis-input(5)
@@ -28,49 +30,35 @@ DESCRIPTION
thermal system. It relies on a line-based ad-hoc syntax.
A thermal system is composed of lines of text, each one describing either a
+program (an user-provided shared object), a
medium (solid or fluid) frontier, a boundary (limit condition or connection
-between two media), or the scale of the geometry. In the medium or boundary
+between two media), the scale of the whole geometry, or the radiative
+temperature around the system. In the medium or boundary
cases, description lines include a list of file names that constitute the
-limit or boundary. The current version of *stardis* only accepts triangle
-mesh geometry files in *STL* format. If a scale is specified, it defines the
+limit or boundary. The current version of *stardis(1)* only accepts triangle
+mesh geometry files in *STL* format. If a scale is specified, it defines the
scaling factor to apply to the geometry to have it expressed in meters (e.g.
1e-3 if the geometry is in mm).
-A medium limit or a boundary description can be split accross files and a
+A medium limit or a boundary description can be split across files and a
single file or description line can describe more than one frontier (more than
one connex region). The main semantic constraint on descriptions is that any
enclosure must be defined by a single description line, to ensure that any
part in the system is made from a single medium.
Finally, description lines can be submitted to the *stardis*(1) program in
-any order and can be split accross more than one file, through multiple use
+any order, with the exception of programs that must be defined before use,
+and can be split across more than one file, through multiple use
of option *-M*.
-UNITS
------
-Any physical quantity involved in descriptions is expected in the
-International System of Units (second, metre, kilogram, kelvin, watt, joule);
-the same applies to *stardis(1)* outputs as described in *stardis-output(5)*.
-
-However, the geometry provided to *stardis*(1) can be described in any unit,
-multiple of meters or not, as long as the scaling factor is provided.
-
-TINIT VS TIMPOSED
------------------
-Media's descriptions, either solids or fluids, include two possible
-temperatures: initial and imposed. If imposed temperature is set (that is not
-"UNKNOWN"), initial temperature must be defined at the same value. As a
-consequence, one cannot define a medium with an imposed temperature that
-changes at t=0.
-
GRAMMAR
-------
In what follows, some lines end in *\*. This is used as a convenience to
continue a description next line. However, this trick cannot be used in
actual description files and actual description lines must be kept single-line.
Also, text appearing between quote marks has to be used verbatim in the input,
-except the quote characters. Finally, text introduced by the *#* character in
-descriptions, when not verbatim, is a comment and is not part of the
+except the quote characters. Finally, text introduced by the *{sharp}* character
+in descriptions, when not verbatim, is a comment and is not part of the
description.
[verse]
@@ -80,118 +68,202 @@ _______
<description-lines> ::= <description-line>
[ <description-lines> ]
-<description-line> ::= [ <medium-frontier> ] [ <comment> ]
+<description-line> ::= [ <program> ] [ <comment> ]
+ | [ <medium-frontier> ] [ <comment> ]
| [ <medium-boundary> ] [ <comment> ]
| [ <media-connection> ] [ <comment> ]
- | [ <scaling-factor> ] [ <comment> ] # at most once
- | [ <radiative-temps> ] [ <comment > ] # at most once
+ | [ <scaling-factor> ] [ <comment> ] {sharp} at most once
+ | [ <radiative-temps> ] [ <comment > ] {sharp} at most once
-------------------------------------
-<medium-frontier> ::= <solid-frontier>
- | <fluid-frontier>
+<program> ::= "PROGRAM" <prog-name> <library-path> [ <lib-arguments> ]
+
+<medium-frontier> ::= <solid-frontier>
+ | <fluid-frontier>
+ | <prog-solid-frontier>
+ | <prog-fluid-frontier>
+
+<medium-boundary> ::= <t-bound-for-solid>
+ | <h-bound-for-solid>
+ | <h-bound-for-fluid>
+ | <f-bound-for-solid>
+ | <prog-t-bound-for-solid>
+ | <prog-h-bound-for-solid>
+ | <prog-h-bound-for-fluid>
+ | <prog-f-bound-for-solid>
+
+<media-connection> ::= <solid-fluid-connect>
+ | <solid-solid-connect>
+ | <prog-solid-fluid-connect>
+ | <prog-solid-solid-connect>
+
+<comment> ::= "{sharp}" Any text introduced by the {sharp} character
+
+<solid-frontier> ::= "SOLID" <medium-name> <lambda> <rho> <cp> <delta> \
+ <initial-temperature> <imposed-temperature> \
+ <volumic-power> <triangle-sides>
+
+<fluid-frontier> ::= "FLUID" <medium-name> <rho> <cp> \
+ <initial-temperature> <imposed-temperature> \
+ <triangle-sides>
+
+<t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID" <bound-name> <temperature> \
+ <triangles>
+
-<medium-boundary> ::= <t-bound-for-solid>
- | <h-bound-for-solid>
- | <h-bound-for-fluid>
- | <f-bound-for-solid>
+<h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \
+ <specular-fraction> <hc> <outside-temperature> \
+ <triangles>
-<media-connection> ::= <solid-fluid-connect>
- | <solid-solid-connect>
+<h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID" <bound-name> <Tref> <emissivity> \
+ <specular-fraction> <hc> <outside-temperature> \
+ <triangles>
-<comment> ::= "#" Any text introduced by the # character
+<f-bound-for-solid> ::= "F_BOUNDARY_FOR_SOLID" <bound-name> <flux> <triangles>
-<scaling_factor> ::= REAL # scaling factor to apply to the geometry
- # in ]0 INF)
+<solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION" <connect-name> <Tref>\
+ <emissivity> <specular-fraction> <hc> <triangles>
-<solid-frontier> ::= "SOLID" <medium-name> <lambda> <rho> <cp> <delta> \
- <initial-temperature> <imposed-temperature> \
- <volumic-power> <triangle-sides>
+<solid-solid-connect> ::= "SOLID_SOLID_CONNECTION" <connect-name> \
+ <contact-resistance> <triangles>
-<fluid-frontier> ::= "FLUID" <medium-name> <rho> <cp> \
- <initial-temperature> <imposed-temperature> \
- <triangle-sides>
+<prog-solid-frontier> ::= "SOLID_PROG" <medium-name> <prog-name> <triangle-sides> \
+ [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID" <bound-name> <temperature> \
- <triangles>
+<prog-fluid-frontier> ::= "FLUID_PROG" <medium-name> <prog-name> <triangle-sides> \
+ [ "PROG_PARAMS" [ <desc-arguments> ] ]
+<prog-t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \
+ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \
- <specular-fraction> <hc> <outside-temperature> \
- <triangles>
-<h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID" <bound-name> <Tref> <emissivity> \
- <specular-fraction> <hc> <outside-temperature> \
- <triangles>
+<prog-h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \
+ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<f-bound-for-solid> ::= "F_BOUNDARY_FOR_SOLID" <bound-name> <flux> <triangles>
+<prog-h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID_PROG" <bound-name> <prog-name> \
+ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION" <bound-name> <Tref> <emissivity> \
- <specular-fraction> <hc> <triangles>
+<prog-f-bound-for-solid> ::= "F_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \
+ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<solid-solid-connect> ::= "SOLID_SOLID_CONNECTION" <bound-name> \
- <contact-resistance> <triangles>
+<prog-solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION_PROG" <connect-name> \
+ <prog-name> <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<scaling-factor> ::= "SCALE" <scaling_factor> [ <comment> ]
+<prog-solid-solid-connect> ::= "SOLID_SOLID_CONNECTION_PROG" <connect-name> \
+ <prog-name> <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ]
-<radiative-temps> ::= "TRAD" <radiative-temp> <radiative-temp-ref>
+<scaling-factor> ::= "SCALE" <scale> [ <comment> ]
+
+<radiative-temps> ::= "TRAD" <radiative-temp> <radiative-temp-ref>
-------------------------------------
-<medium-name> ::= STRING # no space allowed, must not be parsable as a
- # number, including INF and others
+<prog-name> ::= STRING {sharp} no space allowed, must not be a keyword nor a
+ {sharp} number, including INF and others
+
+<library-path> ::= FILEPATH {sharp} the path can be absolute
+ {sharp} or relative to the running directory and must be valid
+
+<lib-arguments> ::= STRING {sharp} if not empty, the whole string is send to the
+ {sharp} stardis_create_library_data() optional function
+ {sharp} it is an error to provide arguments to a program if
+ {sharp} the associated library doesn't define this function
+ {sharp} note that the {sharp} character consistently ends
+ {sharp} arguments by starting a comment
-<lambda> ::= REAL # conductivity in W/(m.K); in ]0, INF)
+<medium-name> ::= STRING {sharp} no space allowed, must not be a keyword nor a
+ {sharp} number, including INF and others
-<rho> ::= REAL # volumic mass,in kg/m3; in ]0, INF)
+<lambda> ::= REAL {sharp} conductivity in W/(m.K); in ]0, INF)
-<cp> ::= REAL # capacity, in J/(kg.K) or kg.m2/(s2.K)
- # in ]0, INF)
+<rho> ::= REAL {sharp} volumic mass,in kg/m3; in ]0, INF)
-<delta> ::= "AUTO" # delta is automatically set to V/6A (V and A
- # being respectively the solid volume and its
- # boundary area)
- | REAL # delta*scaling_factor in m; in [0, INF)
+<cp> ::= REAL {sharp} capacity, in J/(kg.K) or kg.m2/(s2.K)
+ {sharp} in ]0, INF)
-<initial-temperature> ::= REAL # in K; in [0, INF)
+<delta> ::= "AUTO" {sharp} delta is automatically set to V/6A (V and A
+ {sharp} being respectively the solid volume and its
+ {sharp} boundary area)
+ | REAL {sharp} delta*scaling_factor in m; in [0, INF)
-<imposed-temperature> ::= "UNKNOWN" # temperature has to be solved
- | REAL # in K; in [0, INF)
+<initial-temperature> ::= REAL {sharp} in K; in [0, INF)
-<outside-temperature> ::= REAL # in K; in [0, INF)
+<imposed-temperature> ::= "UNKNOWN" {sharp} temperature has to be solved
+ | REAL {sharp} in K; in [0, INF)
-<volumic-power> ::= REAL # in W/m3; in (-INF , INF)
+<outside-temperature> ::= REAL {sharp} in K; in [0, INF)
+
+<volumic-power> ::= REAL {sharp} in W/m3; in (-INF , INF)
<triangle-sides> ::= <side-specifier> <file-name> [ <triangle-sides> ]
-<bound-name> ::= STRING # no space allowed
+<bound-name> ::= STRING {sharp} no space allowed, must not be a keyword nor a
+ {sharp} number, including INF and others
+
+<connect-name> ::= STRING {sharp} no space allowed, must not be a keyword nor a
+ {sharp} number, including INF and others
-<Tref> ::= REAL # in [0, inf)
+<Tref> ::= REAL {sharp} in [0, inf)
-<emissivity> ::= REAL # in [0, 1]
+<emissivity> ::= REAL {sharp} in [0, 1]
-<specular-fraction> ::= REAL # in [0, 1]
+<specular-fraction> ::= REAL {sharp} in [0, 1]
-<hc> ::= REAL # in W/(m2.K); in [0, INF)
+<hc> ::= REAL {sharp} in W/(m2.K); in [0, INF)
-<contact-resistance> ::= REAL # in m2.K/W in [0, INF)
+<contact-resistance> ::= REAL {sharp} in m2.K/W in [0, INF)
-<flux> ::= REAL # in W/m2; in (-INF , INF)
+<flux> ::= REAL {sharp} in W/m2; in (-INF , INF)
<triangles> ::= <file-name> [ <triangles> ]
-<radiative-temp> ::= REAL # in [0, inf)
+<scale> ::= REAL {sharp} scaling factor to apply to the geometry
+ {sharp} in ]0 INF)
+
+<desc-arguments> ::= STRING {sharp} the whole string is send to the stardis_create_data()
+ {sharp} function when the description is created
+ {sharp} note that the '{sharp}' character consistently ends
+ {sharp} arguments by starting a comment
-<radiative-temp-ref> ::= REAL # in [0, inf)
+<radiative-temp> ::= REAL {sharp} in [0, inf)
+
+<radiative-temp-ref> ::= REAL {sharp} in [0, inf)
-------------------------------------
<side-specifier> ::= "FRONT" | "BACK" | "BOTH"
-<file-name> ::= STRING # no space allowed
+<file-name> ::= STRING {sharp} no space allowed
______________
+PROGRAMS
+--------
+Programs are user-provided shared objects (compiled libraries). They allow to
+provide *stardis(1)* with user defined properties. Depending on the type of
+description they are used with, programs must export a given list of
+mandatory functions. They can also export some other optional functions.
+The exact list with names and types can be found in the stardis-prog.h public
+header file that is installed at the same time as the *stardis(1)* binary.
+
+UNITS
+-----
+Any physical quantity involved in descriptions is expected in the
+International System of Units (second, metre, kilogram, kelvin, watt, joule);
+the same applies to *stardis(1)* outputs as described in *stardis-output(5)*.
+
+However, the geometry provided to *stardis*(1) can be described in any unit,
+multiple of meters or not, as long as the scaling factor is provided.
+
+TINIT VS TIMPOSED
+-----------------
+Media's descriptions, either solids or fluids, include two possible
+temperatures: initial and imposed. If imposed temperature is set (that is not
+"UNKNOWN"), initial temperature must be defined at the same value. In other
+words, one cannot define a medium with an imposed temperature that changes at
+t=0.
+
TRIANGLE SIDES
--------------
Side descriptions in side specifiers rely on the following convention: we
@@ -202,32 +274,40 @@ used with the FRONT side specifier to describe inside medium.
NAMES
-----
-Names, either file names, medium names or boundary names, are a sequence of
-one or ore ASCII characters, including numbers and special characters like
-*.* *_* *-* as one may consider using in standard file names, *without any
-spacing* either escaped or not. Names are case-sensitive and two different
-description lines, either in the same description file or from different
-description files, cannot use the same name. Additionaly, medium and boundary
-names cannot be parsable as a number, nor be one of the keywords defined
-by the present grammar (AUTO, BACK, BOTH, FLUID, FRONT, F_BOUNDARY_FOR_SOLID,
-H_BOUNDARY_FOR_FLUID, H_BOUNDARY_FOR_SOLID, SCALE, SOLID,
-SOLID_FLUID_CONNECTION, T_BOUNDARY_FOR_FLUID, T_BOUNDARY_FOR_SOLID, UNKNOWN) or
-their lowercase counterparts. Finally, description names cannot be longer than
-63 characters.
+Names, either file names or description names (program names, medium names or
+boundary names), are a sequence of one or ore ASCII characters, including
+numbers and special characters like *.* *_* *-* as one may consider using in
+standard file names, *without any spacing* either escaped or not. Description
+names are case-sensitive and two different description lines, either in the
+same description file or from different description files, cannot use the same
+name. Additionally, description names cannot be parsable as a number, nor be one
+of the keywords defined by the present grammar (AUTO, BACK, BOTH, FLUID,
+FLUID_PROG, FRONT, F_BOUNDARY_FOR_SOLID, F_BOUNDARY_FOR_SOLID_PROG,
+H_BOUNDARY_FOR_FLUID, H_BOUNDARY_FOR_FLUID_PROG, H_BOUNDARY_FOR_SOLID,
+H_BOUNDARY_FOR_SOLID_PROG, PROGRAM, PROG_PARAMS, SCALE, SOLID, SOLID_PROG,
+SOLID_FLUID_CONNECTION, SOLID_FLUID_CONNECTION_PROG, SOLID_SOLID_CONNECTION,
+SOLID_SOLID_CONNECTION_PROG, TRAD, T_BOUNDARY_FOR_SOLID,
+T_BOUNDARY_FOR_SOLID_PROG, UNKNOWN) or their lowercase counterparts.
+Finally, description names cannot be longer than 63 characters.
EXAMPLES
--------
-Define a solid named Cube with a h boundary. The cube geometry is read from
+Define a solid named Cube, a h boundary, and their radiative environment.
+The cube geometry is read from
the file cube.stl and the solid medium properties are lambda=0.1, rho=25, cp=2.
The numerical parameter delta, that is used for solid conductive walks, is
-0.05. The initial temperature of the cube is 0°K and its volumic power is 0.
-The boundary properties are emisivity=0, specular-fraction=0, h=10 and
-external-temperature = 100°K, while the reference temperature for radiative
-transfer linearization in the Picard algorithm is set to 300°K.
-.
+0.05. The initial temperature of the cube is 0°K, its temperature is unknown
+(*stardis(1)* needs to solve it), and its volumic power is 2.5 W/m3.
+The boundary properties are emissivity=0, specular-fraction=0, h=10 and
+external-temperature = 100°K.
+The cube radiative environment is at 300°K.
+Finally, when the Picard method linearises radiative transfer involving the HdT
+boundary, the reference temperature is set to 310°K, while it is set to 330°K
+when linearisation involves the radiative environment.
.......
-SOLID Cube 0.1 25 2 0.05 0 0 FRONT cube.stl
-H_BOUNDARY_FOR_SOLID HdT 300 0 0 10 100 cube.stl
+SOLID Cube 0.1 25 2 0.05 0 UNKNOWN 2.5 FRONT cube.stl
+H_BOUNDARY_FOR_SOLID HdT 310 0 0 10 100 cube.stl
+TRAD 300 330
.......
SEE ALSO
diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in
@@ -102,7 +102,9 @@ MANDATORY OPTIONS
-----------------
*-M* _file_::
Read a text file containing a possibly partial description of the system.
- Can include both media enclosures and boundary conditions, in any order.
+ Can include programs, media enclosures and boundary conditions. Media and
+ boundaries can appear in any order, but programs must be defined before their
+ first reference. Refer to *stardis-input(5)* for details.
Can be used more than once if the description is split across different
files.
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -18,18 +18,22 @@
#endif
#include "stardis-app.h"
-#include "stardis-output.h"
+#include "stardis-args.h"
+#include "stardis-description.h"
+#include "stardis-default.h"
+#include "stardis-parsing.h"
#include "stardis-compute.h"
#include "stardis-intface.h"
-#include "stardis-fluid.h"
#include "stardis-solid.h"
+#include "stardis-fluid.h"
+#include "stardis-program.h"
#include <star/senc3d.h>
#include <star/sg3d_sencXd_helper.h>
#include <star/sg3d_sdisXd_helper.h>
#include <rsys/str.h>
-#include <rsys/text_reader.h>
+#include <rsys/library.h>
#include <rsys/logger.h>
#include <rsys/double2.h>
#include <rsys/double3.h>
@@ -47,64 +51,6 @@ static const struct counts COUNTS_NULL = COUNTS_NULL__;
/*******************************************************************************
* Local Functions
******************************************************************************/
-static res_T
-read_model
- (const struct darray_str* model_files,
- struct stardis* stardis)
-{
- res_T res = RES_OK;
- const struct str* files = NULL;
- size_t i;
- FILE* f = NULL;
- struct txtrdr* txtrdr = NULL;
-
- ASSERT(model_files && stardis);
- files = darray_str_cdata_get(model_files);
- FOR_EACH(i, 0, darray_str_size_get(model_files)) {
- const char* name = str_cget(files + i);
- f = fopen(name, "r");
- if(!f) {
- logger_print(stardis->logger, LOG_ERROR,
- "Cannot open model file '%s'\n",
- name);
- res = RES_IO_ERR;
- goto error;
- }
- txtrdr_stream(stardis->allocator, f, name, '#', &txtrdr);
- for(;;) {
- char* line;
- ERR(txtrdr_read_line(txtrdr));
- line = txtrdr_get_line(txtrdr);
- if(!line) break;
- ERR(process_model_line(name, line, stardis));
- }
- txtrdr_ref_put(txtrdr);
- txtrdr = NULL;
- fclose(f);
- f = NULL;
- }
- if(stardis->scale_factor <= 0)
- stardis->scale_factor = STARDIS_DEFAULT_SCALE_FACTOR;
- logger_print(stardis->logger, LOG_OUTPUT,
- "Scaling factor is %g\n", stardis->scale_factor);
- logger_print(stardis->logger, LOG_OUTPUT,
- "Trad is %g, Trad reference is %g\n", stardis->trad, stardis->trad_ref);
- stardis->t_range[0] = MMIN(stardis->t_range[0], stardis->trad_ref);
- stardis->t_range[1] = MMAX(stardis->t_range[1], stardis->trad_ref);
- logger_print(stardis->logger, LOG_OUTPUT,
- "System T range is [%g %g]\n", SPLIT2(stardis->t_range));
- logger_print(stardis->logger, LOG_OUTPUT,
- "Picard order is %u\n", stardis->picard_order);
-
- ASSERT(!f && !txtrdr);
-exit:
- return res;
-error:
- if(f) fclose(f);
- if(txtrdr) txtrdr_ref_put(txtrdr);
- goto exit;
-}
-
static struct sdis_interface*
geometry_get_interface
(const size_t itri, void* ctx)
@@ -428,16 +374,18 @@ stardis_init
}
}
- /* Create solids and log model information */
+ /* Create solids, finalize program data, and log model information */
for(i = 0; i < darray_descriptions_size_get(&stardis->descriptions); i++) {
struct description* desc =
darray_descriptions_data_get(&stardis->descriptions) + i;
if(desc->type == DESC_MAT_SOLID) {
tmp_res = check_delta_and_create_solid(stardis, desc);
- if(tmp_res != RES_OK && is_for_compute) {
- res = tmp_res;
- goto error;
- }
+ } else if(desc->type == DESC_PROGRAM && desc->d.program->finalize) {
+ tmp_res = desc->d.program->finalize(desc->d.program->prog_data);
+ }
+ if(tmp_res != RES_OK && is_for_compute) {
+ res = tmp_res;
+ goto error;
}
ERR(str_print_description(&str, i, desc));
logger_print(stardis->logger, LOG_OUTPUT, "%s\n", str_cget(&str));
@@ -523,8 +471,16 @@ stardis_release
str_release(&stardis->bin_green_filename);
str_release(&stardis->end_paths_filename);
str_release(&stardis->chunks_prefix);
+ /* release non-PROGRAM descritions first */
+ FOR_EACH(i, 0, darray_descriptions_size_get(&stardis->descriptions)) {
+ struct description* d = darray_descriptions_data_get(&stardis->descriptions) +i;
+ if(d->type == DESC_PROGRAM) continue;
+ release_description(d, stardis->allocator);
+ }
+ /* release PROGRAM descritions */
FOR_EACH(i, 0, darray_descriptions_size_get(&stardis->descriptions)) {
struct description* d = darray_descriptions_data_get(&stardis->descriptions) +i;
+ if(d->type != DESC_PROGRAM) continue;
release_description(d, stardis->allocator);
}
darray_descriptions_release(&stardis->descriptions);
@@ -547,6 +503,14 @@ stardis_release
}
}
+unsigned
+allocate_stardis_medium_id
+ (struct stardis* stardis)
+{
+ ASSERT(stardis);
+ return stardis->next_medium_id++;
+}
+
res_T
init_enclosures
(struct stardis* stardis)
@@ -577,9 +541,9 @@ error:
if(properties[(Rank)] == SG3D_UNSPECIFIED_PROPERTY) undef_count++;\
else {\
ASSERT(properties[(Rank)] < darray_descriptions_size_get(&stardis->descriptions));\
- ASSERT(DESC_IS_MEDIUM(descs[properties[(Rank)]].type));\
- if(descs[properties[(Rank)]].type == DESC_MAT_SOLID) solid_count++;\
- else fluid_count++;\
+ ASSERT(DESC_IS_MEDIUM(descs+properties[(Rank)]));\
+ if(DESC_IS_SOLID(descs+properties[(Rank)])) { solid_count++; }\
+ else { ASSERT(DESC_IS_FLUID(descs+properties[(Rank)])); fluid_count++; }\
}\
}
@@ -616,6 +580,7 @@ validate_properties
intface = descs + properties[SG3D_INTFACE];
switch (intface->type) {
case DESC_BOUND_H_FOR_FLUID:
+ case DESC_BOUND_H_FOR_FLUID_PROG:
if(!(solid_count == 0 && fluid_count == 1)) {
if(solid_count + fluid_count == 2)
*properties_conflict_status = BOUND_H_FOR_FLUID_BETWEEN_2_DEFS;
@@ -628,6 +593,7 @@ validate_properties
}
break;
case DESC_BOUND_H_FOR_SOLID:
+ case DESC_BOUND_H_FOR_SOLID_PROG:
if(!(solid_count == 1 && fluid_count == 0)) {
if(solid_count + fluid_count == 2)
*properties_conflict_status = BOUND_H_FOR_SOLID_BETWEEN_2_DEFS;
@@ -640,6 +606,7 @@ validate_properties
}
break;
case DESC_BOUND_T_FOR_SOLID:
+ case DESC_BOUND_T_FOR_SOLID_PROG:
if(!(solid_count == 1 && fluid_count == 0)) {
if(solid_count + fluid_count == 2)
*properties_conflict_status = BOUND_T_FOR_SOLID_BETWEEN_2_DEFS;
@@ -652,6 +619,7 @@ validate_properties
}
break;
case DESC_BOUND_F_FOR_SOLID:
+ case DESC_BOUND_F_FOR_SOLID_PROG:
if(!(solid_count == 1 && fluid_count == 0)) {
if(solid_count + fluid_count == 2)
*properties_conflict_status = BOUND_F_FOR_SOLID_BETWEEN_2_DEFS;
@@ -664,6 +632,7 @@ validate_properties
}
break;
case DESC_SOLID_FLUID_CONNECT:
+ case DESC_SOLID_FLUID_CONNECT_PROG:
if(solid_count != 1 || fluid_count != 1) {
if(solid_count == 2)
*properties_conflict_status = SFCONNECT_BETWEEN_2_SOLIDS;
@@ -678,6 +647,7 @@ validate_properties
}
break;
case DESC_SOLID_SOLID_CONNECT:
+ case DESC_SOLID_SOLID_CONNECT_PROG:
if(solid_count != 2) {
/*if(soli_count == 1 && fluid_count == 1)*/
/**properties_conflict_status = SSCONNECT_BETWEEN_SOLID_AND_FLUID;*/
@@ -718,3 +688,109 @@ end:
}
#undef COUNT_SIDE
+
+res_T
+init_geometry
+ (struct logger* logger,
+ struct mem_allocator* allocator,
+ const int verbose,
+ struct geometry* geom)
+{
+ res_T res = RES_OK;
+ struct sg3d_device* sg3d_dev = NULL;
+
+ ASSERT(allocator && geom);
+
+ geom->sg3d = NULL;
+ darray_interface_ptrs_init(allocator, &geom->interfaces);
+ darray_interface_ptrs_init(allocator, &geom->interf_bytrg);
+ ERR(sg3d_device_create(logger, allocator, verbose, &sg3d_dev));
+ ERR(sg3d_geometry_create(sg3d_dev, &geom->sg3d));
+
+exit:
+ if(sg3d_dev) SG3D(device_ref_put(sg3d_dev));
+ return res;
+error:
+ release_geometry(geom);
+ goto exit;
+}
+
+void
+release_geometry
+ (struct geometry* geom)
+{
+ size_t i;
+ struct sdis_interface
+ ** intf = darray_interface_ptrs_data_get(&geom->interfaces);
+ if(geom->sg3d) SG3D(geometry_ref_put(geom->sg3d));
+ for(i = 0; i < darray_interface_ptrs_size_get(&geom->interfaces); ++i)
+ SDIS(interface_ref_put(intf[i]));
+ darray_interface_ptrs_release(&geom->interfaces);
+ darray_interface_ptrs_release(&geom->interf_bytrg);
+}
+
+void
+init_camera
+ (struct mem_allocator* alloc, struct camera* cam)
+{
+ ASSERT(alloc && cam);
+ d3(cam->pos, STARDIS_DEFAULT_RENDERING_POS);
+ d3(cam->tgt, STARDIS_DEFAULT_RENDERING_TGT);
+ d3(cam->up, STARDIS_DEFAULT_RENDERING_UP);
+ cam->fmt = STARDIS_DEFAULT_RENDERING_OUTPUT_FILE_FMT;
+ cam->fov = STARDIS_DEFAULT_RENDERING_FOV;
+ cam->spp = STARDIS_DEFAULT_RENDERING_SPP;
+ cam->img_width = STARDIS_DEFAULT_RENDERING_IMG_WIDTH;
+ cam->img_height = STARDIS_DEFAULT_RENDERING_IMG_HEIGHT;
+ d2(cam->time_range, STARDIS_DEFAULT_RENDERING_TIME);
+ cam->auto_look_at = 1;
+ str_init(alloc, &cam->file_name);
+}
+
+void
+release_camera
+ (struct camera* cam)
+{
+ ASSERT(cam);
+ str_release(&cam->file_name);
+}
+
+void
+log_err_fn
+ (const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+#ifdef OS_WINDOWS
+ fprintf(stderr, "error: %s", msg);
+#else
+ fprintf(stderr, "\x1b[31merror:\x1b[0m %s", msg);
+#endif
+}
+
+void
+log_warn_fn
+ (const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+#ifdef OS_WINDOWS
+ fprintf(stderr, "warning: %s", msg);
+#else
+ fprintf(stderr, "\x1b[33mwarning:\x1b[0m %s", msg);
+#endif
+}
+
+void
+log_prt_fn
+ (const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+#ifdef OS_WINDOWS
+ fprintf(stderr, "message: %s", msg);
+#else
+ fprintf(stderr, "\x1b[32moutput:\x1b[0m %s", msg);
+#endif
+}
+
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -16,28 +16,20 @@
#ifndef STARDIS_APP_H
#define STARDIS_APP_H
-#include "stardis-args.h"
-#include "stardis-parsing.h"
-#include "stardis-default.h"
-#include "stardis-solid.h"
-#include "stardis-fluid.h"
+#include "stardis-description.h"
-#include <star/sstl.h>
#include <star/sg3d.h>
#include <rsys/rsys.h>
-#include <rsys/float3.h>
#include <rsys/double2.h>
#include <rsys/double3.h>
#include <rsys/dynamic_array_size_t.h>
+#include <rsys/dynamic_array_uint.h>
#include <rsys/dynamic_array.h>
#include <rsys/str.h>
#include <sdis.h>
-#include <limits.h>
-#include <stdarg.h>
-
#ifdef STARDIS_ENABLE_MPI
#include <mpi/mpi.h>
#endif
@@ -47,30 +39,23 @@ struct logger;
struct mem_allocator;
struct sdis_medium;
+struct args;
+struct solid;
+struct fluid;
+
/* Utility macros */
#define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0
-#define STR_APPEND_PRINTF(Accum, Fmt, Args) \
-{ \
- struct str tmp; \
- str_init((Accum)->allocator, &tmp); \
- res = str_printf(&tmp, Fmt COMMA_##Args LIST_##Args); \
- if(res == RES_OK) res = str_append((Accum), str_cget(&tmp)); \
- str_release(&tmp); \
- if(res != RES_OK) goto error; \
-} (void)0
-
-
-#define VFATAL(Fmt, Args) \
- { \
- fprintf(stderr, Fmt COMMA_##Args LIST_##Args); \
- ASSERT(0); \
- abort(); \
+#define VFATAL(Fmt, Args) \
+ { \
+ fprintf(stderr, Fmt COMMA_##Args LIST_##Args); \
+ ASSERT(0); \
+ abort(); \
} (void)0
#define DELTA_AUTO INF /* Placeholder until actual value is substituted */
-#define UNKNOWN_MEDIUM_TEMPERATURE -1 /* Unknown for stadis solver is -1 */
+#define UNKNOWN_MEDIUM_TEMPERATURE -1 /* Unknown for stardis solver is -1 */
enum properties_conflict_t {
NO_PROPERTY_CONFLICT,
@@ -98,31 +83,6 @@ enum properties_conflict_t {
PROPERTIES_CONFLICT_COUNT__
};
-/* Different types of descriptions */
-enum description_type {
- DESC_MAT_SOLID,
- DESC_MAT_FLUID,
- DESC_BOUND_H_FOR_FLUID,
- DESC_BOUND_H_FOR_SOLID,
- DESC_BOUND_T_FOR_SOLID,
- DESC_BOUND_F_FOR_SOLID,
- DESC_SOLID_FLUID_CONNECT,
- DESC_SOLID_SOLID_CONNECT,
- DESCRIPTION_TYPE_COUNT__,
- DESC_OUTSIDE
-};
-
-#define DESC_IS_H(D) \
- ((D) == DESC_BOUND_H_FOR_SOLID || (D) == DESC_BOUND_H_FOR_FLUID)
-#define DESC_IS_T(D) \
- ((D) == DESC_BOUND_T_FOR_SOLID)
-#define DESC_IS_F(D) \
- ((D) == DESC_BOUND_F_FOR_SOLID)
-#define DESC_IS_MEDIUM(D) \
- ((D) == DESC_MAT_SOLID || (D) == DESC_MAT_FLUID)
-#define DESC_IS_BOUNDARY(D) \
- (DESC_IS_H(D) || DESC_IS_T(D) || DESC_IS_F(D))
-
#define DARRAY_NAME interface_ptrs
#define DARRAY_DATA struct sdis_interface*
#include <rsys/dynamic_array.h>
@@ -160,518 +120,18 @@ struct geometry {
struct darray_interface_ptrs interfaces;
};
-static INLINE void
-release_geometry(struct geometry* geom)
-{
- size_t i;
- struct sdis_interface
- ** intf = darray_interface_ptrs_data_get(&geom->interfaces);
- if(geom->sg3d) SG3D(geometry_ref_put(geom->sg3d));
- for(i = 0; i < darray_interface_ptrs_size_get(&geom->interfaces); ++i)
- SDIS(interface_ref_put(intf[i]));
- darray_interface_ptrs_release(&geom->interfaces);
- darray_interface_ptrs_release(&geom->interf_bytrg);
-}
+void
+release_geometry
+ (struct geometry* geom);
-static INLINE res_T
+res_T
init_geometry
(struct logger* logger,
struct mem_allocator* allocator,
const int verbose,
- struct geometry* geom)
-{
- res_T res = RES_OK;
- struct sg3d_device* sg3d_dev = NULL;
-
- ASSERT(allocator && geom);
-
- geom->sg3d = NULL;
- darray_interface_ptrs_init(allocator, &geom->interfaces);
- darray_interface_ptrs_init(allocator, &geom->interf_bytrg);
- ERR(sg3d_device_create(logger, allocator, verbose, &sg3d_dev));
- ERR(sg3d_geometry_create(sg3d_dev, &geom->sg3d));
-
-exit:
- if(sg3d_dev) SG3D(device_ref_put(sg3d_dev));
- return res;
-error:
- release_geometry(geom);
- goto exit;
-}
+ struct geometry* geom);
/******************************************************************************/
-
-struct fluid;
-struct solid;
-struct t_boundary;
-struct f_boundary;
-struct h_boundary;
-struct solid_fluid_connect;
-struct solid_solid_connect;
-
-struct description {
- enum description_type type;
- union {
- struct fluid* fluid;
- struct solid* solid;
- struct t_boundary* t_boundary;
- struct f_boundary* f_boundary;
- struct h_boundary* h_boundary;
- struct solid_fluid_connect* sf_connect;
- struct solid_solid_connect* ss_connect;
- } d;
-};
-
-/******************************************************************************/
-
-struct h_boundary {
- struct str name;
- double ref_temperature;
- double emissivity;
- double specular_fraction;
- double hc;
- double imposed_temperature;
- unsigned mat_id;
- struct fluid* possible_external_fluid; /* if H for solid */
-};
-
-static FINLINE res_T
-init_h
- (struct mem_allocator* allocator,
- struct h_boundary** dst)
-{
- res_T res = RES_OK;
- int str_initialized = 0;
- ASSERT(allocator && dst && *dst == NULL);
- *dst = MEM_ALLOC(allocator, sizeof(struct h_boundary));
- if(! *dst) {
- res = RES_MEM_ERR;
- goto error;
- }
- str_init(allocator, &(*dst)->name);
- (*dst)->ref_temperature = 0;
- (*dst)->emissivity = 0;
- (*dst)->specular_fraction = 0;
- (*dst)->hc = 0;
- (*dst)->imposed_temperature = -1;
- (*dst)->mat_id = UINT_MAX;
- (*dst)->possible_external_fluid = NULL;
-end:
- return res;
-error:
- if(str_initialized) str_release(&(*dst)->name);
- if(*dst) MEM_RM(allocator, *dst);
- goto end;
-}
-
-static FINLINE void
-release_h_boundary
- (struct h_boundary* bound,
- struct mem_allocator* allocator)
-{
- ASSERT(bound && allocator);
- str_release(&bound->name);
- if(bound->possible_external_fluid) {
- release_fluid(bound->possible_external_fluid, allocator);
- }
- MEM_RM(allocator, bound);
-}
-
-static res_T
-str_print_h_boundary
- (struct str* str,
- const struct h_boundary* b,
- const enum description_type type)
-{
- res_T res = RES_OK;
- ASSERT(str && b && DESC_IS_H(type));
- STR_APPEND_PRINTF(str,
- "H boundary for %s '%s': ref_temperature=%g emissivity=%g specular_fraction=%g "
- "hc=%g T=%g (using medium %u as external medium)",
- ARG8( (type == DESC_BOUND_H_FOR_SOLID ? "solid" : "fluid"), str_cget(&b->name),
- b->ref_temperature, b->emissivity, b->specular_fraction, b->hc,
- b->imposed_temperature, b->mat_id ) );
-end:
- return res;
-error:
- goto end;
-}
-
-struct t_boundary {
- struct str name;
- double imposed_temperature;
- unsigned mat_id;
-};
-
-static FINLINE res_T
-init_t
- (struct mem_allocator* allocator,
- struct t_boundary** dst)
-{
- res_T res = RES_OK;
- int str_initialized = 0;
- ASSERT(allocator && dst && *dst == NULL);
- *dst = MEM_ALLOC(allocator, sizeof(struct t_boundary));
- if(! *dst) {
- res = RES_MEM_ERR;
- goto error;
- }
- str_init(allocator, &(*dst)->name);
- (*dst)->imposed_temperature = -1;
- (*dst)->mat_id = UINT_MAX;
-end:
- return res;
-error:
- if(str_initialized) str_release(&(*dst)->name);
- if(*dst) MEM_RM(allocator, *dst);
- goto end;
-}
-
-static FINLINE void
-release_t_boundary
- (struct t_boundary* bound,
- struct mem_allocator* allocator)
-{
- ASSERT(bound && allocator);
- str_release(&bound->name);
- MEM_RM(allocator, bound);
-}
-
-static res_T
-str_print_t_boundary
- (struct str* str,
- const struct t_boundary* b)
-{
- res_T res = RES_OK;
- ASSERT(str && b);
- STR_APPEND_PRINTF(str, "T boundary for solid '%s': T=%g ",
- ARG2( str_cget(&b->name), b->imposed_temperature ) );
-
- STR_APPEND_PRINTF(str, "(using medium %u as external medium)",
- ARG1( b->mat_id ) );
-end:
- return res;
-error:
- goto end;
-}
-
-struct f_boundary {
- struct str name;
- double imposed_flux;
- unsigned mat_id;
-};
-
-static FINLINE res_T
-init_f
- (struct mem_allocator* allocator,
- struct f_boundary** dst)
-{
- res_T res = RES_OK;
- int str_initialized = 0;
- ASSERT(allocator && dst && *dst == NULL);
- *dst = MEM_ALLOC(allocator, sizeof(struct f_boundary));
- if(! *dst) {
- res = RES_MEM_ERR;
- goto error;
- }
- str_init(allocator, &(*dst)->name);
- (*dst)->mat_id = UINT_MAX;
- (*dst)->imposed_flux = -1;
-end:
- return res;
-error:
- if(str_initialized) str_release(&(*dst)->name);
- if(*dst) MEM_RM(allocator, *dst);
- goto end;
-}
-
-static FINLINE void
-release_f_boundary
- (struct f_boundary* bound,
- struct mem_allocator* allocator)
-{
- ASSERT(bound && allocator);
- str_release(&bound->name);
- MEM_RM(allocator, bound);
-}
-
-static res_T
-str_print_f_boundary
- (struct str* str,
- const struct f_boundary* b)
-{
- res_T res = RES_OK;
- ASSERT(str && b);
- STR_APPEND_PRINTF(str,
- "F boundary for SOLID '%s': flux=%g (using medium %u as external medium)",
- ARG3( str_cget(&b->name), b->imposed_flux, b->mat_id ) );
-end:
- return res;
-error:
- goto end;
-}
-
-struct solid_fluid_connect {
- struct str name;
- double ref_temperature;
- double emissivity;
- double specular_fraction;
- double hc;
- unsigned connection_id;
-};
-
-static FINLINE void
-release_sf_connect
- (struct solid_fluid_connect* connect,
- struct mem_allocator* allocator)
-{
- ASSERT(connect && allocator);
- str_release(&connect->name);
- MEM_RM(allocator, connect);
-}
-
-static FINLINE res_T
-init_sf
- (struct mem_allocator* allocator,
- struct solid_fluid_connect** dst)
-{
- res_T res = RES_OK;
- int str_initialized = 0;
- ASSERT(allocator && dst && *dst == NULL);
- *dst = MEM_ALLOC(allocator, sizeof(struct solid_fluid_connect));
- if(! *dst) {
- res = RES_MEM_ERR;
- goto error;
- }
- str_init(allocator, &(*dst)->name);
- (*dst)->ref_temperature = 0;
- (*dst)->emissivity = 0;
- (*dst)->specular_fraction = 0;
- (*dst)->hc = 0;
- (*dst)->connection_id = UINT_MAX;
-end:
- return res;
-error:
- if(str_initialized) str_release(&(*dst)->name);
- if(*dst) MEM_RM(allocator, *dst);
- goto end;
-}
-
-static res_T
-str_print_sf_connect
- (struct str* str,
- const struct solid_fluid_connect* c)
-{
- res_T res = RES_OK;
- ASSERT(str && c);
- STR_APPEND_PRINTF(str, "Solid-Fluid connection '%s': ", ARG1( str_cget(&c->name) ) );
- STR_APPEND_PRINTF(str, "ref_temperature=%g emissivity=%g, specular_fraction=%g hc=%g",
- ARG4( c->ref_temperature, c->emissivity, c->specular_fraction, c->hc ) );
-end:
- return res;
-error:
- goto end;
-}
-
-struct solid_solid_connect {
- struct str name;
- double tcr;
- unsigned connection_id;
-};
-
-static FINLINE void
-release_ss_connect
- (struct solid_solid_connect* connect,
- struct mem_allocator* allocator)
-{
- ASSERT(connect && allocator);
- str_release(&connect->name);
- MEM_RM(allocator, connect);
-}
-
-static FINLINE res_T
-init_ss
- (struct mem_allocator* allocator,
- struct solid_solid_connect** dst)
-{
- res_T res = RES_OK;
- int str_initialized = 0;
- ASSERT(allocator && dst && *dst == NULL);
- *dst = MEM_ALLOC(allocator, sizeof(struct solid_solid_connect));
- if(! *dst) {
- res = RES_MEM_ERR;
- goto error;
- }
- str_init(allocator, &(*dst)->name);
- (*dst)->tcr = 0;
- (*dst)->connection_id = UINT_MAX;
-end:
- return res;
-error:
- if(str_initialized) str_release(&(*dst)->name);
- if(*dst) MEM_RM(allocator, *dst);
- goto end;
-}
-
-static res_T
-str_print_ss_connect
- (struct str* str,
- const struct solid_solid_connect* c)
-{
- res_T res = RES_OK;
- ASSERT(str && c);
- STR_APPEND_PRINTF(str, "Solid-Solid connection '%s': ", ARG1( str_cget(&c->name) ) );
- STR_APPEND_PRINTF(str, "contact resistance=%g", ARG1( c->tcr ) );
-end:
- return res;
-error:
- goto end;
-}
-
-static FINLINE res_T
-init_description
- (struct mem_allocator* alloc,
- struct description* desc)
-{
- ASSERT(desc);
- (void)alloc;
- desc->type = DESCRIPTION_TYPE_COUNT__;
- desc->d.fluid = NULL;
- return RES_OK;
-}
-
-static FINLINE void
-release_description
- (struct description* desc,
- struct mem_allocator* allocator)
-{
- ASSERT(desc && allocator);
- switch (desc->type) {
- case DESC_MAT_SOLID:
- release_solid(desc->d.solid, allocator);
- break;
- case DESC_MAT_FLUID:
- release_fluid(desc->d.fluid, allocator);
- break;
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- release_h_boundary(desc->d.h_boundary, allocator);
- break;
- case DESC_BOUND_T_FOR_SOLID:
- release_t_boundary(desc->d.t_boundary, allocator);
- break;
- case DESC_BOUND_F_FOR_SOLID:
- release_f_boundary(desc->d.f_boundary, allocator);
- break;
- case DESC_SOLID_FLUID_CONNECT:
- release_sf_connect(desc->d.sf_connect, allocator);
- break;
- case DESC_SOLID_SOLID_CONNECT:
- release_ss_connect(desc->d.ss_connect, allocator);
- break;
- default:
- FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
- }
-}
-
-static INLINE res_T
-str_print_description
- (struct str* str,
- const unsigned rank,
- const struct description* desc)
-{
- res_T res = RES_OK;
- ASSERT(str && desc);
- str_clear(str);
- ERR(str_printf(str, "Description %u: ", rank));
- switch (desc->type) {
- case DESC_MAT_SOLID:
- ERR(str_print_solid(str, desc->d.solid));
- break;
- case DESC_MAT_FLUID:
- ERR(str_print_fluid(str, desc->d.fluid));
- break;
- case DESC_BOUND_T_FOR_SOLID:
- ERR(str_print_t_boundary(str, desc->d.t_boundary));
- break;
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- ERR(str_print_h_boundary(str, desc->d.h_boundary, desc->type));
- break;
- case DESC_BOUND_F_FOR_SOLID:
- ERR(str_print_f_boundary(str, desc->d.f_boundary));
- break;
- case DESC_SOLID_FLUID_CONNECT:
- ERR(str_print_sf_connect(str, desc->d.sf_connect));
- break;
- case DESC_SOLID_SOLID_CONNECT:
- ERR(str_print_ss_connect(str, desc->d.ss_connect));
- break;
- default:
- FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
- }
-end:
- return res;
-error:
- goto end;
-}
-
-static INLINE const struct str*
-get_description_name
- (const struct description* desc)
-{
- ASSERT(desc);
- switch (desc->type) {
- case DESC_MAT_SOLID:
- return &desc->d.solid->name;
- case DESC_MAT_FLUID:
- return &desc->d.fluid->name;
- case DESC_BOUND_T_FOR_SOLID:
- return &desc->d.t_boundary->name;
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- return &desc->d.h_boundary->name;
- case DESC_BOUND_F_FOR_SOLID:
- return &desc->d.f_boundary->name;
- case DESC_SOLID_FLUID_CONNECT:
- return &desc->d.sf_connect->name;
- case DESC_SOLID_SOLID_CONNECT:
- return &desc->d.ss_connect->name;
- default:
- FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
- }
-}
-
-static FINLINE void
-description_get_medium_id
- (const struct description* desc,
- unsigned* id)
-{
- ASSERT(desc && id);
- switch (desc->type) {
- case DESC_MAT_SOLID:
- *id = desc->d.solid->solid_id;
- return;
- case DESC_MAT_FLUID:
- *id = desc->d.fluid->fluid_id;
- return;
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- *id = desc->d.h_boundary->mat_id;
- return;
- case DESC_BOUND_T_FOR_SOLID:
- *id = desc->d.t_boundary->mat_id;
- return;
- case DESC_BOUND_F_FOR_SOLID:
- *id = desc->d.f_boundary->mat_id;
- return;
- case DESC_SOLID_FLUID_CONNECT: /* No medium linked to SF */
- case DESC_SOLID_SOLID_CONNECT: /* No medium linked to SS */
- default:
- FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
- }
-}
-
enum stardis_output_fmt {
STARDIS_RENDERING_OUTPUT_FILE_FMT_VTK,
STARDIS_RENDERING_OUTPUT_FILE_FMT_HT
@@ -690,37 +150,20 @@ struct camera {
struct str file_name;
};
-static INLINE void
-init_camera(struct mem_allocator* alloc, struct camera* cam) {
- ASSERT(alloc && cam);
- d3(cam->pos, STARDIS_DEFAULT_RENDERING_POS);
- d3(cam->tgt, STARDIS_DEFAULT_RENDERING_TGT);
- d3(cam->up, STARDIS_DEFAULT_RENDERING_UP);
- cam->fmt = STARDIS_DEFAULT_RENDERING_OUTPUT_FILE_FMT;
- cam->fov = STARDIS_DEFAULT_RENDERING_FOV;
- cam->spp = STARDIS_DEFAULT_RENDERING_SPP;
- cam->img_width = STARDIS_DEFAULT_RENDERING_IMG_WIDTH;
- cam->img_height = STARDIS_DEFAULT_RENDERING_IMG_HEIGHT;
- d2(cam->time_range, STARDIS_DEFAULT_RENDERING_TIME);
- cam->auto_look_at = 1;
- str_init(alloc, &cam->file_name);
-}
+void
+init_camera
+ (struct mem_allocator* alloc, struct camera* cam);
-static INLINE void
-release_camera(struct camera* cam) {
- ASSERT(cam);
- str_release(&cam->file_name);
-}
+/******************************************************************************/
+void
+release_camera(struct camera* cam);
-static INLINE void
-log_err_fn(const char* msg, void* ctx)
-{
+void
+log_err_fn(const char* msg, void* ctx);
#ifdef STARDIS_ENABLE_MPI
int initialized, rank = 0;
#endif
- ASSERT(msg);
- (void)ctx;
#ifdef STARDIS_ENABLE_MPI
CHK(MPI_Initialized(&initialized) == MPI_SUCCESS);
@@ -729,22 +172,13 @@ log_err_fn(const char* msg, void* ctx)
if(rank != 0) return;
#endif
-#ifdef OS_WINDOWS
- fprintf(stderr, "error: %s", msg);
-#else
- fprintf(stderr, "\x1b[31merror:\x1b[0m %s", msg);
-#endif
-}
-static INLINE void
-log_warn_fn(const char* msg, void* ctx)
-{
+void
+log_warn_fn(const char* msg, void* ctx);
#ifdef STARDIS_ENABLE_MPI
int initialized, rank = 0;
#endif
- ASSERT(msg);
- (void)ctx;
#ifdef STARDIS_ENABLE_MPI
CHK(MPI_Initialized(&initialized) == MPI_SUCCESS);
@@ -753,22 +187,13 @@ log_warn_fn(const char* msg, void* ctx)
if(rank != 0) return;
#endif
-#ifdef OS_WINDOWS
- fprintf(stderr, "warning: %s", msg);
-#else
- fprintf(stderr, "\x1b[33mwarning:\x1b[0m %s", msg);
-#endif
-}
-static INLINE void
-log_prt_fn(const char* msg, void* ctx)
-{
+void
+log_prt_fn(const char* msg, void* ctx);
#ifdef STARDIS_ENABLE_MPI
int initialized, rank = 0;
#endif
- ASSERT(msg);
- (void)ctx;
#ifdef STARDIS_ENABLE_MPI
CHK(MPI_Initialized(&initialized) == MPI_SUCCESS);
@@ -777,12 +202,6 @@ log_prt_fn(const char* msg, void* ctx)
if(rank != 0) return;
#endif
-#ifdef OS_WINDOWS
- fprintf(stderr, "message: %s", msg);
-#else
- fprintf(stderr, "\x1b[32moutput:\x1b[0m %s", msg);
-#endif
-}
struct counts {
unsigned smed_count, fmed_count, tbound_count, hbound_count,
@@ -853,12 +272,9 @@ struct stardis {
int mpi_rank;
};
-static INLINE unsigned
-allocate_stardis_medium_id(struct stardis* stardis)
-{
- ASSERT(stardis);
- return stardis->next_medium_id++;
-}
+unsigned
+allocate_stardis_medium_id
+ (struct stardis* stardis);
#ifdef STARDIS_ENABLE_MPI
extern LOCAL_SYM res_T
@@ -872,22 +288,22 @@ extern LOCAL_SYM void
finalize_mpi(void);
#endif
-extern LOCAL_SYM res_T
+res_T
stardis_init
(const struct args* args,
struct logger* logger,
struct mem_allocator* allocator,
struct stardis* stardis);
-extern LOCAL_SYM void
+void
stardis_release
(struct stardis* stardis);
-extern LOCAL_SYM res_T
+res_T
init_enclosures
(struct stardis* stardis);
-extern LOCAL_SYM res_T
+res_T
validate_properties
(const unsigned itri,
const unsigned properties[SG3D_PROP_TYPES_COUNT__],
diff --git a/src/stardis-args.c b/src/stardis-args.c
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define _POSIX_C_SOURCE 200809L /* strdup */
+#include "stardis-args.h"
#include "stardis-parsing.h"
#include "stardis-app.h"
#include "stardis-default.h"
diff --git a/src/stardis-args.h b/src/stardis-args.h
@@ -25,7 +25,6 @@ struct camera;
struct logger;
struct mem_allocator;
struct stardis;
-struct dummies;
enum stardis_mode {
/* Ordered so that print_multiple_modes() prints in alphabetical order */
@@ -106,33 +105,33 @@ struct args {
int verbose;
};
-extern LOCAL_SYM res_T
+res_T
init_args
(struct logger* logger,
struct mem_allocator* mem,
struct args** args);
-extern LOCAL_SYM void
+void
release_args
(struct args* args);
-extern void
+void
print_version
(FILE* stream);
-extern void
+void
short_help
(FILE* stream,
const char* prog);
-extern res_T
+res_T
parse_args
(const int argc,
char** argv,
struct args* args,
struct mem_allocator* allocator);
-extern res_T
+res_T
parse_camera
(struct logger* logger,
char* cam_param,
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -14,10 +14,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "stardis-app.h"
+#include "stardis-args.h"
+#include "stardis-description.h"
#include "stardis-output.h"
#include "stardis-compute.h"
+#include "stardis-parsing.h"
+#include "stardis-default.h"
#include "stardis-fluid.h"
+#include "stardis-fluid-prog.h"
#include "stardis-solid.h"
+#include "stardis-solid-prog.h"
+#include "stardis-sfconnect.h"
+#include "stardis-ssconnect.h"
#include <sdis.h>
#include <sdis_version.h>
@@ -40,7 +48,7 @@
#endif
/*******************************************************************************
- * Local Functions
+ * Local type; custom data for raytracing callbacks
******************************************************************************/
struct filter_ctx {
const struct stardis* stardis;
@@ -55,6 +63,10 @@ struct filter_ctx {
#define FILTER_CTX_DEFAULT__ \
{ NULL, S3D_INVALID_ID, NULL, { 0, 0, 0 }, FLT_MAX, 0, 0 }
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+
/* Filter used from a point query to determine not only one of the closest
* point, but the better one if there are more than one. In some circumstances
* it is not possible to determine the medium we are in using a given hit, but
@@ -182,6 +194,7 @@ check_probe_conform_to_type
(const struct stardis* stardis,
const int move2boundary,
double pos[3],
+ double time,
unsigned* iprim,
double uv[2])
{
@@ -245,36 +258,60 @@ check_probe_conform_to_type
logger_print(stardis->logger, LOG_WARNING,
"Could not determine the medium probe is in.\n");
} else {
- if(filter_ctx.desc->type == DESC_MAT_SOLID) {
- struct solid* solid = filter_ctx.desc->d.solid;
- ASSERT(solid->delta < INF);
+ if(DESC_IS_SOLID(filter_ctx.desc)) {
+ double delta;
+ const char* pppp;
+ if(filter_ctx.desc->type == DESC_MAT_SOLID) {
+ struct solid* solid = filter_ctx.desc->d.solid;
+ delta = solid->delta;
+ pppp = "";
+ } else {
+ struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog;
+ struct stardis_vertex vtx;
+ ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG);
+ d3_set(vtx.P, pos);
+ vtx.time = time;
+ delta = solid_prog->delta(&vtx, solid_prog->prog_data);
+ pppp = "programmed ";
+ }
+ ASSERT(delta < INF);
logger_print(stardis->logger, LOG_OUTPUT,
- "Probe was in solid '%s'.\n", str_cget(&solid->name));
- if(filter_ctx.dist > 2 * solid->delta) {
+ "Probe was in %ssolid '%s'.\n",
+ pppp, str_cget(get_description_name(filter_ctx.desc)));
+ if(filter_ctx.dist > 2 * delta) {
logger_print(stardis->logger, LOG_ERROR,
"Probe moved to (%g, %g, %g), primitive %u, uv = (%g, %g).\n",
SPLIT3(filter_ctx.pos), hit.prim.prim_id, SPLIT2(hit.uv));
logger_print(stardis->logger, LOG_ERROR,
"Move is %g delta long. Use -p instead of -P.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
res = RES_BAD_ARG;
goto error;
}
- if(filter_ctx.dist > 0.5 * solid->delta) {
+ if(filter_ctx.dist > 0.5 * delta) {
logger_print(stardis->logger, LOG_WARNING,
"Probe was %g delta from closest boundary. "
"Consider using -p instead of -P.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
} else {
if(filter_ctx.dist != 0)
logger_print(stardis->logger, LOG_OUTPUT,
"Probe was %g delta from closest boundary.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
}
} else {
+ const char* pppp;
+ ASSERT(DESC_IS_FLUID(filter_ctx.desc));
/* TODO: check move length wrt local geometry? */
+ if(filter_ctx.desc->type == DESC_MAT_FLUID) {
+ pppp = "";
+ } else {
+ ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG);
+ pppp = "programmed ";
+ }
logger_print(stardis->logger, LOG_OUTPUT,
- "Probe was in fluid '%s'.\n", str_cget(&filter_ctx.desc->d.fluid->name));
+ "Probe was in %sfluid '%s'.\n",
+ pppp, str_cget(get_description_name(filter_ctx.desc)));
logger_print(stardis->logger, LOG_OUTPUT,
"Probe distance from closest boundary was %g.\n", filter_ctx.dist);
}
@@ -328,36 +365,54 @@ check_probe_conform_to_type
res = RES_BAD_ARG;
goto error;
}
- logger_print(stardis->logger, LOG_OUTPUT,
- "Probe is in solid '%s'.\n", str_cget(&filter_ctx.desc->d.solid->name));
- if(filter_ctx.desc->type == DESC_MAT_SOLID) {
- struct solid* solid = filter_ctx.desc->d.solid;
- if(filter_ctx.dist < 0.25 * solid->delta) {
+ if(DESC_IS_SOLID(filter_ctx.desc)) {
+ double delta;
+ if(filter_ctx.desc->type == DESC_MAT_SOLID) {
+ struct solid* solid = filter_ctx.desc->d.solid;
+ delta = solid->delta;
+ } else {
+ struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog;
+ struct stardis_vertex vtx;
+ ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG);
+ d3_set(vtx.P, pos);
+ vtx.time = time;
+ delta = solid_prog->delta(&vtx, solid_prog->prog_data);
+ }
+ if(filter_ctx.dist < 0.25 * delta) {
logger_print(stardis->logger, LOG_ERROR,
"Probe is %g delta from closest boundary. Use -P instead of -p.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
logger_print(stardis->logger, LOG_ERROR,
"Closest geometry is primitive %u, uv = (%g, %g).\n",
hit.prim.prim_id, SPLIT2(hit.uv));
res = RES_BAD_ARG;
goto error;
}
- if(filter_ctx.dist < 0.5 * solid->delta) {
+ if(filter_ctx.dist < 0.5 * delta) {
logger_print(stardis->logger, LOG_WARNING,
"Probe is %g delta from closest boundary. "
"Consider using -P instead of -p.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
} else {
logger_print(stardis->logger, LOG_OUTPUT,
"Probe is %g delta from closest boundary.\n",
- filter_ctx.dist / solid->delta);
+ filter_ctx.dist / delta);
}
} else {
- logger_print(stardis->logger, LOG_WARNING,
- "Probe is in fluid '%s': computing fluid temperature, "
- "not using a specific position.\n",
- str_cget(&filter_ctx.desc->d.fluid->name));
+ ASSERT(DESC_IS_FLUID(filter_ctx.desc));
/* In fluid; TODO: check distance wrt local geometry (use 4V/S?) */
+ if(filter_ctx.desc->type == DESC_MAT_FLUID) {
+ logger_print(stardis->logger, LOG_WARNING,
+ "Probe is in fluid '%s': computing fluid temperature, "
+ "not using a specific position.\n",
+ str_cget(&filter_ctx.desc->d.fluid->name));
+ } else {
+ ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG);
+ logger_print(stardis->logger, LOG_WARNING,
+ "Probe is in fluid_prog '%s': computing fluid temperature, "
+ "not using a specific position.\n",
+ str_cget(&filter_ctx.desc->d.fluid_prog->name));
+ }
}
}
@@ -433,7 +488,8 @@ compute_probe(struct stardis* stardis, struct time* start)
ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE));
- ERR(check_probe_conform_to_type(stardis, 0, stardis->probe, &iprim, uv));
+ ERR(check_probe_conform_to_type(stardis, 0, stardis->probe,
+ stardis->time_range[0], &iprim, uv));
args.nrealisations = stardis->samples;
d3_set(args.position, stardis->probe);
@@ -538,7 +594,8 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
#endif
ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE));
- ERR(check_probe_conform_to_type(stardis, 1, stardis->probe, &iprim, uv));
+ ERR(check_probe_conform_to_type(stardis, 1, stardis->probe,
+ stardis->time_range[0], &iprim, uv));
ASSERT(iprim != UINT_MAX);
ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d,
@@ -560,7 +617,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
const struct description* d;
ASSERT(prop[SG3D_FRONT] < dcount);
d = descriptions + prop[SG3D_FRONT];
- ASSERT(DESC_IS_MEDIUM(d->type));
+ ASSERT(DESC_IS_MEDIUM(d));
medium_name = str_cget(get_description_name(d));
compute_side = SDIS_FRONT;
compute_side_name = "FRONT";
@@ -569,7 +626,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
const struct description* d;
ASSERT(prop[SG3D_BACK] < dcount);
d = descriptions + prop[SG3D_BACK];
- ASSERT(DESC_IS_MEDIUM(d->type));
+ ASSERT(DESC_IS_MEDIUM(d));
medium_name = str_cget(get_description_name(d));
compute_side = SDIS_BACK;
compute_side_name = "BACK";
@@ -589,8 +646,8 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
fd = descriptions + prop[SG3D_FRONT];
bd = descriptions + prop[SG3D_BACK];
- ASSERT(DESC_IS_MEDIUM(fd->type));
- ASSERT(DESC_IS_MEDIUM(bd->type));
+ ASSERT(DESC_IS_MEDIUM(fd));
+ ASSERT(DESC_IS_MEDIUM(bd));
description_get_medium_id(fd, &fmat_id);
description_get_medium_id(bd, &bmat_id);
diff --git a/src/stardis-compute.h b/src/stardis-compute.h
@@ -33,13 +33,13 @@ find_medium_by_name
const struct str* name,
unsigned* id); /* Can be NULL */
-extern LOCAL_SYM res_T
+res_T
stardis_compute
(struct stardis* stardis,
struct time* start);
-extern LOCAL_SYM res_T
+res_T
read_compute_surface
(struct stardis* stardis);
-#endif
-\ No newline at end of file
+#endif
diff --git a/src/stardis-description.c b/src/stardis-description.c
@@ -0,0 +1,271 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-description.h"
+#include "stardis-prog-properties.h"
+#include "stardis-solid.h"
+#include "stardis-solid-prog.h"
+#include "stardis-fluid.h"
+#include "stardis-fluid-prog.h"
+#include "stardis-hbound.h"
+#include "stardis-hbound-prog.h"
+#include "stardis-tbound.h"
+#include "stardis-tbound-prog.h"
+#include "stardis-fbound.h"
+#include "stardis-fbound-prog.h"
+#include "stardis-sfconnect.h"
+#include "stardis-sfconnect-prog.h"
+#include "stardis-ssconnect.h"
+#include "stardis-ssconnect-prog.h"
+#include "stardis-program.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+res_T
+init_description
+ (struct mem_allocator* alloc,
+ struct description* desc)
+{
+ ASSERT(desc);
+ (void)alloc;
+ desc->type = DESCRIPTION_TYPE_COUNT__;
+ desc->d.fluid = NULL;
+ return RES_OK;
+}
+
+void
+release_description
+ (struct description* desc,
+ struct mem_allocator* allocator)
+{
+ ASSERT(desc && allocator);
+ switch (desc->type) {
+ case DESC_MAT_SOLID:
+ release_solid(desc->d.solid, allocator);
+ break;
+ case DESC_MAT_SOLID_PROG:
+ release_solid_prog(desc->d.solid_prog, allocator);
+ break;
+ case DESC_MAT_FLUID:
+ release_fluid(desc->d.fluid, allocator);
+ break;
+ case DESC_MAT_FLUID_PROG:
+ release_fluid_prog(desc->d.fluid_prog, allocator);
+ break;
+ case DESC_BOUND_H_FOR_SOLID:
+ case DESC_BOUND_H_FOR_FLUID:
+ release_h_boundary(desc->d.h_boundary, allocator);
+ break;
+ case DESC_BOUND_H_FOR_SOLID_PROG:
+ case DESC_BOUND_H_FOR_FLUID_PROG:
+ release_h_boundary_prog(desc->d.h_boundary_prog, allocator);
+ break;
+ case DESC_BOUND_T_FOR_SOLID:
+ release_t_boundary(desc->d.t_boundary, allocator);
+ break;
+ case DESC_BOUND_T_FOR_SOLID_PROG:
+ release_t_boundary_prog(desc->d.t_boundary_prog, allocator);
+ break;
+ case DESC_BOUND_F_FOR_SOLID:
+ release_f_boundary(desc->d.f_boundary, allocator);
+ break;
+ case DESC_BOUND_F_FOR_SOLID_PROG:
+ release_f_boundary_prog(desc->d.f_boundary_prog, allocator);
+ break;
+ case DESC_SOLID_FLUID_CONNECT:
+ release_sf_connect(desc->d.sf_connect, allocator);
+ break;
+ case DESC_SOLID_FLUID_CONNECT_PROG:
+ release_sf_connect_prog(desc->d.sf_connect_prog, allocator);
+ break;
+ case DESC_SOLID_SOLID_CONNECT:
+ release_ss_connect(desc->d.ss_connect, allocator);
+ break;
+ case DESC_SOLID_SOLID_CONNECT_PROG:
+ release_ss_connect_prog(desc->d.ss_connect_prog, allocator);
+ break;
+ case DESC_PROGRAM:
+ release_program(desc->d.program, allocator);
+ break;
+ default:
+ FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
+ }
+}
+
+res_T
+str_print_description
+ (struct str* str,
+ const unsigned rank,
+ const struct description* desc)
+{
+ res_T res = RES_OK;
+ ASSERT(str && desc);
+ str_clear(str);
+ ERR(str_printf(str, "Description %u: ", rank));
+ switch (desc->type) {
+ case DESC_MAT_SOLID:
+ ERR(str_print_solid(str, desc->d.solid));
+ break;
+ case DESC_MAT_SOLID_PROG:
+ ERR(str_print_solid_prog(str, desc->d.solid_prog));
+ break;
+ case DESC_MAT_FLUID:
+ ERR(str_print_fluid(str, desc->d.fluid));
+ break;
+ case DESC_MAT_FLUID_PROG:
+ ERR(str_print_fluid_prog(str, desc->d.fluid_prog));
+ break;
+ case DESC_BOUND_T_FOR_SOLID:
+ ERR(str_print_t_boundary(str, desc->d.t_boundary));
+ break;
+ case DESC_BOUND_T_FOR_SOLID_PROG:
+ ERR(str_print_t_boundary_prog(str, desc->d.t_boundary_prog));
+ break;
+ case DESC_BOUND_H_FOR_SOLID:
+ case DESC_BOUND_H_FOR_FLUID:
+ ERR(str_print_h_boundary(str, desc));
+ break;
+ case DESC_BOUND_H_FOR_SOLID_PROG:
+ case DESC_BOUND_H_FOR_FLUID_PROG:
+ ERR(str_print_h_boundary_prog(str, desc));
+ break;
+ case DESC_BOUND_F_FOR_SOLID:
+ ERR(str_print_f_boundary(str, desc->d.f_boundary));
+ break;
+ case DESC_BOUND_F_FOR_SOLID_PROG:
+ ERR(str_print_f_boundary_prog(str, desc->d.f_boundary_prog));
+ break;
+ case DESC_SOLID_FLUID_CONNECT:
+ ERR(str_print_sf_connect(str, desc->d.sf_connect));
+ break;
+ case DESC_SOLID_FLUID_CONNECT_PROG:
+ ERR(str_print_sf_connect_prog(str, desc->d.sf_connect_prog));
+ break;
+ case DESC_SOLID_SOLID_CONNECT:
+ ERR(str_print_ss_connect(str, desc->d.ss_connect));
+ break;
+ case DESC_SOLID_SOLID_CONNECT_PROG:
+ ERR(str_print_ss_connect_prog(str, desc->d.ss_connect_prog));
+ break;
+ case DESC_PROGRAM:
+ ERR(str_print_program(str, desc->d.program));
+ break;
+ default:
+ FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
+ }
+end:
+ return res;
+error:
+ goto end;
+}
+
+const struct str*
+get_description_name
+ (const struct description* desc)
+{
+ ASSERT(desc);
+ switch (desc->type) {
+ case DESC_MAT_SOLID:
+ return &desc->d.solid->name;
+ case DESC_MAT_SOLID_PROG:
+ return &desc->d.solid_prog->name;
+ case DESC_MAT_FLUID:
+ return &desc->d.fluid->name;
+ case DESC_MAT_FLUID_PROG:
+ return &desc->d.fluid_prog->name;
+ case DESC_BOUND_T_FOR_SOLID:
+ return &desc->d.t_boundary->name;
+ case DESC_BOUND_T_FOR_SOLID_PROG:
+ return &desc->d.t_boundary_prog->name;
+ case DESC_BOUND_H_FOR_SOLID:
+ case DESC_BOUND_H_FOR_FLUID:
+ return &desc->d.h_boundary->name;
+ case DESC_BOUND_H_FOR_SOLID_PROG:
+ case DESC_BOUND_H_FOR_FLUID_PROG:
+ return &desc->d.h_boundary_prog->name;
+ case DESC_BOUND_F_FOR_SOLID:
+ return &desc->d.f_boundary->name;
+ case DESC_BOUND_F_FOR_SOLID_PROG:
+ return &desc->d.f_boundary_prog->name;
+ case DESC_SOLID_FLUID_CONNECT:
+ return &desc->d.sf_connect->name;
+ case DESC_SOLID_FLUID_CONNECT_PROG:
+ return &desc->d.sf_connect_prog->name;
+ case DESC_SOLID_SOLID_CONNECT:
+ return &desc->d.ss_connect->name;
+ case DESC_SOLID_SOLID_CONNECT_PROG:
+ return &desc->d.ss_connect_prog->name;
+ case DESC_PROGRAM:
+ return &desc->d.program->name;
+ default:
+ FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
+ }
+}
+
+void
+description_get_medium_id
+ (const struct description* desc,
+ unsigned* id)
+{
+ ASSERT(desc && id);
+ switch (desc->type) {
+ case DESC_MAT_SOLID:
+ *id = desc->d.solid->solid_id;
+ return;
+ case DESC_MAT_SOLID_PROG:
+ *id = desc->d.solid_prog->solid_id;
+ return;
+ case DESC_MAT_FLUID:
+ *id = desc->d.fluid->fluid_id;
+ return;
+ case DESC_MAT_FLUID_PROG:
+ *id = desc->d.fluid_prog->fluid_id;
+ return;
+ case DESC_BOUND_H_FOR_SOLID:
+ case DESC_BOUND_H_FOR_FLUID:
+ *id = desc->d.h_boundary->mat_id;
+ return;
+ case DESC_BOUND_H_FOR_SOLID_PROG:
+ case DESC_BOUND_H_FOR_FLUID_PROG:
+ *id = desc->d.h_boundary_prog->mat_id;
+ return;
+ case DESC_BOUND_T_FOR_SOLID:
+ *id = desc->d.t_boundary->mat_id;
+ return;
+ case DESC_BOUND_T_FOR_SOLID_PROG:
+ *id = desc->d.t_boundary_prog->mat_id;
+ return;
+ case DESC_BOUND_F_FOR_SOLID:
+ *id = desc->d.f_boundary->mat_id;
+ return;
+ case DESC_BOUND_F_FOR_SOLID_PROG:
+ *id = desc->d.f_boundary_prog->mat_id;
+ return;
+ case DESC_SOLID_FLUID_CONNECT: /* No medium linked to SF */
+ case DESC_SOLID_SOLID_CONNECT: /* No medium linked to SS */
+ case DESC_SOLID_FLUID_CONNECT_PROG: /* No medium linked to SF */
+ case DESC_SOLID_SOLID_CONNECT_PROG: /* No medium linked to SS */
+ case DESC_PROGRAM: /* No medium linked to PRORGRAM */
+ default:
+ FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
+ }
+}
diff --git a/src/stardis-description.h b/src/stardis-description.h
@@ -0,0 +1,154 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef STARDIS_DESCRIPTION_H
+#define STARDIS_DESCRIPTION_H
+
+#include "stardis-prog-properties.h"
+
+#include <rsys/rsys.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/* Forward declarations */
+struct mem_allocator;
+
+/* Different types of descriptions */
+enum description_type {
+ DESC_MAT_SOLID,
+ DESC_MAT_FLUID,
+ DESC_BOUND_H_FOR_FLUID,
+ DESC_BOUND_H_FOR_SOLID,
+ DESC_BOUND_T_FOR_SOLID,
+ DESC_BOUND_F_FOR_SOLID,
+ DESC_SOLID_FLUID_CONNECT,
+ DESC_SOLID_SOLID_CONNECT,
+ DESC_MAT_SOLID_PROG,
+ DESC_MAT_FLUID_PROG,
+ DESC_BOUND_H_FOR_FLUID_PROG,
+ DESC_BOUND_H_FOR_SOLID_PROG,
+ DESC_BOUND_T_FOR_SOLID_PROG,
+ DESC_BOUND_F_FOR_SOLID_PROG,
+ DESC_SOLID_FLUID_CONNECT_PROG,
+ DESC_SOLID_SOLID_CONNECT_PROG,
+ DESC_PROGRAM,
+ DESCRIPTION_TYPE_COUNT__
+};
+
+#define DESC_IS_H(D) \
+ ((D)->type == DESC_BOUND_H_FOR_SOLID || (D)->type == DESC_BOUND_H_FOR_FLUID \
+ || (D)->type == DESC_BOUND_H_FOR_SOLID_PROG \
+ || (D)->type == DESC_BOUND_H_FOR_FLUID_PROG)
+#define DESC_IS_T(D) \
+ ((D)->type == DESC_BOUND_T_FOR_SOLID \
+ || (D)->type == DESC_BOUND_T_FOR_SOLID_PROG)
+#define DESC_IS_F(D) \
+ ((D)->type == DESC_BOUND_F_FOR_SOLID \
+ || (D)->type == DESC_BOUND_F_FOR_SOLID_PROG)
+#define DESC_IS_SOLID(D) \
+ ((D)->type == DESC_MAT_SOLID || (D)->type == DESC_MAT_SOLID_PROG)
+#define DESC_IS_FLUID(D) \
+ ((D)->type == DESC_MAT_FLUID || (D)->type == DESC_MAT_FLUID_PROG)
+#define DESC_IS_MEDIUM(D) \
+ (DESC_IS_SOLID(D) || DESC_IS_FLUID(D))
+#define DESC_IS_BOUNDARY(D) \
+ (DESC_IS_H(D) || DESC_IS_T(D) || DESC_IS_F(D))
+#define DESC_IS_SOLID_FLUID(D) \
+ ((D)->type == DESC_SOLID_FLUID_CONNECT \
+ || (D)->type == DESC_SOLID_FLUID_CONNECT_PROG)
+#define DESC_IS_SOLID_SOLID(D) \
+ ((D)->type == DESC_SOLID_SOLID_CONNECT \
+ || (D)->type == DESC_SOLID_SOLID_CONNECT_PROG)
+#define DESC_IS_CONNECTION(D) \
+ (DESC_IS_SOLID_FLUID(D) || DESC_IS_SOLID_SOLID(D))
+#define DESC_IS_PROG(D) \
+ ((D)->type == DESC_MAT_SOLID_PROG || (D)->type == DESC_MAT_FLUID_PROG \
+ || (D)->type == DESC_BOUND_H_FOR_FLUID_PROG \
+ || (D)->type == DESC_BOUND_H_FOR_SOLID_PROG \
+ || (D)->type == DESC_BOUND_T_FOR_SOLID_PROG \
+ || (D)->type == DESC_BOUND_F_FOR_SOLID_PROG \
+ || (D)->type == DESC_SOLID_FLUID_CONNECT_PROG \
+ || (D)->type == DESC_SOLID_SOLID_CONNECT_PROG)
+
+/******************************************************************************/
+
+struct fluid;
+struct fluid_prog;
+struct solid;
+struct solid_prog;
+struct t_boundary;
+struct t_boundary_prog;
+struct f_boundary;
+struct f_boundary_prog;
+struct h_boundary;
+struct h_boundary_prog;
+struct solid_fluid_connect;
+struct solid_fluid_connect_prog;
+struct solid_solid_connect;
+struct solid_solid_connect_prog;
+struct program;
+
+struct description {
+ enum description_type type;
+ union {
+ struct fluid* fluid;
+ struct fluid_prog* fluid_prog;
+ struct solid* solid;
+ struct solid_prog* solid_prog;
+ struct t_boundary* t_boundary;
+ struct t_boundary_prog* t_boundary_prog;
+ struct f_boundary* f_boundary;
+ struct f_boundary_prog* f_boundary_prog;
+ struct h_boundary* h_boundary;
+ struct h_boundary_prog* h_boundary_prog;
+ struct solid_fluid_connect* sf_connect;
+ struct solid_fluid_connect_prog* sf_connect_prog;
+ struct solid_solid_connect* ss_connect;
+ struct solid_solid_connect_prog* ss_connect_prog;
+ struct program* program;
+ } d;
+};
+
+/******************************************************************************/
+res_T
+init_description
+ (struct mem_allocator* alloc,
+ struct description* desc);
+
+void
+release_description
+ (struct description* desc,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_description
+ (struct str* str,
+ const unsigned rank,
+ const struct description* desc);
+
+const struct str*
+get_description_name
+ (const struct description* desc);
+
+void
+description_get_medium_id
+ (const struct description* desc,
+ unsigned* id);
+
+#endif
diff --git a/src/stardis-fbound-prog.c b/src/stardis-fbound-prog.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-fbound-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+
+res_T
+init_f_boundary_prog
+ (struct mem_allocator* allocator,
+ struct f_boundary_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->mat_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_f_boundary_prog
+ (struct f_boundary_prog* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ str_release(&bound->prog_name);
+ str_release(&bound->args);
+ if(bound->prog_data)
+ bound->release(bound->prog_data);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_f_boundary_prog
+ (struct str* str,
+ const struct f_boundary_prog* b)
+{
+ res_T res = RES_OK;
+ ASSERT(str && b);
+ ERR(str_append_printf(str,
+ "programmed F boundary for SOLID '%s': lib='%s', args=[%s]"
+ " (using medium %u as external medium)",
+ str_cget(&b->name), str_cget(&b->prog_name),
+ str_cget(&b->args), b->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-fbound-prog.h b/src/stardis-fbound-prog.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_FBOUND_PROG_H
+#define SDIS_FBOUND_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct stardis;
+struct mem_allocator;
+struct fluid_prog;
+struct description;
+struct program;
+
+/*******************************************************************************
+ * F boundary prog data
+ ******************************************************************************/
+struct f_boundary_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*flux)(const struct stardis_interface_fragment*, void*);
+ unsigned mat_id;
+};
+
+res_T
+init_f_boundary_prog
+ (struct mem_allocator* allocator,
+ struct f_boundary_prog** dst);
+
+void
+release_f_boundary_prog
+ (struct f_boundary_prog* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_f_boundary_prog
+ (struct str* str,
+ const struct f_boundary_prog* b);
+
+#endif
diff --git a/src/stardis-fbound.c b/src/stardis-fbound.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-fbound.h"
+#include "stardis-fluid.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_f_boundary
+ (struct mem_allocator* allocator,
+ struct f_boundary** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_initialized = 1;
+ (*dst)->mat_id = UINT_MAX;
+ (*dst)->imposed_flux = -1;
+end:
+ return res;
+error:
+ if(str_initialized) str_release(&(*dst)->name);
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_f_boundary
+ (struct f_boundary* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_f_boundary
+ (struct str* str,
+ const struct f_boundary* bound)
+{
+ res_T res = RES_OK;
+ ASSERT(str && bound);
+ ERR(str_append_printf(str,
+ "F boundary for SOLID '%s': flux=%g (using medium %u as external medium)",
+ str_cget(&bound->name), bound->imposed_flux, bound->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-fbound.h b/src/stardis-fbound.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_FBOUND_H
+#define SDIS_FBOUND_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct mem_allocator;
+
+/*******************************************************************************
+ * F boundary type
+ ******************************************************************************/
+struct f_boundary {
+ struct str name;
+ double imposed_flux;
+ unsigned mat_id;
+};
+
+res_T
+init_f_boundary
+ (struct mem_allocator* allocator,
+ struct f_boundary** dst);
+
+void
+release_f_boundary
+ (struct f_boundary* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_f_boundary
+ (struct str* str,
+ const struct f_boundary* bound);
+
+#endif
diff --git a/src/stardis-fluid-prog.c b/src/stardis-fluid-prog.c
@@ -0,0 +1,198 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-fluid-prog.h"
+#include "stardis-app.h"
+#include "stardis-prog-properties.h"
+#include "stardis-app.h"
+
+#include <rsys/mem_allocator.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+static double
+fluid_prog_get_calorific_capacity
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct fluid_prog* const* fluid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*fluid_props)->cp(&v, (*fluid_props)->prog_data);
+}
+
+static double
+fluid_prog_get_volumic_mass
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct fluid_prog* const* fluid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*fluid_props)->rho(&v, (*fluid_props)->prog_data);
+}
+
+static double
+fluid_prog_get_temperature
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct fluid_prog* const* fluid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*fluid_props)->temp(&v, (*fluid_props)->prog_data);
+}
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+create_solver_fluid_prog
+ (struct stardis* stardis,
+ const struct fluid_prog* fluid_props)
+{
+ res_T res = RES_OK;
+ struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL;
+ struct sdis_data* data = NULL;
+ const struct fluid_prog** props;
+
+ ASSERT(stardis && fluid_props);
+ fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity;
+ fluid_shader.volumic_mass = fluid_prog_get_volumic_mass;
+ fluid_shader.temperature = fluid_prog_get_temperature;
+ ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*),
+ ALIGNOF(struct fluid_prog*), NULL, &data));
+
+ props = sdis_data_get(data); /* Fetch the allocated memory space */
+ *props = fluid_props;
+ if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) {
+ ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1));
+ }
+ ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]);
+ ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data,
+ darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id));
+
+end:
+ if(data) SDIS(data_ref_put(data));
+ return res;
+error:
+ goto end;
+}
+
+res_T
+create_solver_external_fluid_prog
+ (struct stardis* stardis,
+ const struct fluid_prog* fluid_props)
+{
+ res_T res = RES_OK;
+ struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL;
+ struct sdis_data* data = NULL;
+ const struct fluid_prog** props;
+
+ ASSERT(stardis && fluid_props);
+ fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity;
+ fluid_shader.volumic_mass = fluid_prog_get_volumic_mass;
+ fluid_shader.temperature = fluid_prog_get_temperature;
+ /* temperature has to be provided by h_boundary_prog */
+ ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*),
+ ALIGNOF(struct fluid_prog*), NULL, &data));
+
+ props = sdis_data_get(data); /* Fetch the allocated memory space */
+ *props = fluid_props;
+ if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) {
+ ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1));
+ }
+ ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]);
+ ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data,
+ darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id));
+
+end:
+ if(data) SDIS(data_ref_put(data));
+ return res;
+error:
+ goto end;
+}
+
+res_T
+init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->desc_id = UINT_MAX;
+ (*dst)->fluid_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_fluid_prog
+ (struct fluid_prog* fluid,
+ struct mem_allocator* allocator)
+{
+ ASSERT(fluid && allocator);
+ str_release(&fluid->name);
+ str_release(&fluid->prog_name);
+ str_release(&fluid->args);
+
+ if(fluid->prog_data
+ && fluid->release) /* can be NULL if external fluid */
+ {
+ fluid->release(fluid->prog_data);
+ }
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, fluid);
+}
+
+res_T
+str_print_fluid_prog(struct str* str, const struct fluid_prog* f)
+{
+ res_T res = RES_OK;
+ ASSERT(str && f);
+ ERR(str_append_printf(str,
+ "programmed fluid '%s': lib='%s', args=[%s] (it is medium %u)",
+ str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args),
+ f->fluid_id));
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-fluid-prog.h b/src/stardis-fluid-prog.h
@@ -0,0 +1,75 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_FLUID_PROG_H
+#define SDIS_FLUID_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct stardis;
+struct mem_allocator;
+struct program;
+
+/*******************************************************************************
+ * Fluid prog data
+ ******************************************************************************/
+struct fluid_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ int is_outside; /* the fluid is used for a boundary */
+ unsigned desc_id; /* id of the boundary; meaningful if is_outside */
+ unsigned fluid_id;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*rho)(const struct stardis_vertex*, void*);
+ double (*cp)(const struct stardis_vertex*, void*);
+ double (*temp)(const struct stardis_vertex*, void*);
+ double* (*t_range)(void*, double trange[2]);
+};
+
+res_T
+create_solver_fluid_prog
+ (struct stardis* stardis,
+ const struct fluid_prog* fluid_props);
+
+res_T
+create_solver_external_fluid_prog
+ (struct stardis* stardis,
+ const struct fluid_prog* fluid_props);
+
+res_T
+init_fluid_prog
+ (struct mem_allocator* allocator,
+ struct fluid_prog** dst);
+
+void
+release_fluid_prog
+ (struct fluid_prog* fluid,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_fluid_prog
+ (struct str* str,
+ const struct fluid_prog* fluid);
+
+#endif
diff --git a/src/stardis-fluid.c b/src/stardis-fluid.c
@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "stardis-fluid.h"
-#include "stardis-compute.h"
#include "stardis-app.h"
#include <sdis.h>
@@ -153,15 +152,15 @@ str_print_fluid(struct str* str, const struct fluid* f)
{
res_T res = RES_OK;
ASSERT(str && f);
- STR_APPEND_PRINTF(str, "Fluid '%s': rho=%g cp=%g",
- ARG3( str_cget(&f->name), f->rho, f->cp ) );
+ ERR(str_append_printf(str, "Fluid '%s': rho=%g cp=%g",
+ str_cget(&f->name), f->rho, f->cp));
if(f->tinit >= 0) {
- STR_APPEND_PRINTF(str, " Tinit=%g", ARG1( f->tinit ) );
+ ERR(str_append_printf(str, " Tinit=%g", f->tinit));
}
if(f->imposed_temperature >= 0) {
- STR_APPEND_PRINTF(str, " Temp=%g", ARG1( f->imposed_temperature ) );
+ ERR(str_append_printf(str, " Temp=%g", f->imposed_temperature));
}
- STR_APPEND_PRINTF(str, " (it is medium %u)", ARG1( f->fluid_id ) );
+ ERR(str_append_printf(str, " (it is medium %u)", f->fluid_id));
end:
return res;
error:
diff --git a/src/stardis-fluid.h b/src/stardis-fluid.h
@@ -36,7 +36,7 @@ struct fluid {
double t0; /* End time of tinit */
int is_outside; /* the fluid is used for a boundary */
int is_green; /* green computation (nothing to do with fluid itself) */
- unsigned desc_id; /* id of the boundary; meaningful if is_outside */
+ unsigned desc_id;
unsigned fluid_id;
};
@@ -45,15 +45,15 @@ create_solver_fluid
(struct stardis* stardis,
const struct fluid* fluid_props);
-LOCAL_SYM res_T
+res_T
init_fluid(struct mem_allocator* allocator, struct fluid** dst);
-LOCAL_SYM void
+void
release_fluid
(struct fluid* desc,
struct mem_allocator* allocator);
-LOCAL_SYM res_T
+res_T
str_print_fluid(struct str* str, const struct fluid* s);
#endif
diff --git a/src/stardis-hbound-prog.c b/src/stardis-hbound-prog.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-hbound-prog.h"
+#include "stardis-fluid-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_h_boundary_prog
+ (struct mem_allocator* allocator,
+ struct h_boundary_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->mat_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_h_boundary_prog
+ (struct h_boundary_prog* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ str_release(&bound->prog_name);
+ str_release(&bound->args);
+ if(bound->prog_data)
+ bound->release(bound->prog_data);
+ if(bound->possible_external_fluid)
+ release_fluid_prog(bound->possible_external_fluid, allocator);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_h_boundary_prog
+ (struct str* str,
+ const struct description* desc)
+{
+ res_T res = RES_OK;
+ const struct h_boundary_prog* b;
+ ASSERT(str && desc && DESC_IS_H(desc));
+ b = desc->d.h_boundary_prog;
+ ERR(str_append_printf(str,
+ "programmed H boundary for %s '%s': lib='%s', args=[%s] "
+ "(using medium %u as external medium)",
+ (desc->type == DESC_BOUND_H_FOR_SOLID_PROG ? "solid" : "fluid"),
+ str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args),
+ b->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
+
+double
+h_bound_prog_get_hmax
+ (struct h_boundary_prog* h_boundary_props)
+{
+ return h_boundary_props->hmax(h_boundary_props->prog_data);
+}
diff --git a/src/stardis-hbound-prog.h b/src/stardis-hbound-prog.h
@@ -0,0 +1,75 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_HBOUND_PROG_H
+#define SDIS_HBOUND_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct mem_allocator;
+struct fluid_prog;
+struct description;
+struct program;
+
+/*******************************************************************************
+ * H boundary prog data
+ ******************************************************************************/
+struct h_boundary_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*ref_temp)(const struct stardis_interface_fragment*, void*);
+ double (*emissivity)(const struct stardis_interface_fragment*, void*);
+ double (*alpha)(const struct stardis_interface_fragment*, void*);
+ double (*hc)(const struct stardis_interface_fragment*, void*);
+ double (*hmax)(void*);
+ double* (*t_range)(void*, double trange[2]);
+ /* for h for solid */
+ double (*boundary_temp)(const struct stardis_interface_fragment*, void*);
+ /* for h for fluid */
+ double (*fluid_temp)(const struct stardis_vertex*, void*);
+ unsigned mat_id;
+ struct fluid_prog* possible_external_fluid; /* if H for solid */
+};
+
+res_T
+init_h_boundary_prog
+ (struct mem_allocator* allocator,
+ struct h_boundary_prog** dst);
+
+void
+release_h_boundary_prog
+ (struct h_boundary_prog* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_h_boundary_prog
+ (struct str* str,
+ const struct description* bound);
+
+double
+h_bound_prog_get_hmax
+ (struct h_boundary_prog* h_boundary_props);
+
+#endif
diff --git a/src/stardis-hbound.c b/src/stardis-hbound.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-hbound.h"
+#include "stardis-fluid.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_h_boundary
+ (struct mem_allocator* allocator,
+ struct h_boundary** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_initialized = 1;
+ (*dst)->imposed_temperature = -1;
+ (*dst)->mat_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) str_release(&(*dst)->name);
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_h_boundary
+ (struct h_boundary* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ if(bound->possible_external_fluid)
+ release_fluid(bound->possible_external_fluid, allocator);
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_h_boundary
+ (struct str* str,
+ const struct description* desc)
+{
+ res_T res = RES_OK;
+ const struct h_boundary* b;
+ ASSERT(str && desc && DESC_IS_H(desc));
+ b = desc->d.h_boundary;
+ ERR(str_append_printf(str,
+ "H boundary for %s '%s': ref_temperature=%g emissivity=%g specular_fraction=%g "
+ "hc=%g T=%g (using medium %u as external medium)",
+ (desc->type == DESC_BOUND_H_FOR_SOLID ? "solid" : "fluid"),
+ str_cget(&b->name), b->ref_temperature, b->emissivity,
+ b->specular_fraction, b->hc, b->imposed_temperature, b->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-hbound.h b/src/stardis-hbound.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_HBOUND_H
+#define SDIS_HBOUND_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct mem_allocator;
+struct fluid;
+struct description;
+
+/*******************************************************************************
+ * H boundary type
+ ******************************************************************************/
+struct h_boundary {
+ struct str name;
+ double ref_temperature;
+ double emissivity;
+ double specular_fraction;
+ double hc;
+ double imposed_temperature;
+ unsigned mat_id;
+ struct fluid* possible_external_fluid; /* if H for solid */
+};
+
+res_T
+init_h_boundary
+ (struct mem_allocator* allocator,
+ struct h_boundary** dst);
+
+void
+release_h_boundary
+ (struct h_boundary* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_h_boundary
+ (struct str* str,
+ const struct description* desc);
+
+#endif
diff --git a/src/stardis-intface.c b/src/stardis-intface.c
@@ -18,6 +18,17 @@
#include "stardis-compute.h"
#include "stardis-output.h"
#include "stardis-solid.h"
+#include "stardis-hbound.h"
+#include "stardis-hbound-prog.h"
+#include "stardis-tbound.h"
+#include "stardis-tbound-prog.h"
+#include "stardis-fbound.h"
+#include "stardis-fbound-prog.h"
+#include "stardis-ssconnect.h"
+#include "stardis-ssconnect-prog.h"
+#include "stardis-sfconnect.h"
+#include "stardis-sfconnect-prog.h"
+#include "stardis-prog-properties.h"
#include <sdis.h>
@@ -95,6 +106,126 @@ interface_get_tcr
return interface_props->tcr;
}
+static double
+emissivity_1
+ (const struct stardis_interface_fragment* frag,
+ void* data)
+{
+ (void)frag, (void)data;
+ return 1;
+}
+
+static double
+intface_prog_get_temp
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_temp(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_flux
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_flux(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_hc
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_hc(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_emissivity
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_emissivity(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_alpha
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_alpha(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_ref_temp
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_ref_temp(&f, interface_props->prog_data);
+}
+
+static double
+intface_prog_get_tcr
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ struct stardis_interface_fragment f;
+ d3_set(f.P, frag->P);
+ d3_set(f.Ng, frag->Ng);
+ d3_set(f.uv, frag->uv);
+ f.time = frag->time;
+ ASSERT(frag->side == SDIS_FRONT || frag->side == SDIS_BACK);
+ f.side = (frag->side == SDIS_FRONT) ? FRONT : BACK;
+ return interface_props->get_tcr(&f, interface_props->prog_data);
+}
/*******************************************************************************
* Public Functions
@@ -107,16 +238,16 @@ create_intface
struct htable_intface* htable_interfaces)
{
struct int_descs int_descs = INT_DESCS_NULL;
- struct sdis_interface** p_intface;
- struct sdis_interface* intface;
+ struct sdis_interface** pp_intface;
+ struct sdis_interface* p_intface;
struct sdis_medium* front_med = NULL;
struct sdis_medium* back_med = NULL;
struct sdis_interface_side_shader* fluid_side_shader = NULL;
struct sdis_data* data = NULL;
- unsigned fd, bd, cd, descr[SG3D_PROP_TYPES_COUNT__];
+ unsigned fd, bd, id, descr[SG3D_PROP_TYPES_COUNT__];
int fluid_count = 0, solid_count = 0;
int solid_fluid_connection_count = 0, solid_solid_connection_count = 0;
- int connection_count = 0, boundary_count = 0;
+ int intface_count = 0, boundary_count = 0, prog_count = 0;
const struct description* descriptions;
struct sdis_medium** media;
res_T res = RES_OK;
@@ -133,20 +264,20 @@ create_intface
/* Create key */
int_descs.front = fd = descr[SG3D_FRONT];
int_descs.back = bd = descr[SG3D_BACK];
- int_descs.connect = cd = descr[SG3D_INTFACE];
+ int_descs.intface = id = descr[SG3D_INTFACE];
/* Search if interface already exists, or create it */
- p_intface = htable_intface_find(htable_interfaces, &int_descs);
- if(p_intface) {
- intface = *p_intface;
+ pp_intface = htable_intface_find(htable_interfaces, &int_descs);
+ if(pp_intface) {
+ p_intface = *pp_intface;
} else {
/* create new interface and register */
struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL;
struct intface* interface_props = NULL;
- unsigned id;
+ unsigned mid;
int front_defined = (fd != SG3D_UNSPECIFIED_PROPERTY);
int back_defined = (bd != SG3D_UNSPECIFIED_PROPERTY);
- int connect_defined = (cd != SG3D_UNSPECIFIED_PROPERTY);
+ int intface_defined = (id != SG3D_UNSPECIFIED_PROPERTY);
ERR(sdis_data_create(stardis->dev, sizeof(struct intface),
ALIGNOF(struct intface), NULL, &data));
@@ -156,20 +287,35 @@ create_intface
interface_props->front_medium_id = UINT_MAX;
interface_props->back_medium_id = UINT_MAX;
interface_props->desc_id = UINT_MAX;
+ interface_props->get_temp = NULL;
+ interface_props->get_flux = NULL;
+ interface_props->get_hc = NULL;
+ interface_props->get_emissivity = NULL;
+ interface_props->get_alpha = NULL;
+ interface_props->get_ref_temp = NULL;
+ interface_props->get_tcr = NULL;
+ interface_props->prog_data = NULL;
+ if(fluid_count == 2) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
if(front_defined) {
+ description_get_medium_id(&descriptions[fd], &mid);
+ interface_props->front_medium_id = mid;
+ front_med = media[mid];
switch (descriptions[fd].type) {
+ case DESC_MAT_SOLID_PROG:
+ prog_count++;
+ /* fall through */
case DESC_MAT_SOLID:
- id = descriptions[fd].d.solid->solid_id;
solid_count++;
- interface_props->front_medium_id = id;
- front_med = media[id];
break;
+ case DESC_MAT_FLUID_PROG:
+ prog_count++;
+ /* fall through */
case DESC_MAT_FLUID:
fluid_count++;
- id = descriptions[fd].d.fluid->fluid_id;
- interface_props->front_medium_id = id;
- front_med = media[id];
fluid_side_shader = &interface_shader.front;
break;
default:
@@ -177,105 +323,141 @@ create_intface
}
}
if(back_defined) {
+ description_get_medium_id(&descriptions[bd], &mid);
+ interface_props->back_medium_id = mid;
+ back_med = media[mid];
switch (descriptions[bd].type) {
+ case DESC_MAT_SOLID_PROG:
+ prog_count++;
+ /* fall through */
case DESC_MAT_SOLID:
- id = descriptions[bd].d.solid->solid_id;
solid_count++;
- interface_props->back_medium_id = id;
- back_med = media[id];
break;
+ case DESC_MAT_FLUID_PROG:
+ prog_count++;
+ /* fall through */
case DESC_MAT_FLUID:
fluid_count++;
- id = descriptions[bd].d.fluid->fluid_id;
- interface_props->back_medium_id = id;
- back_med = media[id];
- /* Can overwrite fluid_side_shader. However it would imply two
- * fluids and this case lead to an error */
+ /* cannot overwrite as the 2-fluid case is an error */
fluid_side_shader = &interface_shader.back;
break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
}
- if(fluid_count == 2) {
- res = RES_BAD_ARG;
- goto error;
- }
- if(connect_defined) {
- const struct description* connect = descriptions + cd;
- int type_checked = 0;
+ if(intface_defined) {
+ const struct description* intface = descriptions + id;
+ int for_fluid = 0;
struct sdis_medium* def_medium = NULL;
unsigned ext_id;
- if(connect->type != DESC_SOLID_FLUID_CONNECT
- && connect->type != DESC_SOLID_SOLID_CONNECT
- && front_defined == back_defined)
- {
- /* 1 and only 1 defined */
+ if(!DESC_IS_CONNECTION(intface) && front_defined == back_defined) {
+ /* not connection implies 1 and only 1 side defined */
res = RES_BAD_ARG;
goto error;
}
- if(front_defined) {
- def_medium = front_med;
- fluid_side_shader = (descriptions[fd].type == DESC_MAT_FLUID)
- ? &interface_shader.front : &interface_shader.back;
- } else {
- ASSERT(back_defined);
- def_medium = back_med;
- fluid_side_shader = (descriptions[bd].type == DESC_MAT_FLUID)
- ? &interface_shader.back : &interface_shader.front;
- }
- interface_props->desc_id = cd;
- switch(connect->type) {
+ /* meaningless if connection (but unused in this case) */
+ def_medium = front_defined ? front_med : back_med;
+ interface_props->desc_id = id;
+ switch(intface->type) {
case DESC_BOUND_H_FOR_FLUID:
if(sdis_medium_get_type(def_medium) != SDIS_FLUID) {
res = RES_BAD_ARG;
goto error;
}
- type_checked = 1;
- ASSERT(connect->d.h_boundary->imposed_temperature >= 0);
+ for_fluid = 1;
+ ASSERT(intface->d.h_boundary->imposed_temperature >= 0);
interface_props->imposed_temperature
- = connect->d.h_boundary->imposed_temperature;
+ = intface->d.h_boundary->imposed_temperature;
ASSERT(fluid_side_shader);
fluid_side_shader->temperature = interface_get_temperature;
/* fall through */
case DESC_BOUND_H_FOR_SOLID:
- if(!type_checked
- && sdis_medium_get_type(def_medium) != SDIS_SOLID)
- {
- res = RES_BAD_ARG; goto error;
+ if(!for_fluid) {
+ if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(!fluid_side_shader);
+ fluid_side_shader =
+ front_defined ? &interface_shader.back : &interface_shader.front;
}
- ext_id = connect->d.h_boundary->mat_id; /* External material id */
+ ext_id = intface->d.h_boundary->mat_id; /* External material id */
ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media));
ASSERT(sdis_medium_get_type(media[ext_id]) ==
- (connect->type == DESC_BOUND_H_FOR_SOLID ? SDIS_FLUID : SDIS_SOLID));
- connection_count++;
+ (for_fluid ? SDIS_SOLID : SDIS_FLUID));
+ intface_count++;
boundary_count++;
if(front_defined) back_med = media[ext_id];
else front_med = media[ext_id];
- interface_shader.convection_coef_upper_bound = connect->d.h_boundary->hc;
- interface_props->hc = connect->d.h_boundary->hc;
- interface_props->ref_temperature = connect->d.h_boundary->ref_temperature;
- interface_props->emissivity = connect->d.h_boundary->emissivity;
- interface_props->alpha = connect->d.h_boundary->specular_fraction;
- if(connect->d.h_boundary->hc > 0) {
+ interface_shader.convection_coef_upper_bound = intface->d.h_boundary->hc;
+ interface_props->hc = intface->d.h_boundary->hc;
+ interface_props->ref_temperature = intface->d.h_boundary->ref_temperature;
+ interface_props->emissivity = intface->d.h_boundary->emissivity;
+ interface_props->alpha = intface->d.h_boundary->specular_fraction;
+ if(intface->d.h_boundary->hc > 0) {
interface_shader.convection_coef = interface_get_convection_coef;
}
- ASSERT(fluid_side_shader);
fluid_side_shader->reference_temperature = interface_get_ref_temperature;
- if(connect->d.h_boundary->emissivity > 0) {
+ if(intface->d.h_boundary->emissivity > 0) {
fluid_side_shader->emissivity = interface_get_emissivity;
fluid_side_shader->specular_fraction = interface_get_alpha;
}
break;
+ case DESC_BOUND_H_FOR_FLUID_PROG:
+ if(sdis_medium_get_type(def_medium) != SDIS_FLUID) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ for_fluid = 1;
+ interface_props->get_temp = intface->d.h_boundary_prog->boundary_temp;
+ ASSERT(fluid_side_shader);
+ fluid_side_shader->temperature = intface_prog_get_temp;
+ /* fall through */
+ case DESC_BOUND_H_FOR_SOLID_PROG:
+ if(!for_fluid) {
+ if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(!fluid_side_shader);
+ fluid_side_shader =
+ front_defined ? &interface_shader.back : &interface_shader.front;
+ }
+ ext_id = intface->d.h_boundary_prog->mat_id; /* External material id */
+ ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media));
+ ASSERT(sdis_medium_get_type(media[ext_id]) ==
+ (for_fluid ? SDIS_SOLID : SDIS_FLUID));
+ prog_count++;
+ intface_count++;
+ boundary_count++;
+ if(front_defined) back_med = media[ext_id];
+ else front_med = media[ext_id];
+ interface_shader.convection_coef_upper_bound
+ = h_bound_prog_get_hmax(intface->d.h_boundary_prog);
+ ASSERT(interface_shader.convection_coef_upper_bound >= 0);
+ interface_shader.convection_coef
+ = intface_prog_get_hc;
+ fluid_side_shader->reference_temperature
+ = intface_prog_get_ref_temp;
+ fluid_side_shader->emissivity = intface_prog_get_emissivity;
+ fluid_side_shader->specular_fraction = intface_prog_get_alpha;
+ interface_props->get_hc = intface->d.h_boundary_prog->hc;
+ interface_props->get_emissivity = intface->d.h_boundary_prog->emissivity;
+ interface_props->get_alpha = intface->d.h_boundary_prog->alpha;
+ interface_props->get_ref_temp = intface->d.h_boundary_prog->ref_temp;
+ interface_props->prog_data = intface->d.h_boundary_prog->prog_data;
+ break;
case DESC_BOUND_T_FOR_SOLID:
if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
res = RES_BAD_ARG;
goto error;
}
- ext_id = connect->d.t_boundary->mat_id; /* External material id */
+ fluid_side_shader =
+ front_defined ? &interface_shader.back : &interface_shader.front;
+ ext_id = intface->d.t_boundary->mat_id; /* External material id */
ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media));
ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID);
- connection_count++;
+ intface_count++;
boundary_count++;
if(front_defined) {
ASSERT(!back_med);
@@ -284,35 +466,81 @@ create_intface
ASSERT(!front_med);
front_med = media[ext_id];
}
- /* The imposed T is for the 2 sides (until there is contact resistances) */
+ /* The imposed T is for the 2 sides (there is no contact resistance) */
interface_shader.front.temperature = interface_get_temperature;
interface_shader.back.temperature = interface_get_temperature;
/* Set emissivity to 1 to allow radiative paths comming from
* a possible external fluid to 'see' the imposed T */
- ASSERT(fluid_side_shader);
- fluid_side_shader->reference_temperature = interface_get_ref_temperature;
fluid_side_shader->emissivity = interface_get_emissivity;
interface_props->emissivity = 1;
- ASSERT(connect->d.t_boundary->imposed_temperature >= 0);
+ ASSERT(intface->d.t_boundary->imposed_temperature >= 0);
interface_props->imposed_temperature
- = connect->d.t_boundary->imposed_temperature;
+ = intface->d.t_boundary->imposed_temperature;
+ break;
+ case DESC_BOUND_T_FOR_SOLID_PROG:
+ if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ fluid_side_shader =
+ front_defined ? &interface_shader.back : &interface_shader.front;
+ ext_id = intface->d.t_boundary_prog->mat_id; /* External material id */
+ ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media));
+ ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID);
+ prog_count++;
+ intface_count++;
+ boundary_count++;
+ if(front_defined) {
+ ASSERT(!back_med);
+ back_med = media[ext_id];
+ } else {
+ ASSERT(!front_med);
+ front_med = media[ext_id];
+ }
+ /* The imposed T is for the 2 sides (there is no contact resistance) */
+ interface_shader.front.temperature = intface_prog_get_temp;
+ interface_shader.back.temperature = intface_prog_get_temp;
+ /* Set emissivity to 1 to allow radiative paths comming from
+ * a possible external fluid to 'see' the imposed T */
+ fluid_side_shader->emissivity = interface_get_emissivity;
+ interface_props->get_emissivity = emissivity_1;
+ interface_props->get_temp = intface->d.t_boundary_prog->temperature;
+ interface_props->prog_data = intface->d.t_boundary_prog->prog_data;
break;
case DESC_BOUND_F_FOR_SOLID:
if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
res = RES_BAD_ARG;
goto error;
}
- connection_count++;
+ intface_count++;
boundary_count++;
if(front_defined) {
- back_med = media[connect->d.f_boundary->mat_id];
+ back_med = media[intface->d.f_boundary->mat_id];
interface_shader.front.flux = interface_get_flux;
} else {
- front_med = media[connect->d.f_boundary->mat_id];
+ front_med = media[intface->d.f_boundary->mat_id];
interface_shader.back.flux = interface_get_flux;
}
- ASSERT(connect->d.f_boundary->imposed_flux != SDIS_FLUX_NONE);
- interface_props->imposed_flux = connect->d.f_boundary->imposed_flux;
+ ASSERT(intface->d.f_boundary->imposed_flux != SDIS_FLUX_NONE);
+ interface_props->imposed_flux = intface->d.f_boundary->imposed_flux;
+ break;
+ case DESC_BOUND_F_FOR_SOLID_PROG:
+ if(sdis_medium_get_type(def_medium) != SDIS_SOLID) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ prog_count++;
+ intface_count++;
+ boundary_count++;
+ if(front_defined) {
+ back_med = media[intface->d.f_boundary_prog->mat_id];
+ interface_shader.front.flux = intface_prog_get_flux;
+ } else {
+ front_med = media[intface->d.f_boundary_prog->mat_id];
+ interface_shader.back.flux = intface_prog_get_flux;
+ }
+ interface_props->get_flux = intface->d.f_boundary_prog->flux;
+ interface_props->prog_data = intface->d.f_boundary_prog->prog_data;
break;
case DESC_SOLID_FLUID_CONNECT:
/* Both front and back should be defined */
@@ -321,23 +549,48 @@ create_intface
goto error;
}
ASSERT(front_defined && back_defined);
- connection_count++;
+ intface_count++;
solid_fluid_connection_count++;
- interface_shader.convection_coef_upper_bound = connect->d.sf_connect->hc;
- interface_props->hc = connect->d.sf_connect->hc;
- interface_props->ref_temperature = connect->d.sf_connect->ref_temperature;
- interface_props->emissivity = connect->d.sf_connect->emissivity;
- interface_props->alpha = connect->d.sf_connect->specular_fraction;
- if(connect->d.sf_connect->hc > 0) {
+ interface_shader.convection_coef_upper_bound = intface->d.sf_connect->hc;
+ interface_props->hc = intface->d.sf_connect->hc;
+ 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;
+ if(intface->d.sf_connect->hc > 0) {
interface_shader.convection_coef = interface_get_convection_coef;
}
ASSERT(fluid_side_shader);
fluid_side_shader->reference_temperature = interface_get_ref_temperature;
- if(connect->d.sf_connect->emissivity > 0) {
+ if(intface->d.sf_connect->emissivity > 0) {
fluid_side_shader->emissivity = interface_get_emissivity;
fluid_side_shader->specular_fraction = interface_get_alpha;
}
break;
+ case DESC_SOLID_FLUID_CONNECT_PROG:
+ /* Both front and back should be defined */
+ if(solid_count != 1 || fluid_count != 1) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(front_defined && back_defined);
+ prog_count++;
+ intface_count++;
+ solid_fluid_connection_count++;
+ interface_shader.convection_coef_upper_bound
+ = sf_connect_prog_get_hmax(intface->d.sf_connect_prog);
+ ASSERT(interface_shader.convection_coef_upper_bound >= 0);
+ interface_props->get_ref_temp = intface->d.sf_connect_prog->ref_temp;
+ interface_props->get_hc = intface->d.sf_connect_prog->hc;
+ interface_props->get_emissivity
+ = intface->d.sf_connect_prog->emissivity;
+ interface_props->get_alpha = intface->d.sf_connect_prog->alpha;
+ interface_shader.convection_coef = intface_prog_get_hc;
+ ASSERT(fluid_side_shader);
+ fluid_side_shader->emissivity = intface_prog_get_emissivity;
+ fluid_side_shader->specular_fraction = intface_prog_get_alpha;
+ fluid_side_shader->reference_temperature = intface_prog_get_ref_temp;
+ interface_props->prog_data = intface->d.sf_connect_prog->prog_data;
+ break;
case DESC_SOLID_SOLID_CONNECT:
/* Both front and back should be defined */
if(solid_count != 2 || fluid_count != 0) {
@@ -345,19 +598,33 @@ create_intface
goto error;
}
ASSERT(front_defined && back_defined);
- connection_count++;
+ intface_count++;
solid_solid_connection_count++;
- interface_props->tcr = connect->d.ss_connect->tcr;
- if(connect->d.ss_connect->tcr > 0) {
+ interface_props->tcr = intface->d.ss_connect->tcr;
+ if(intface->d.ss_connect->tcr > 0) {
interface_shader.thermal_contact_resistance = interface_get_tcr;
}
break;
+ case DESC_SOLID_SOLID_CONNECT_PROG:
+ /* Both front and back should be defined */
+ if(solid_count != 2 || fluid_count != 0) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(front_defined && back_defined);
+ prog_count++;
+ intface_count++;
+ solid_solid_connection_count++;
+ interface_props->get_tcr = intface->d.ss_connect_prog->tcr;
+ interface_shader.thermal_contact_resistance = intface_prog_get_tcr;
+ interface_props->prog_data = intface->d.ss_connect_prog->prog_data;
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
}
- if((fluid_count + solid_count + connection_count < 2)
+ if((fluid_count + solid_count + intface_count < 2)
|| (boundary_count && (fluid_count + solid_count != 1)))
{
res = RES_BAD_ARG;
@@ -365,12 +632,12 @@ create_intface
}
ERR(sdis_interface_create(stardis->dev, front_med, back_med,
- &interface_shader, data, &intface));
+ &interface_shader, data, &p_intface));
SDIS(data_ref_put(data)); data = NULL;
- ERR(darray_interface_ptrs_push_back(&stardis->geometry.interfaces, &intface));
- ERR(htable_intface_set(htable_interfaces, &int_descs, &intface));
+ ERR(darray_interface_ptrs_push_back(&stardis->geometry.interfaces, &p_intface));
+ ERR(htable_intface_set(htable_interfaces, &int_descs, &p_intface));
}
- ERR(darray_interface_ptrs_push_back(&stardis->geometry.interf_bytrg, &intface));
+ ERR(darray_interface_ptrs_push_back(&stardis->geometry.interf_bytrg, &p_intface));
end:
if(data) SDIS(data_ref_put(data));
diff --git a/src/stardis-intface.h b/src/stardis-intface.h
@@ -21,12 +21,21 @@
#include <limits.h>
struct stardis;
-struct dummies;
+struct stardis_interface_fragment;
/*******************************************************************************
* Interface data
******************************************************************************/
struct intface {
+ /* programmed interfaces */
+ double (*get_temp)(const struct stardis_interface_fragment*, void*);
+ double (*get_flux)(const struct stardis_interface_fragment*, void*);
+ double (*get_hc)(const struct stardis_interface_fragment*, void*);
+ double (*get_emissivity)(const struct stardis_interface_fragment*, void*);
+ double (*get_alpha)(const struct stardis_interface_fragment*, void*);
+ double (*get_ref_temp)(const struct stardis_interface_fragment*, void*);
+ double (*get_tcr)(const struct stardis_interface_fragment*, void*);
+ void* prog_data;
/* fluid - solid */
double hc;
double ref_temperature;
@@ -44,7 +53,7 @@ struct intface {
/* Declare the hash table that map an interface to its descriptor */
struct int_descs {
- unsigned front, back, connect;
+ unsigned front, back, intface;
};
#define INT_DESCS_NULL__ { UINT_MAX, UINT_MAX, UINT_MAX }
static const struct int_descs INT_DESCS_NULL = INT_DESCS_NULL__;
@@ -53,7 +62,7 @@ static INLINE char
eq_desc(const struct int_descs* a, const struct int_descs* b)
{
return (char)(a->front == b->front && a->back == b->back
- && a->connect == b->connect);
+ && a->intface == b->intface);
}
#define HTABLE_NAME intface
@@ -62,7 +71,7 @@ eq_desc(const struct int_descs* a, const struct int_descs* b)
#define HTABLE_KEY_FUNCTOR_EQ eq_desc
#include <rsys/hash_table.h>
-extern res_T
+res_T
create_intface
(struct stardis* stardis,
unsigned tr_idx,
diff --git a/src/stardis-main.c b/src/stardis-main.c
@@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "stardis-app.h"
+#include "stardis-args.h"
#include "stardis-parsing.h"
#include "stardis-output.h"
#include "stardis-compute.h"
diff --git a/src/stardis-output.c b/src/stardis-output.c
@@ -15,18 +15,24 @@
#define _POSIX_C_SOURCE 200112L /* snprintf */
#include "stardis-output.h"
+#include "stardis-args.h"
#include "stardis-compute.h"
#include "stardis-fluid.h"
#include "stardis-solid.h"
+#include "stardis-hbound.h"
+#include "stardis-tbound.h"
+#include "stardis-fbound.h"
+#include "stardis-ssconnect.h"
+#include "stardis-sfconnect.h"
#include "stardis-intface.h"
#include "stardis-app.h"
#include "stardis-green-types.h"
#include <sdis.h>
+#include<star/ssp.h>
#include<star/senc3d.h>
#include<star/sg3d.h>
-#include<star/ssp.h>
#include <rsys/math.h>
#include <rsys/mem_allocator.h>
@@ -68,7 +74,6 @@ enum enclosure_errors_t {
ENCLOSURE_WITH_UNDEF_MEDIUM = BIT(2)
};
-
static res_T
copy_desc_to_green_desc
(struct green_description* gdesc,
@@ -604,7 +609,7 @@ dump_sample_end
pos = pt.data.itfrag.fragment.P;
d__ = sdis_data_get(data);
id = d__->desc_id;
- CHK(DESC_IS_T(descs[id].type) || DESC_IS_H(descs[id].type));
+ CHK(DESC_IS_T(descs+id) || DESC_IS_H(descs+id));
break;
}
case SDIS_VERTEX:
@@ -689,7 +694,7 @@ dump_sample
data = sdis_interface_get_data(pt.data.itfrag.intface);
d__ = sdis_data_get(data);
desc_id = d__->desc_id;
- CHK(DESC_IS_T(descs[desc_id].type) || DESC_IS_H(descs[desc_id].type));
+ CHK(DESC_IS_T(descs+desc_id) || DESC_IS_H(descs+desc_id));
header.sample_end_description_id = desc_id;
header.at_initial = 0;
break;
@@ -1177,7 +1182,7 @@ dump_boundaries_at_the_end_of_vtk
ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, t,
descr));
if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
- && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type))
+ && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE]))
/* Descriptions are numbered from 1 in the log (so the 1+ below) */
fprintf(stream, "%u\n", 1 + descr[SG3D_INTFACE]);
else fprintf(stream, "%u\n", SG3D_UNSPECIFIED_PROPERTY);
@@ -1382,7 +1387,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk
if(descr[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY)
description_get_medium_id(descriptions + descr[SG3D_FRONT], &fmid);
else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
- && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type))
+ && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE]))
{
description_get_medium_id(descriptions + descr[SG3D_INTFACE], &fmid);
}
@@ -1390,7 +1395,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk
if(descr[SENC3D_BACK] != SG3D_UNSPECIFIED_PROPERTY)
description_get_medium_id(descriptions + descr[SENC3D_BACK], &bmid);
else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
- && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type))
+ && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE]))
{
description_get_medium_id(descriptions + descr[SG3D_INTFACE], &bmid);
}
@@ -1402,7 +1407,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk
if(descr[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY)
description_get_medium_id(descriptions + descr[SG3D_FRONT], &mid);
else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
- && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type))
+ && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE]))
{
description_get_medium_id(descriptions + descr[SG3D_INTFACE], &mid);
}
@@ -1413,7 +1418,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk
if(descr[SENC3D_BACK] != SG3D_UNSPECIFIED_PROPERTY)
description_get_medium_id(descriptions + descr[SENC3D_BACK], &mid);
else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
- && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type))
+ && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE]))
{
description_get_medium_id(descriptions + descr[SG3D_INTFACE], &mid);
}
diff --git a/src/stardis-output.h b/src/stardis-output.h
@@ -39,50 +39,50 @@ struct dump_path_context {
struct stardis* stardis;
};
-extern res_T
+res_T
dump_path
(const struct sdis_heat_path* path,
void* context);
-extern res_T
+res_T
print_sample
(struct sdis_green_path* path,
void* ctx);
-extern res_T
+res_T
dump_vtk_image
(const struct sdis_estimator_buffer* buf,
FILE* stream);
-extern res_T
+res_T
dump_ht_image
(const struct sdis_estimator_buffer* buf,
FILE* stream);
-extern res_T
+res_T
dump_green_ascii
(struct sdis_green_function* green,
const struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_green_bin
(struct sdis_green_function* green,
const struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_paths_end
(struct sdis_green_function* green,
const struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_enclosure_related_stuff_at_the_end_of_vtk
(struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
print_computation_time
(struct sdis_estimator* estimator, /* Can be NULL */
struct stardis* stardis,
@@ -91,39 +91,39 @@ print_computation_time
struct time* computation_end,
struct time* output_end); /* Can be NULL */
-extern res_T
+res_T
print_single_MC_result
(struct sdis_estimator* estimator,
struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_map
(const struct stardis* stardis,
const struct darray_estimators* estimators,
FILE* stream);
-extern res_T
+res_T
dump_boundaries_at_the_end_of_vtk
(const struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_compute_region_at_the_end_of_vtk
(struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
dump_model_as_c_chunks
(struct stardis* stardis,
FILE* stream);
-extern res_T
+res_T
write_random_generator_state
(struct sdis_estimator* estimator,
FILE* stream);
-extern res_T
+res_T
read_random_generator_state
(struct ssp_rng* state,
FILE* stream);
diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c
@@ -16,6 +16,24 @@
#define _POSIX_C_SOURCE 200809L /* strdup */
#include "stardis-parsing.h"
#include "stardis-app.h"
+#include "stardis-prog-properties.h"
+#include "stardis-args.h"
+#include "stardis-description.h"
+#include "stardis-hbound.h"
+#include "stardis-hbound-prog.h"
+#include "stardis-tbound.h"
+#include "stardis-tbound-prog.h"
+#include "stardis-fbound.h"
+#include "stardis-fbound-prog.h"
+#include "stardis-sfconnect.h"
+#include "stardis-sfconnect-prog.h"
+#include "stardis-ssconnect.h"
+#include "stardis-ssconnect-prog.h"
+#include "stardis-fluid-prog.h"
+#include "stardis-fluid.h"
+#include "stardis-solid-prog.h"
+#include "stardis-solid.h"
+#include "stardis-program.h"
#include "stardis-default.h"
#include "stardis-green-types.h"
@@ -23,8 +41,9 @@
#include <rsys/double2.h>
#include <rsys/double3.h>
#include <rsys/logger.h>
+#include <rsys/text_reader.h>
+#include <rsys/library.h>
-#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
@@ -40,23 +59,7 @@
/*******************************************************************************
* Local Functions
******************************************************************************/
-
-void
-add_geom_ctx_indices
- (const unsigned itri,
- unsigned ids[3],
- void* context)
-{
- const struct add_geom_ctx* ctx = context;
- const unsigned* trg;
- int i;
- ASSERT(ids && ctx);
- ASSERT(itri < ctx->stl_desc.triangles_count);
- trg = ctx->stl_desc.indices + 3 * itri;
- for(i = 0; i < 3; i++) ids[i] = trg[i];
-}
-
-void
+static void
add_geom_ctx_properties
(const unsigned itri,
unsigned prop[3],
@@ -70,20 +73,6 @@ add_geom_ctx_properties
for(i = 0; i < SG3D_PROP_TYPES_COUNT__; i++) prop[i] = ctx->properties[i];
}
-void
-add_geom_ctx_position
- (const unsigned ivert,
- double pos[3],
- void* context)
-{
- const struct add_geom_ctx* ctx = context;
- const float* v;
- ASSERT(pos && ctx);
- ASSERT(ivert < ctx->stl_desc.vertices_count);
- v = ctx->stl_desc.vertices + 3 * ivert;
- d3_set_f3(pos, v);
-}
-
static res_T
add_geom_keep_degenerated
(const unsigned itri,
@@ -92,7 +81,6 @@ add_geom_keep_degenerated
{
const struct add_geom_ctx* ctx = context;
struct darray_uint* degenerated;
-
ASSERT(abort && ctx && ctx->custom); (void)abort;
ASSERT(itri < ctx->stl_desc.triangles_count);
degenerated = ctx->custom;
@@ -139,7 +127,7 @@ read_sides_and_files
add_geom_ctx.properties[SG3D_INTFACE] = description_id;
} else {
tk = strtok_r(NULL, " \t", tok_ctx);
- if(!tk) {
+ if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) {
if(file_count == 0) {
/* At least 1 side */
logger_print(stardis->logger, LOG_ERROR,
@@ -170,9 +158,9 @@ read_sides_and_files
}
}
tk = strtok_r(NULL, " \t", tok_ctx);
- if(!tk) {
- if(!descr_is_intface /* Has read a side */
- || !file_count) /* Need at least 1 file */
+ if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) {
+ if(!descr_is_intface /* Has read a side specifier */
+ || !file_count) /* Need at least 1 file name */
{
logger_print(stardis->logger, LOG_ERROR,
"Invalid data (missing token 'file name')\n");
@@ -207,7 +195,7 @@ read_sides_and_files
"File '%s' included %lu degenerated triangles (removed)\n",
tk, (unsigned long)c);
ERR(str_printf(&str, "Degenerated triangles IDs: %u", ids[0]));
- FOR_EACH(n, 1, c) { STR_APPEND_PRINTF(&str, ", %u", ARG1( ids[n] ) ); }
+ FOR_EACH(n, 1, c) { ERR(str_append_printf(&str, ", %u", ids[n])); }
logger_print(stardis->logger, LOG_OUTPUT, "%s\n", str_cget(&str));
darray_uint_clear(°enerated);
}
@@ -246,6 +234,34 @@ error:
/*******************************************************************************
* Public Functions
******************************************************************************/
+void
+add_geom_ctx_position
+ (const unsigned ivert,
+ double pos[3],
+ void* context)
+{
+ const struct add_geom_ctx* ctx = context;
+ const float* v;
+ ASSERT(pos && ctx);
+ ASSERT(ivert < ctx->stl_desc.vertices_count);
+ v = ctx->stl_desc.vertices + 3 * ivert;
+ d3_set_f3(pos, v);
+}
+
+void
+add_geom_ctx_indices
+ (const unsigned itri,
+ unsigned ids[3],
+ void* context)
+{
+ const struct add_geom_ctx* ctx = context;
+ const unsigned* trg;
+ int i;
+ ASSERT(ids && ctx);
+ ASSERT(itri < ctx->stl_desc.triangles_count);
+ trg = ctx->stl_desc.indices + 3 * itri;
+ for(i = 0; i < 3; i++) ids[i] = trg[i];
+}
static res_T
description_set_name
@@ -256,10 +272,13 @@ description_set_name
res_T res = RES_OK;
double foo;
const char* keywords[] = {
- "AUTO", "BACK", "BOTH", "FLUID", "FRONT", "F_BOUNDARY_FOR_SOLID",
- "H_BOUNDARY_FOR_FLUID", "H_BOUNDARY_FOR_SOLID", "SCALE", "SOLID",
- "SOLID_FLUID_CONNECTION", "SOLID_SOLID_CONNECTION", "TRAD",
- "T_BOUNDARY_FOR_SOLID", "UNKNOWN" };
+ "AUTO", "BACK", "BOTH", "FLUID", "FLUID_PROG", "FRONT", "F_BOUNDARY_FOR_SOLID",
+ "F_BOUNDARY_FOR_SOLID_PROG", "H_BOUNDARY_FOR_FLUID", "H_BOUNDARY_FOR_FLUID_PROG",
+ "H_BOUNDARY_FOR_SOLID", "H_BOUNDARY_FOR_SOLID_PROG", "PROGRAM", "PROG_PARAMS",
+ "SCALE", "SOLID", "SOLID_PROG", "SOLID_FLUID_CONNECTION",
+ "SOLID_FLUID_CONNECTION_PROG", "SOLID_SOLID_CONNECTION",
+ "SOLID_SOLID_CONNECTION_PROG", "TRAD", "T_BOUNDARY_FOR_SOLID",
+ "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" };
const char* reason = NULL;
int i;
ASSERT(name && tk);
@@ -305,7 +324,7 @@ find_description_by_name
const struct description* self)
{
size_t i;
- ASSERT(stardis && name && self);
+ ASSERT(stardis && name);
FOR_EACH(i, 0, darray_descriptions_size_get(&stardis->descriptions)) {
struct description* desc
@@ -339,7 +358,7 @@ process_h
sz = darray_descriptions_size_get(&stardis->descriptions);
ERR(darray_descriptions_resize(&stardis->descriptions, sz+1));
desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
- ERR(init_h(stardis->allocator, &desc->d.h_boundary));
+ ERR(init_h_boundary(stardis->allocator, &desc->d.h_boundary));
h_boundary = desc->d.h_boundary;
desc->type = type;
@@ -384,12 +403,13 @@ process_h
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "hc");
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient");
res = cstr_to_double(tk, &h_boundary->hc);
if(res != RES_OK
|| h_boundary->hc < 0)
{
- logger_print(stardis->logger, LOG_ERROR, "Invalid hc: %s\n", tk);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid Convection coefficient: %s\n", tk);
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
@@ -409,14 +429,14 @@ process_h
ERR(get_dummy_solid_id(stardis, &h_boundary->mat_id));
else {
struct fluid* fluid = NULL;
+ ASSERT(type == DESC_BOUND_H_FOR_SOLID);
ERR(init_fluid(stardis->allocator, &fluid));
fluid->fluid_id = allocate_stardis_medium_id(stardis);
h_boundary->mat_id = fluid->fluid_id;
h_boundary->possible_external_fluid = fluid;
ASSERT(sz <= UINT_MAX);
fluid->desc_id = (unsigned)sz;
- fluid->imposed_temperature
- = h_boundary->imposed_temperature;
+ fluid->imposed_temperature = h_boundary->imposed_temperature;
fluid->is_outside = 1;
fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN);
ERR(create_solver_fluid(stardis, fluid));
@@ -435,6 +455,292 @@ error:
goto end;
}
+static res_T
+set_stripped_args
+ (struct str* str,
+ const char* args)
+{
+ const char whitespace[] = " \f\n\r\t\v";
+ ASSERT(str && args);
+ return str_set(str, args + strspn(args, whitespace));
+}
+
+/* utility macros */
+#define GET_LIB_SYMBOL_BASE(DestField, LibHandle, FunName, Optional) \
+ *(void**)DestField = library_get_symbol((LibHandle), #FunName ); \
+ if(!*DestField && !(Optional)) { \
+ logger_print(stardis->logger, LOG_ERROR, \
+ "Cannot find function '" #FunName "()' in lib %s\n", lib_name); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ }
+
+#define GET_LIB_SYMBOL(Dest, Field, FunName) \
+ GET_LIB_SYMBOL_BASE(&((Dest)->Field), (Dest)->program->lib_handle, FunName, 0)
+
+#define CREATE_DESC_DATA_BASE(Desc, CreateArgs) \
+ /* duplicate args to allow to modify them */ \
+ ERR(str_copy(&tmp, &(Desc)->args)); \
+ (Desc)->prog_data = (Desc)->create(&ctx, CreateArgs); \
+ if(!(Desc)->prog_data) { \
+ logger_print(stardis->logger, LOG_ERROR, \
+ "Cannot create data for description %s\n", str_cget(&(Desc)->name)); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ }
+
+#define CREATE_DESC_DATA(Desc) \
+ CREATE_DESC_DATA_BASE(Desc, LIST_ARG2((Desc)->program->prog_data, str_get(&tmp)))
+
+/* The returned program is NULL if no stardis_create_program function is
+ * defined in the library. */
+static res_T
+get_prog_common
+ (const char* lib_name,
+ struct stardis* stardis,
+ struct program** program,
+ void* (**create)
+ (const struct stardis_description_create_context*, void*, char*),
+ void (**release)(void*))
+{
+ res_T res = RES_OK;
+ struct description* desc;
+ struct str tmp;
+
+ ASSERT(lib_name && program && create && release && stardis);
+
+ /* get the library handler */
+ str_init(stardis->allocator, &tmp);
+ ERR(str_set(&tmp, lib_name));
+ desc = find_description_by_name(stardis, &tmp, NULL);
+ if(!desc) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Undefined PROGRAM: %s\n", lib_name);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ *program = desc->d.program;
+ /* get the mandatory user-defined functions from the library */
+ GET_LIB_SYMBOL_BASE(create, (*program)->lib_handle, stardis_create_data, 0);
+ GET_LIB_SYMBOL_BASE(release, (*program)->lib_handle, stardis_release_data, 0);
+
+end:
+ str_release(&tmp);
+ return res;
+error:
+ goto end;
+}
+
+/* PROGRAM Name library_path [...] */
+static res_T
+process_program
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ size_t sz;
+ struct program* program;
+ const char* lib_name;
+ struct str tmp;
+ const char* lic;
+ const char* _c_;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_program(stardis->allocator, &desc->d.program));
+ program = desc->d.program;
+ desc->type = DESC_PROGRAM;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(description_set_name(stardis, &program->name, tk));
+ if(find_description_by_name(stardis, &program->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ lib_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "library path");
+ ERR(str_set(&program->lib_path, tk));
+
+ /* get the library handler */
+ program->lib_handle = library_open(tk);
+ if(!program->lib_handle) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot open library: %s (%s)\n", lib_name, tk);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* get the mandatory user-defined functions from the library */
+ GET_LIB_SYMBOL_BASE(&program->get_copyright_notice, program->lib_handle,
+ get_copyright_notice, 0);
+ GET_LIB_SYMBOL_BASE(&program->get_license_short, program->lib_handle,
+ get_license_short, 0);
+ GET_LIB_SYMBOL_BASE(&program->get_license_text, program->lib_handle,
+ get_license_text, 0);
+ /* get the optional user-defined functions from the library */
+ GET_LIB_SYMBOL_BASE(&program->create,
+ program->lib_handle, stardis_create_library_data, 1);
+ GET_LIB_SYMBOL_BASE(&program->release,
+ program->lib_handle, stardis_release_library_data, 1);
+ GET_LIB_SYMBOL_BASE(&program->finalize,
+ program->lib_handle, stardis_finalize_library_data, 1);
+ if(!(program->create && program->release && program->finalize)
+ && !(!program->create && !program->release && !program->finalize))
+ {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Inconsistent library data management for library '%s'.\n",
+ lib_name);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Please define all or none of stardis_create_library_data, "
+ "stardis_finalize_library_data and stardis_release_library_data funcions.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&program->args, *tok_ctx));
+ if(program->create) {
+ /* create and init custom data */
+ struct stardis_program_context ctx;
+ ctx.name = lib_name;
+ ctx.verbosity_level = stardis->verbose;
+ CREATE_DESC_DATA_BASE(program, LIST_ARG1(str_get(&tmp)));
+ } else if(!str_is_empty(&program->args)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Library '%s' has no custom data management functions but has arguments.\n",
+ lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ lic = program->get_license_short(program->prog_data);
+ _c_ = program->get_copyright_notice(program->prog_data);
+ if(!lic) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(!_c_) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Loading external library '%s': \"%s\"\n",
+ str_cget(&program->name), str_cget(&program->lib_path));
+ logger_print(stardis->logger, LOG_OUTPUT, " %s\n", _c_);
+ logger_print(stardis->logger, LOG_OUTPUT, " %s\n", lic);
+
+end:
+ str_release(&tmp);
+ return res;
+error:
+ goto end;
+}
+
+/* H_BOUNDARY_FOR_SOLID_PROG Name ProgName STL_filenames [PROG_PARAMS ...]
+ * H_BOUNDARY_FOR_FLUID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_h_prog
+ (struct stardis* stardis,
+ const enum description_type type,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct h_boundary_prog* h_boundary_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_h_boundary_prog(stardis->allocator, &desc->d.h_boundary_prog));
+ h_boundary_prog = desc->d.h_boundary_prog;
+ desc->type = type;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed h boundary name");
+ ERR(description_set_name(stardis, &h_boundary_prog->name, tk));
+ if(find_description_by_name(stardis, &h_boundary_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&h_boundary_prog->prog_name, tk));
+ lib_name = tk;
+
+ ASSERT(sz <= UINT_MAX);
+ ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&h_boundary_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &h_boundary_prog->program,
+ &h_boundary_prog->create, &h_boundary_prog->release));
+ GET_LIB_SYMBOL(h_boundary_prog, ref_temp, stardis_reference_temperature);
+ GET_LIB_SYMBOL(h_boundary_prog, emissivity, stardis_emissivity);
+ GET_LIB_SYMBOL(h_boundary_prog, alpha, stardis_specular_fraction);
+ GET_LIB_SYMBOL(h_boundary_prog, hc, stardis_convection_coefficient);
+ GET_LIB_SYMBOL(h_boundary_prog, hmax, stardis_max_convection_coefficient);
+ GET_LIB_SYMBOL(h_boundary_prog, t_range, stardis_t_range);
+ if(type == DESC_BOUND_H_FOR_FLUID_PROG) {
+ GET_LIB_SYMBOL(h_boundary_prog, boundary_temp, stardis_boundary_temperature);
+ } else {
+ GET_LIB_SYMBOL(h_boundary_prog, fluid_temp, stardis_medium_temperature);
+ }
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(h_boundary_prog);
+
+ h_boundary_prog->t_range(h_boundary_prog->prog_data, stardis->t_range);
+
+ /* create the media behind the interface */
+ if(type == DESC_BOUND_H_FOR_FLUID_PROG) {
+ ERR(get_dummy_solid_id(stardis, &h_boundary_prog->mat_id));
+ } else {
+ struct fluid_prog* fluid_prog = NULL;
+ ASSERT(type == DESC_BOUND_H_FOR_SOLID_PROG);
+ ERR(init_fluid_prog(stardis->allocator, &fluid_prog));
+ fluid_prog->fluid_id = allocate_stardis_medium_id(stardis);
+ h_boundary_prog->mat_id = fluid_prog->fluid_id;
+ h_boundary_prog->possible_external_fluid = fluid_prog;
+ fluid_prog->desc_id = (unsigned)sz;
+ fluid_prog->temp = h_boundary_prog->fluid_temp;
+ fluid_prog->is_outside = 1;
+ fluid_prog->prog_data = h_boundary_prog->prog_data;
+ /* fluid_prog->release is NULL to avoid deleting shared prog_data */
+ ERR(create_solver_external_fluid_prog(stardis, fluid_prog));
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "External programmed fluid created (it is medium %u)\n",
+ fluid_prog->fluid_id);
+ }
+
+end:
+ str_release(&tmp);
+ return res;
+error:
+ goto end;
+}
+
/* T_BOUNDARY_FOR_SOLID Name T STL_filenames */
static res_T
process_t
@@ -454,7 +760,7 @@ process_t
sz = darray_descriptions_size_get(&stardis->descriptions);
ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
- ERR(init_t(stardis->allocator, &desc->d.t_boundary));
+ ERR(init_t_boundary(stardis->allocator, &desc->d.t_boundary));
t_boundary = desc->d.t_boundary;
desc->type = DESC_BOUND_T_FOR_SOLID;
@@ -490,6 +796,72 @@ error:
goto end;
}
+/* T_BOUNDARY_FOR_SOLID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_t_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct t_boundary_prog* t_boundary_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_t_boundary_prog(stardis->allocator, &desc->d.t_boundary_prog));
+ t_boundary_prog = desc->d.t_boundary_prog;
+ desc->type = DESC_BOUND_T_FOR_SOLID_PROG;
+
+ ERR(get_dummy_fluid_id(stardis, &t_boundary_prog->mat_id));
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name");
+ ERR(description_set_name(stardis, &t_boundary_prog->name, tk));
+ if(find_description_by_name(stardis, &t_boundary_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&t_boundary_prog->prog_name, tk));
+ lib_name = tk;
+
+ ASSERT(sz <= UINT_MAX);
+ ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&t_boundary_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &t_boundary_prog->program,
+ &t_boundary_prog->create, &t_boundary_prog->release));
+ GET_LIB_SYMBOL(t_boundary_prog, temperature, stardis_boundary_temperature);
+ GET_LIB_SYMBOL(t_boundary_prog, t_range, stardis_t_range);
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(t_boundary_prog);
+
+ t_boundary_prog->t_range(t_boundary_prog->prog_data, stardis->t_range);
+
+end:
+ str_release(&tmp);
+ return res;
+error:
+ goto end;
+}
+
/* F_BOUNDARY_FOR_SOLID Name F STL_filenames */
static res_T
process_flx
@@ -509,7 +881,7 @@ process_flx
sz = darray_descriptions_size_get(&stardis->descriptions);
ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
- ERR(init_f(stardis->allocator, &desc->d.f_boundary));
+ ERR(init_f_boundary(stardis->allocator, &desc->d.f_boundary));
f_boundary = desc->d.f_boundary;
desc->type = DESC_BOUND_F_FOR_SOLID;
@@ -551,6 +923,70 @@ error:
goto end;
}
+/* F_BOUNDARY_FOR_SOLID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_flx_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct f_boundary_prog* f_boundary_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_f_boundary_prog(stardis->allocator, &desc->d.f_boundary_prog));
+ f_boundary_prog = desc->d.f_boundary_prog;
+ desc->type = DESC_BOUND_F_FOR_SOLID_PROG;
+
+ ERR(get_dummy_fluid_id(stardis, &f_boundary_prog->mat_id));
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name");
+ ERR(description_set_name(stardis, &f_boundary_prog->name, tk));
+ if(find_description_by_name(stardis, &f_boundary_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&f_boundary_prog->prog_name, tk));
+ desc_name = tk;
+ desc_name = tk;
+ lib_name = tk;
+
+ ASSERT(sz <= UINT_MAX);
+ ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&f_boundary_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &f_boundary_prog->program,
+ &f_boundary_prog->create, &f_boundary_prog->release));
+ GET_LIB_SYMBOL(f_boundary_prog, flux, stardis_boundary_flux);
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(f_boundary_prog);
+
+end:
+ str_release(&tmp);
+ return res;
+error:
+ goto end;
+}
+
/* SOLID_FLUID_CONNECTION Name ref_temperature emissivity specular_fraction hc STL_filenames */
static res_T
process_sfc
@@ -570,7 +1006,7 @@ process_sfc
sz = darray_descriptions_size_get(&stardis->descriptions);
ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
- ERR(init_sf(stardis->allocator, &desc->d.sf_connect));
+ ERR(init_sf_connect(stardis->allocator, &desc->d.sf_connect));
sf_connect = desc->d.sf_connect;
desc->type = DESC_SOLID_FLUID_CONNECT;
@@ -579,7 +1015,7 @@ process_sfc
* we continue the trend to ensure connection ID is OK */
sf_connect->connection_id = allocate_stardis_medium_id(stardis);
- CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid fluid connection name");
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-fluid connection name");
ERR(description_set_name(stardis, &sf_connect->name, tk));
if(find_description_by_name(stardis, &sf_connect->name, desc)) {
logger_print(stardis->logger, LOG_ERROR,
@@ -620,20 +1056,90 @@ process_sfc
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
- CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "hc");
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient");
res = cstr_to_double(tk, &sf_connect->hc);
if(res != RES_OK
|| sf_connect->hc < 0)
{
- logger_print(stardis->logger, LOG_ERROR, "Invalid hc: %s\n", tk);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid Convection coefficient: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+
+ ASSERT(sz <= UINT_MAX);
+ ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
+/* SOLID_FLUID_CONNECTION_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_sfc_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct solid_fluid_connect_prog* sf_connect_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.sfconnect_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_sf_connect_prog(stardis->allocator, &desc->d.sf_connect_prog));
+ sf_connect_prog = desc->d.sf_connect_prog;
+ desc->type = DESC_SOLID_FLUID_CONNECT_PROG;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx),
+ "programmed solid-fluid connection name");
+ ERR(description_set_name(stardis, &sf_connect_prog->name, tk));
+ if(find_description_by_name(stardis, &sf_connect_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&sf_connect_prog->prog_name, tk));
+ lib_name = tk;
ASSERT(sz <= UINT_MAX);
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&sf_connect_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &sf_connect_prog->program,
+ &sf_connect_prog->create, &sf_connect_prog->release));
+ GET_LIB_SYMBOL(sf_connect_prog, ref_temp, stardis_reference_temperature);
+ GET_LIB_SYMBOL(sf_connect_prog, emissivity, stardis_emissivity);
+ GET_LIB_SYMBOL(sf_connect_prog, alpha, stardis_specular_fraction);
+ 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);
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(sf_connect_prog);
+
+ sf_connect_prog->t_range(sf_connect_prog->prog_data, stardis->t_range);
+
end:
+ str_release(&tmp);
return res;
error:
goto end;
@@ -658,7 +1164,7 @@ process_ssc
sz = darray_descriptions_size_get(&stardis->descriptions);
ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
- ERR(init_ss(stardis->allocator, &desc->d.ss_connect));
+ ERR(init_ss_connect(stardis->allocator, &desc->d.ss_connect));
ss_connect = desc->d.ss_connect;
desc->type = DESC_SOLID_SOLID_CONNECT;
@@ -667,7 +1173,7 @@ process_ssc
* we continue the trend to ensure connection ID is OK */
ss_connect->connection_id = allocate_stardis_medium_id(stardis);
- CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid solid connection name");
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-solid connection name");
ERR(description_set_name(stardis, &ss_connect->name, tk));
if(find_description_by_name(stardis, &ss_connect->name, desc)) {
logger_print(stardis->logger, LOG_ERROR,
@@ -701,6 +1207,73 @@ error:
goto end;
}
+/* SOLID_SOLID_CONNECTION_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_ssc_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct solid_solid_connect_prog* ss_connect_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.sfconnect_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_ss_connect_prog(stardis->allocator, &desc->d.ss_connect_prog));
+ ss_connect_prog = desc->d.ss_connect_prog;
+ desc->type = DESC_SOLID_SOLID_CONNECT_PROG;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx),
+ "programmed solid-solid connection name");
+ ERR(description_set_name(stardis, &ss_connect_prog->name, tk));
+ if(find_description_by_name(stardis, &ss_connect_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&ss_connect_prog->prog_name, tk));
+ lib_name = tk;
+
+ ASSERT(sz <= UINT_MAX);
+ ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
+
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&ss_connect_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &ss_connect_prog->program,
+ &ss_connect_prog->create, &ss_connect_prog->release));
+ GET_LIB_SYMBOL(ss_connect_prog, tcr, stardis_thermal_contact_resistance);
+ if(!ss_connect_prog->tcr) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'stardis_thermal_contact_resistance()' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(ss_connect_prog);
+
+end:
+ return res;
+error:
+ goto end;
+}
+
static res_T
read_imposed_temperature
(struct stardis* stardis,
@@ -800,7 +1373,6 @@ process_solid
ERR(init_solid(stardis->allocator, &desc->d.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_outside = 0;
@@ -889,10 +1461,82 @@ process_solid
/* Actual solid creation is defered until geometry is read to allow
* enclosure shape VS delta analysis (and auto delta computation) */
+ ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
+/* SOLID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_solid_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct solid_prog* solid_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_solid_prog(stardis->allocator, &desc->d.solid_prog));
+ solid_prog = desc->d.solid_prog;
+ desc->type = DESC_MAT_SOLID_PROG;
+ solid_prog->solid_id = allocate_stardis_medium_id(stardis);
ASSERT(sz <= UINT_MAX);
+ solid_prog->desc_id = (unsigned)sz;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed solid name");
+ ERR(description_set_name(stardis, &solid_prog->name, tk));
+ if(find_description_by_name(stardis, &solid_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&solid_prog->prog_name, tk));
+ lib_name = tk;
+
ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx));
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&solid_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &solid_prog->program,
+ &solid_prog->create, &solid_prog->release));
+ GET_LIB_SYMBOL(solid_prog, lambda, stardis_conductivity);
+ GET_LIB_SYMBOL(solid_prog, rho, stardis_volumic_mass);
+ GET_LIB_SYMBOL(solid_prog, cp, stardis_calorific_capacity);
+ GET_LIB_SYMBOL(solid_prog, delta, stardis_delta_solid);
+ GET_LIB_SYMBOL(solid_prog, temp, stardis_medium_temperature);
+ GET_LIB_SYMBOL(solid_prog, vpower, stardis_volumic_power);
+ GET_LIB_SYMBOL(solid_prog, t_range, stardis_t_range);
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(solid_prog);
+
+ solid_prog->t_range(solid_prog->prog_data, stardis->t_range);
+
+ ERR(create_solver_solid_prog(stardis, solid_prog));
+
end:
+ str_release(&tmp);
return res;
error:
goto end;
@@ -920,9 +1564,7 @@ process_fluid
ERR(init_fluid(stardis->allocator, &desc->d.fluid));
fluid = desc->d.fluid;
desc->type = DESC_MAT_FLUID;
-
fluid->fluid_id = allocate_stardis_medium_id(stardis);
- fluid->is_outside = 0;
fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN);
ASSERT(sz <= UINT_MAX);
fluid->desc_id = (unsigned)sz;
@@ -983,10 +1625,79 @@ process_fluid
ERR(create_solver_fluid(stardis, fluid));
+ ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
+/* FLUID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */
+static res_T
+process_fluid_prog
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ const char *lib_name, *desc_name;
+ struct str tmp;
+ size_t sz;
+ struct fluid_prog* fluid_prog;
+ struct stardis_description_create_context ctx;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ str_init(stardis->allocator, &tmp);
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ ERR(init_fluid_prog(stardis->allocator, &desc->d.fluid_prog));
+ fluid_prog = desc->d.fluid_prog;
+ desc->type = DESC_MAT_FLUID_PROG;
+ fluid_prog->fluid_id = allocate_stardis_medium_id(stardis);
ASSERT(sz <= UINT_MAX);
+ fluid_prog->desc_id = (unsigned)sz;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed fluid name");
+ ERR(description_set_name(stardis, &fluid_prog->name, tk));
+ if(find_description_by_name(stardis, &fluid_prog->name, desc)) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+ desc_name = tk;
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name");
+ ERR(str_set(&fluid_prog->prog_name, tk));
+ lib_name = tk;
+
ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx));
+ /* store the end of line as args for custom init */
+ ERR(set_stripped_args(&fluid_prog->args, *tok_ctx));
+ /* get the user-defined functions from the library */
+ ERR(get_prog_common(lib_name, stardis, &fluid_prog->program,
+ &fluid_prog->create, &fluid_prog->release));
+ GET_LIB_SYMBOL(fluid_prog, rho, stardis_volumic_mass);
+ GET_LIB_SYMBOL(fluid_prog, cp, stardis_calorific_capacity);
+ GET_LIB_SYMBOL(fluid_prog, temp, stardis_medium_temperature);
+ GET_LIB_SYMBOL(fluid_prog, t_range, stardis_t_range);
+ /* create and init custom data */
+ ctx.name = desc_name;
+ CREATE_DESC_DATA(fluid_prog);
+
+ fluid_prog->t_range(fluid_prog->prog_data, stardis->t_range);
+
+ ERR(create_solver_fluid_prog(stardis, fluid_prog));
+
end:
+ str_release(&tmp);
return res;
error:
goto end;
@@ -1072,19 +1783,30 @@ error:
}
/* Read medium or boundary line; should be one of:
- * SOLID Name lambda rho cp delta Tinit Timposed volumic_power STL_filenames
+ * SOLID Name lambda rho cp delta Tinit Timposed volumic_power STL_sides_filenames
* FLUID Name rho cp Tinit Timposed STL_filenames
- * H_BOUNDARY_FOR_SOLID Name ref_temperature emissivity specular_fraction hc T_env STL_filenames
+ * H_BOUNDARY_FOR_SOLID Name ref_temperature emissivity specular_fraction hc T_env STL_sides_filenames
* H_BOUNDARY_FOR_FLUID Name ref_temperature emissivity specular_fraction hc T_env STL_filenames
* T_BOUNDARY_FOR_SOLID Name T STL_filenames
* F_BOUNDARY_FOR_SOLID Name F STL_filenames
* SOLID_FLUID_CONNECTION Name ref_temperature emissivity specular_fraction hc STL_filenames
+ *
+ * SOLID_PROG Name Libray STL_sides_filenames [ PROG_PARAMS ... ]
+ * SOLID_PROG Name Libray STL_sides_filenames [ PROG_PARAMS ... ]
+ * H_BOUNDARY_FOR_SOLID_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ * H_BOUNDARY_FOR_FLUID_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ * T_BOUNDARY_FOR_SOLID_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ * F_BOUNDARY_FOR_SOLID_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ * SOLID_FLUID_CONNECTION_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ * SOLID_SOLID_CONNECTION_PROG Name Libray STL_filenames [ PROG_PARAMS ... ]
+ *
* SCALE scale_factor
* TRAD Trad Trad_ref
*
- * STL_filenames = { { FRONT | BACK | BOTH } STL_filename }+
+ * STL_sides_filenames = { { FRONT | BACK | BOTH } STL_filename }+
+ * STL_filenames = { STL_filename }+
*/
-res_T
+static res_T
process_model_line
(const char* file_name,
char* line,
@@ -1102,20 +1824,38 @@ process_model_line
if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID"))
ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, &tok_ctx));
+ else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID_PROG"))
+ ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_SOLID_PROG, &tok_ctx));
else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID"))
ERR(process_h(stardis, DESC_BOUND_H_FOR_FLUID, &tok_ctx));
+ else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID_PROG"))
+ ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_FLUID_PROG, &tok_ctx));
else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID"))
ERR(process_t(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID_PROG"))
+ ERR(process_t_prog(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID"))
ERR(process_flx(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID_PROG"))
+ ERR(process_flx_prog(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION"))
ERR(process_sfc(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION_PROG"))
+ ERR(process_sfc_prog(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION"))
ERR(process_ssc(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION_PROG"))
+ ERR(process_ssc_prog(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "SOLID"))
ERR(process_solid(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "SOLID_PROG"))
+ ERR(process_solid_prog(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "FLUID"))
ERR(process_fluid(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "FLUID_PROG"))
+ ERR(process_fluid_prog(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "PROGRAM"))
+ ERR(process_program(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "SCALE"))
ERR(process_scale(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "TRAD"))
@@ -1137,6 +1877,10 @@ error:
goto end;
}
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+
res_T
get_dummy_solid_id
(struct stardis* stardis,
@@ -1202,3 +1946,62 @@ end:
error:
goto end;
}
+
+res_T
+read_model
+ (const struct darray_str* model_files,
+ struct stardis* stardis)
+{
+ res_T res = RES_OK;
+ const struct str* files = NULL;
+ size_t i;
+ FILE* f = NULL;
+ struct txtrdr* txtrdr = NULL;
+
+ ASSERT(model_files && stardis);
+ files = darray_str_cdata_get(model_files);
+ FOR_EACH(i, 0, darray_str_size_get(model_files)) {
+ const char* name = str_cget(files + i);
+ f = fopen(name, "r");
+ if(!f) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot open model file '%s'\n",
+ name);
+ res = RES_IO_ERR;
+ goto error;
+ }
+ txtrdr_stream(stardis->allocator, f, name, '#', &txtrdr);
+ for(;;) {
+ char* line;
+ ERR(txtrdr_read_line(txtrdr));
+ line = txtrdr_get_line(txtrdr);
+ if(!line) break;
+ ERR(process_model_line(name, line, stardis));
+ }
+ txtrdr_ref_put(txtrdr);
+ txtrdr = NULL;
+ fclose(f);
+ f = NULL;
+ }
+ if(stardis->scale_factor <= 0)
+ stardis->scale_factor = STARDIS_DEFAULT_SCALE_FACTOR;
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Scaling factor is %g\n", stardis->scale_factor);
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Trad is %g, Trad reference is %g\n", stardis->trad, stardis->trad_ref);
+ stardis->t_range[0] = MMIN(stardis->t_range[0], stardis->trad_ref);
+ stardis->t_range[1] = MMAX(stardis->t_range[1], stardis->trad_ref);
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "System T range is [%g %g]\n", SPLIT2(stardis->t_range));
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Picard order is %u\n", stardis->picard_order);
+
+ ASSERT(!f && !txtrdr);
+exit:
+ return res;
+error:
+ if(f) fclose(f);
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ goto exit;
+}
+
diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h
@@ -23,11 +23,8 @@
#include <star/sstl.h>
-struct camera;
struct logger;
-struct mem_allocator;
struct stardis;
-struct dummies;
/* Utility macros */
#define CHK_TOK(x, Name) if((tk = (x)) == NULL) {\
@@ -46,38 +43,31 @@ struct add_geom_ctx {
/* Possible callbacks for sg3d_geometry_add calls
* when void* context is a struct add_geom_ctx */
-extern LOCAL_SYM void
+void
add_geom_ctx_indices
(const unsigned itri,
unsigned ids[3],
void* context);
-extern LOCAL_SYM void
-add_geom_ctx_properties
- (const unsigned itri,
- unsigned prop[3],
- void* context);
-
-extern LOCAL_SYM void
+void
add_geom_ctx_position
(const unsigned ivert,
double pos[3],
void* context);
-extern LOCAL_SYM res_T
-process_model_line
- (const char* file_name,
- char* line,
- struct stardis* stardis);
-
-extern LOCAL_SYM res_T
+res_T
get_dummy_solid_id
(struct stardis* stardis,
unsigned* id);
-extern LOCAL_SYM res_T
+res_T
get_dummy_fluid_id
(struct stardis* stardis,
unsigned* id);
+res_T
+read_model
+ (const struct darray_str* model_files,
+ struct stardis* stardis);
+
#endif /*ARGS_H*/
diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in
@@ -0,0 +1,501 @@
+/* Copyright (C) 2018-2021 |Meso|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
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef STARDIS_PROG_H__
+#define STARDIS_PROG_H__
+
+/* This header file is intended for inclusion in shared libraries defining
+ * programmed descriptions used in stardis model files.
+ * Please refer to stardis(1) and stardis-input(5) man pages for additional
+ * information. */
+
+#define STARDIS_PROG_PROPERTIES_VERSION @STARDIS_PROG_PROPERTIES_VERSION@
+
+/*****************************************************************************/
+/* API types. */
+/* The various functions defining programmed descriptions receive arguments */
+/* of the following types when called from the stardis simulation. */
+/*****************************************************************************/
+
+struct stardis_vertex {
+ double P[3]; /* World space position */
+ double time; /* "Time" of the vertex */
+};
+
+enum stardis_side {
+ FRONT,
+ BACK
+};
+
+struct stardis_interface_fragment {
+ double P[3]; /* World space position */
+ double Ng[3]; /* Normalized world space geometry normal at the interface */
+ double uv[2]; /* Parametric coordinates of the interface */
+ double time; /* Current time */
+ enum stardis_side side;
+};
+
+enum stardis_return_status {
+ STARDIS_SUCCESS,
+ STARDIS_FAILURE
+};
+
+enum stardis_verbosity_levels {
+ STARDIS_VERBOSE_NONE,
+ STARDIS_VERBOSE_ERROR,
+ STARDIS_VERBOSE_WARNING,
+ STARDIS_VERBOSE_INFO
+};
+
+struct stardis_program_context {
+ const char* name; /* Program name */
+ enum stardis_verbosity_levels verbosity_level;
+};
+
+struct stardis_description_create_context {
+ const char* name; /* Description name */
+};
+
+/******************************************************************************/
+/* Optional functions for any programmed library. */
+/* Either all 3 or none of the 3 following functions must be defined. */
+/* If a libray doesn't need its own data, just let these functions undefined. */
+/******************************************************************************/
+
+/* Create the data attached to a given libray.
+ * A NULL result is interpreted as an error and ends the program.
+ * This function is called the first time a description using this library is
+ * processed.
+ * Args is the end of the description line that was following the library path
+ * (if any). */
+extern void*
+stardis_create_library_data
+ (const struct stardis_program_context* ctx,
+ char* args);
+
+/* Finalize the data created by the successive stardis_create_data calls for
+ * the descriptions created using this library.
+ * A STARDIS_FAILURE result ends the program.
+ * This function is called after descriptions creation, before simulation
+ * starts.
+ * Data is the pointer returned by stardis_create_library_data for this
+ * library. */
+enum stardis_return_status
+stardis_finalize_library_data
+ (void* data);
+
+/* Release the data created by stardis_create_library_data.
+ * This function is called after the simulation finished and after releasing
+ * descriptions data.
+ * Data is the pointer returned by stardis_create_library_data for this
+ * library. */
+extern void
+stardis_release_library_data
+ (void* data);
+
+/******************************************************************************/
+/* Mandatory functions for any programmed description regardless of its type. */
+/******************************************************************************/
+
+/* Create the data attached to a given description.
+ * A NULL result is interpreted as an error and ends the program.
+ * This function is called every time a description using this library is
+ * processed.
+ * Data is the pointer returned by stardis_create_library_data for the library
+ * or NULL if stardis_create_library_data is not defined.
+ * Args is the end of the description line that was following the PROG_PARAM
+ * keyword (if any). */
+extern void*
+stardis_create_data
+ (const struct stardis_description_create_context *ctx,
+ void* data,
+ char* args);
+
+/* Release the data created by stardis_create_data.
+ * This function is called after the simulation finished.
+ * Data is the pointer returned by stardis_create_data for the description. */
+extern void
+stardis_release_data
+ (void* data);
+
+/* Get the copyright notice.
+ * A NULL result is interpreted as an error and ends the program.
+ * Data is the pointer returned by stardis_create_data for the description. */
+const char*
+get_copyright_notice
+ (void* data);
+
+/* Get single-line (name and link?) version of the license.
+ * A NULL result is interpreted as an error and ends the program.
+ * Data is the pointer returned by stardis_create_data for the description. */
+const char*
+get_license_short
+ (void* data);
+
+/* Get full license text.
+ * A NULL result is interpreted as an error and ends the program.
+ * Data is the pointer returned by stardis_create_data for the description. */
+const char*
+get_license_text
+ (void* data);
+
+/*****************************************************************************/
+/* Additional mandatory function declarations (sorted by description type). */
+/* Some functions appear multiple times as they are part of more than one */
+/* description requirement. */
+/*****************************************************************************/
+
+/*********************************************************/
+/* Additional mandatory functions for a programmed solid */
+/*********************************************************/
+
+/* Returns the calorific capacity at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_calorific_capacity
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the volumic mass at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_volumic_mass
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the conductivity at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_conductivity
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the delta numerical parameter at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_delta_solid
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the volumic power at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_volumic_power
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the temperature at a given vertex.
+ * If the temperature is not known/imposed the expected return value is -1.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this solid.
+ * Data is the pointer returned by stardis_create_data for this solid. */
+extern double
+stardis_medium_temperature
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Computes the expected temperature range for this solid.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this solid.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+/*********************************************************/
+/* Additional mandatory functions for a programmed fluid */
+/*********************************************************/
+
+/* Returns the calorific capacity at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this fluid.
+ * Data is the pointer returned by stardis_create_data for this fluid. */
+extern double
+stardis_calorific_capacity
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the volumic mass at a given vertex.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this fluid.
+ * Data is the pointer returned by stardis_create_data for this fluid. */
+extern double
+stardis_volumic_mass
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the temperature at a given vertex.
+ * If the temperature is not known/imposed the expected return value is -1.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this fluid.
+ * Data is the pointer returned by stardis_create_data for this fluid. */
+extern double
+stardis_medium_temperature
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Computes the expected temperature range for this fluid.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this fluid.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+/**************************************************************************/
+/* Additional mandatory functions for a programmed H boundary for a fluid */
+/**************************************************************************/
+
+/* Returns the boundary temperature at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_boundary_temperature
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the emissivity at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_emissivity
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the specular fraction at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_specular_fraction
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the convection coefficient at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_convection_coefficient
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the reference temperature at a given fragment.
+ * This temperature is used as a reference to linearize radiative transfer
+ * in Picard computations.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_reference_temperature
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the upper bound of the convection coefficient accross this boundary.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_max_convection_coefficient
+ (void* data);
+
+/* Computes the expected temperature range for this boundary.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this boundary.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+/**************************************************************************/
+/* Additional mandatory functions for a programmed H boundary for a solid */
+/**************************************************************************/
+
+/* Returns the emissivity at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_emissivity
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the specular fraction at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_specular_fraction
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the convection coefficient at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_convection_coefficient
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the reference temperature at a given fragment.
+ * This temperature is used as a reference to linearize radiative transfer
+ * in Picard computations.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_reference_temperature
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the temperature at a given vertex.
+ * The intent is to return the temperature in an implicit fluid enclosing this
+ * solid.
+ * This functions is called at every vertex of every path of the computation
+ * crossing this fluid.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_medium_temperature
+ (const struct stardis_vertex* vtx,
+ void* data);
+
+/* Returns the upper bound of the convection coefficient accross this boundary.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_max_convection_coefficient
+ (void* data);
+
+/* Computes the expected temperature range for this boundary.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this boundary.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+/**************************************************************/
+/* Additional mandatory functions for a programmed T boundary */
+/**************************************************************/
+
+/* Returns the boundary temperature at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_boundary_temperature
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Computes the expected temperature range for this boundary.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this boundary.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+/**************************************************************/
+/* Additional mandatory functions for a programmed F boundary */
+/**************************************************************/
+
+/* Returns the flux at the boundary at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this boundary.
+ * Data is the pointer returned by stardis_create_data for this boundary. */
+extern double
+stardis_boundary_flux
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/**************************************************************************/
+/* Additional mandatory functions for a programmed Solid-Solid connection */
+/**************************************************************************/
+
+/* Returns the thermal contact resistance at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this connection.
+ * Data is the pointer returned by stardis_create_data for this connection. */
+extern double
+stardis_thermal_contact_resistance
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/**************************************************************************/
+/* Additional mandatory functions for a programmed Solid-Fluid connection */
+/**************************************************************************/
+
+/* Returns the emissivity at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this connection.
+ * Data is the pointer returned by stardis_create_data for this connection. */
+extern double
+stardis_emissivity
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the specular fraction at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this connection.
+ * Data is the pointer returned by stardis_create_data for this connection. */
+extern double
+stardis_specular_fraction
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the convection coefficient at a given fragment.
+ * This functions is called every time a path of the computation reaches
+ * this connection.
+ * Data is the pointer returned by stardis_create_data for this connection. */
+extern double
+stardis_convection_coefficient
+ (const struct stardis_interface_fragment* frag,
+ void* data);
+
+/* Returns the upper bound of the convection coefficient accross this connection.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this connection. */
+extern double
+stardis_max_convection_coefficient
+ (void* data);
+
+/* Computes the expected temperature range for this connection.
+ * This functions is called once when initializing the computation.
+ * Data is the pointer returned by stardis_create_data for this connection.
+ * Returns its modified range argument. */
+extern double*
+stardis_t_range
+ (void* data,
+ double range[2]);
+
+#endif
+
diff --git a/src/stardis-program.c b/src/stardis-program.c
@@ -0,0 +1,80 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <rsys/rsys.h>
+#include <rsys/library.h>
+
+#include "stardis-program.h"
+
+res_T
+init_program
+ (struct mem_allocator* allocator,
+ struct program** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->lib_path);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->lib_path);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_program
+ (struct program* program,
+ struct mem_allocator* allocator)
+{
+ ASSERT(program && allocator);
+ str_release(&program->name);
+ str_release(&program->lib_path);
+ str_release(&program->args);
+ if(program->prog_data) {
+ ASSERT(program->release);
+ program->release(program->prog_data);
+ }
+ library_close(program->lib_handle);
+ MEM_RM(allocator, program);
+}
+
+res_T
+str_print_program
+ (struct str* str,
+ const struct program* program)
+{
+ res_T res = RES_OK;
+ ERR(str_append_printf(str, "Library %s", str_cget(&program->name)));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-program.h b/src/stardis-program.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef STARDIS_PROGRAM_H
+#define STARDIS_PROGRAM_H
+
+#include "stardis-app.h"
+
+#include <stardis-prog-properties.h>
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+/* Forward declarations */
+struct mem_allocator;
+
+/* type to store data for libraries involved in programmed descriptions */
+struct program {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str lib_path;
+ struct str args;
+ /* lib handle and function ptrs */
+ void* lib_handle;
+ const char* (*get_copyright_notice)(void*);
+ const char* (*get_license_short)(void*);
+ const char* (*get_license_text)(void*);
+ void* (*create)(struct stardis_program_context*, char*);
+ enum stardis_return_status (*finalize)(void*);
+ void (*release)(void*);
+};
+
+res_T
+init_program
+ (struct mem_allocator* allocator,
+ struct program** dst);
+
+void
+release_program
+ (struct program* program,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_program
+ (struct str* str,
+ const struct program* program);
+
+#endif
diff --git a/src/stardis-sfconnect-prog.c b/src/stardis-sfconnect-prog.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-sfconnect-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_sf_connect_prog
+ (struct mem_allocator* allocator,
+ struct solid_fluid_connect_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->connection_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_sf_connect_prog
+ (struct solid_fluid_connect_prog* connect,
+ struct mem_allocator* allocator)
+{
+ ASSERT(connect && allocator);
+ str_release(&connect->name);
+ str_release(&connect->prog_name);
+ str_release(&connect->args);
+ if(connect->prog_data)
+ connect->release(connect->prog_data);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, connect);
+}
+
+res_T
+str_print_sf_connect_prog
+ (struct str* str,
+ const struct solid_fluid_connect_prog* connect)
+{
+ res_T res = RES_OK;
+ ASSERT(str && connect);
+ ERR(str_append_printf(str,
+ "programmed Solid-Fluid connection '%s': lib='%s', args=[%s]",
+ str_cget(&connect->name), str_cget(&connect->prog_name),
+ str_cget(&connect->args)));
+end:
+ return res;
+error:
+ goto end;
+}
+
+double
+sf_connect_prog_get_hmax
+ (const struct solid_fluid_connect_prog* connect)
+{
+ return connect->hmax(connect->prog_data);
+}
+
diff --git a/src/stardis-sfconnect-prog.h b/src/stardis-sfconnect-prog.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_SF_CONNECT_PROG_H
+#define SDIS_SF_CONNECT_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct stardis;
+struct mem_allocator;
+struct program;
+
+/*******************************************************************************
+ * Solid-Fluid prog data
+ ******************************************************************************/
+struct solid_fluid_connect_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ int is_outside; /* the fluid is used for a boundary */
+ unsigned desc_id; /* id of the boundary; meaningful if is_outside */
+ unsigned connection_id;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*ref_temp)(const struct stardis_interface_fragment*, void*);
+ double (*emissivity)(const struct stardis_interface_fragment*, void*);
+ double (*alpha)(const struct stardis_interface_fragment*, void*);
+ double (*hc)(const struct stardis_interface_fragment*, void*);
+ double (*hmax)(void*);
+ double* (*t_range)(void*, double trange[2]);
+};
+
+res_T
+create_solver_sf_connect_prog
+ (struct stardis* stardis,
+ const struct solid_fluid_connect_prog* connect);
+
+res_T
+init_sf_connect_prog
+ (struct mem_allocator* allocator,
+ struct solid_fluid_connect_prog** dst);
+
+void
+release_sf_connect_prog
+ (struct solid_fluid_connect_prog* connect,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_sf_connect_prog
+ (struct str* str,
+ const struct solid_fluid_connect_prog* connect);
+
+double
+sf_connect_prog_get_hmax
+ (const struct solid_fluid_connect_prog* connect);
+
+#endif
diff --git a/src/stardis-sfconnect.c b/src/stardis-sfconnect.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-sfconnect.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_sf_connect
+ (struct mem_allocator* allocator,
+ struct solid_fluid_connect** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_initialized = 1;
+ (*dst)->connection_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) str_release(&(*dst)->name);
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_sf_connect
+ (struct solid_fluid_connect* connect,
+ struct mem_allocator* allocator)
+{
+ ASSERT(connect && allocator);
+ str_release(&connect->name);
+ MEM_RM(allocator, connect);
+}
+
+res_T
+str_print_sf_connect
+ (struct str* str,
+ const struct solid_fluid_connect* connect)
+{
+ res_T res = RES_OK;
+ ASSERT(str && connect);
+ ERR(str_append_printf(str,
+ "Solid-Fluid connection '%s': "
+ "ref_temperature=%g emissivity=%g, specular_fraction=%g hc=%g",
+ str_cget(&connect->name),
+ connect->ref_temperature, connect->emissivity, connect->specular_fraction,
+ connect->hc));
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-sfconnect.h b/src/stardis-sfconnect.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_SF_CONNECT_H
+#define SDIS_SF_CONNECT_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct mem_allocator;
+
+/*******************************************************************************
+ * Solid-Fluid connection type
+ ******************************************************************************/
+
+struct solid_fluid_connect {
+ struct str name;
+ double ref_temperature;
+ double emissivity;
+ double specular_fraction;
+ double hc;
+ unsigned connection_id;
+};
+
+res_T
+init_sf_connect
+ (struct mem_allocator* allocator,
+ struct solid_fluid_connect** dst);
+
+void
+release_sf_connect
+ (struct solid_fluid_connect* connect,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_sf_connect
+ (struct str* str,
+ const struct solid_fluid_connect* connect);
+
+#endif
diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c
@@ -0,0 +1,200 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-solid-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-app.h"
+
+#include <rsys/mem_allocator.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+
+static double
+solid_prog_get_thermal_conductivity
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->lambda(&v, (*solid_props)->prog_data);
+}
+
+static double
+solid_prog_get_volumic_mass
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->rho(&v, (*solid_props)->prog_data);
+}
+
+static double
+solid_prog_get_calorific_capacity
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->cp(&v, (*solid_props)->prog_data);
+}
+
+static double
+solid_prog_get_delta
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->delta(&v, (*solid_props)->prog_data);
+}
+
+static double
+solid_prog_get_volumic_power
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->vpower(&v, (*solid_props)->prog_data);
+}
+
+static double
+solid_prog_get_temperature
+ (const struct sdis_rwalk_vertex* vtx,
+ struct sdis_data* data)
+{
+ const struct solid_prog* const* solid_props = sdis_data_cget(data);
+ struct stardis_vertex v;
+ d3_set(v.P, vtx->P);
+ v.time = vtx->time;
+ return (*solid_props)->temp(&v, (*solid_props)->prog_data);
+}
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+
+res_T
+create_solver_solid_prog
+ (struct stardis* stardis,
+ const struct solid_prog* solid_props)
+{
+ res_T res = RES_OK;
+ struct sdis_solid_shader solid_shader = SDIS_SOLID_SHADER_NULL;
+ struct sdis_data* data = NULL;
+ const struct solid_prog** props;
+
+ ASSERT(stardis && solid_props);
+ solid_shader.calorific_capacity = solid_prog_get_calorific_capacity;
+ solid_shader.thermal_conductivity = solid_prog_get_thermal_conductivity;
+ solid_shader.volumic_mass = solid_prog_get_volumic_mass;
+ solid_shader.delta= solid_prog_get_delta;
+ solid_shader.volumic_power = solid_prog_get_volumic_power;
+ solid_shader.temperature = solid_prog_get_temperature;
+ ERR(sdis_data_create(stardis->dev, sizeof(struct solid_prog*),
+ ALIGNOF(struct solid_prog*), NULL, &data));
+
+ props = sdis_data_get(data); /* Fetch the allocated memory space */
+ *props = solid_props;
+ if(solid_props->solid_id >= darray_media_ptr_size_get(&stardis->media)) {
+ ERR(darray_media_ptr_resize(&stardis->media, solid_props->solid_id + 1));
+ }
+ ASSERT(!darray_media_ptr_data_get(&stardis->media)[solid_props->solid_id]);
+ ERR(sdis_solid_create(stardis->dev, &solid_shader, data,
+ darray_media_ptr_data_get(&stardis->media) + solid_props->solid_id));
+
+end:
+ if(data) SDIS(data_ref_put(data));
+ return res;
+error:
+ goto end;
+}
+
+res_T
+init_solid_prog(struct mem_allocator* allocator, struct solid_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->desc_id = UINT_MAX;
+ (*dst)->solid_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_solid_prog
+ (struct solid_prog* solid,
+ struct mem_allocator* allocator)
+{
+ ASSERT(solid && allocator);
+ str_release(&solid->name);
+ str_release(&solid->prog_name);
+ str_release(&solid->args);
+
+ if(solid->prog_data)
+ solid->release(solid->prog_data);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, solid);
+}
+
+res_T
+str_print_solid_prog(struct str* str, const struct solid_prog* f)
+{
+ res_T res = RES_OK;
+ ASSERT(str && f);
+ ERR(str_append_printf(str,
+ "programmed solid '%s': lib='%s', args=[%s] (it is medium %u)",
+ str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args),
+ f->solid_id));
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-solid-prog.h b/src/stardis-solid-prog.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_SOLID_PROG_H
+#define SDIS_SOLID_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct stardis;
+struct mem_allocator;
+struct program;
+
+/*******************************************************************************
+ * Solid prog data
+ ******************************************************************************/
+struct solid_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ int is_outside; /* the solid is used for a boundary */
+ unsigned desc_id; /* id of the boundary; meaningful if is_outside */
+ unsigned solid_id;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*lambda)(const struct stardis_vertex*, void*);
+ double (*rho)(const struct stardis_vertex*, void*);
+ double (*cp)(const struct stardis_vertex*, void*);
+ 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*, double trange[2]);
+};
+
+res_T
+create_solver_solid_prog
+ (struct stardis* stardis,
+ const struct solid_prog* solid_props);
+
+res_T
+init_solid_prog
+ (struct mem_allocator* allocator,
+ struct solid_prog** dst);
+
+void
+release_solid_prog
+ (struct solid_prog* solid,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_solid_prog
+ (struct str* str,
+ const struct solid_prog* s);
+
+#endif
diff --git a/src/stardis-solid.c b/src/stardis-solid.c
@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "stardis-solid.h"
-#include "stardis-compute.h"
#include "stardis-app.h"
#include <sdis.h>
@@ -203,18 +202,18 @@ str_print_solid(struct str* str, const struct solid* s)
{
res_T res = RES_OK;
ASSERT(str && s);
- STR_APPEND_PRINTF(str, "Solid '%s': lambda=%g rho=%g cp=%g delta=%g",
- ARG5( str_cget(&s->name), s->lambda, s->rho, s->cp, s->delta ) );
+ ERR(str_append_printf(str, "Solid '%s': lambda=%g rho=%g cp=%g delta=%g",
+ str_cget(&s->name), s->lambda, s->rho, s->cp, s->delta));
if(s->vpower != 0) {
- STR_APPEND_PRINTF(str, " VPower=%g", ARG1( s->vpower ) );
+ ERR(str_append_printf(str, " VPower=%g", s->vpower));
}
if(s->tinit >= 0) {
- STR_APPEND_PRINTF(str, " Tinit=%g", ARG1( s->tinit ) );
+ ERR(str_append_printf(str, " Tinit=%g", s->tinit));
}
if(s->imposed_temperature >= 0) {
- STR_APPEND_PRINTF(str, " Temp=%g", ARG1( s->imposed_temperature ) );
+ ERR(str_append_printf(str, " Temp=%g", s->imposed_temperature));
}
- STR_APPEND_PRINTF(str, " (it is medium %u)", ARG1( s->solid_id ) );
+ ERR(str_append_printf(str, " (it is medium %u)", s->solid_id));
end:
return res;
error:
diff --git a/src/stardis-solid.h b/src/stardis-solid.h
@@ -37,22 +37,22 @@ struct solid {
double t0; /* End time of tinit */
int is_outside; /* the solid is used for a boundary */
int is_green; /* green computation (nothing to do with solid itself) */
- unsigned desc_id; /* id of the boundary; meaningful if is_outside */
+ unsigned desc_id;
unsigned solid_id;
};
-LOCAL_SYM res_T
+res_T
init_solid(struct mem_allocator* allocator, struct solid** dst);
-LOCAL_SYM void
+void
release_solid
(struct solid* desc,
struct mem_allocator* allocator);
-LOCAL_SYM res_T
+res_T
str_print_solid(struct str* str, const struct solid* solid);
-LOCAL_SYM res_T
+res_T
create_solver_solid
(struct stardis* stardis,
const struct solid* solid_props);
diff --git a/src/stardis-ssconnect-prog.c b/src/stardis-ssconnect-prog.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-ssconnect-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_ss_connect_prog
+ (struct mem_allocator* allocator,
+ struct solid_solid_connect_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->connection_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ (*dst)->connection_id = UINT_MAX;
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_ss_connect_prog
+ (struct solid_solid_connect_prog* connect,
+ struct mem_allocator* allocator)
+{
+ ASSERT(connect && allocator);
+ str_release(&connect->name);
+ str_release(&connect->prog_name);
+ str_release(&connect->args);
+ if(connect->prog_data)
+ connect->release(connect->prog_data);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, connect);
+}
+
+res_T
+str_print_ss_connect_prog
+ (struct str* str,
+ const struct solid_solid_connect_prog* connect)
+{
+ res_T res = RES_OK;
+ ASSERT(str && connect);
+ ERR(str_append_printf(str,
+ "programmed Solid-Solid connection '%s': lib='%s', args=[%s]",
+ str_cget(&connect->name), str_cget(&connect->prog_name),
+ str_cget(&connect->args)));
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-ssconnect-prog.h b/src/stardis-ssconnect-prog.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_SS_CONNECT_PROG_H
+#define SDIS_SS_CONNECT_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct stardis;
+struct mem_allocator;
+struct program;
+
+/*******************************************************************************
+ * Solid-Solid prog data
+ ******************************************************************************/
+struct solid_solid_connect_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*tcr)(const struct stardis_interface_fragment*, void*);
+ unsigned connection_id;
+};
+
+res_T
+create_solver_ss_connect_prog
+ (struct stardis* stardis,
+ const struct solid_solid_connect_prog* connect);
+
+res_T
+init_ss_connect_prog
+ (struct mem_allocator* allocator,
+ struct solid_solid_connect_prog** dst);
+
+void
+release_ss_connect_prog
+ (struct solid_solid_connect_prog* connect,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_ss_connect_prog
+ (struct str* str,
+ const struct solid_solid_connect_prog* connect);
+
+#endif
+
diff --git a/src/stardis-ssconnect.c b/src/stardis-ssconnect.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-ssconnect.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_ss_connect
+ (struct mem_allocator* allocator,
+ struct solid_solid_connect** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_initialized = 1;
+ (*dst)->connection_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) str_release(&(*dst)->name);
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_ss_connect
+ (struct solid_solid_connect* connect,
+ struct mem_allocator* allocator)
+{
+ ASSERT(connect && allocator);
+ str_release(&connect->name);
+ MEM_RM(allocator, connect);
+}
+
+res_T
+str_print_ss_connect
+ (struct str* str,
+ const struct solid_solid_connect* connect)
+{
+ res_T res = RES_OK;
+ ASSERT(str && connect);
+ ERR(str_append_printf(str,
+ "Solid-Solid connection '%s': contact resistance=%g",
+ str_cget(&connect->name), connect->tcr));
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-ssconnect.h b/src/stardis-ssconnect.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_SS_CONNECT_H
+#define SDIS_SS_CONNECT_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct mem_allocator;
+
+/*******************************************************************************
+ * Solid-Solid connection type
+ ******************************************************************************/
+struct solid_solid_connect {
+ struct str name;
+ double tcr;
+ unsigned connection_id;
+};
+
+res_T
+init_ss_connect
+ (struct mem_allocator* allocator,
+ struct solid_solid_connect** dst);
+
+void
+release_ss_connect
+ (struct solid_solid_connect* connect,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_ss_connect
+ (struct str* str,
+ const struct solid_solid_connect* cconnect);
+
+#endif
diff --git a/src/stardis-tbound-prog.c b/src/stardis-tbound-prog.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-tbound-prog.h"
+#include "stardis-prog-properties.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_t_boundary_prog
+ (struct mem_allocator* allocator,
+ struct t_boundary_prog** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_init(allocator, &(*dst)->prog_name);
+ str_init(allocator, &(*dst)->args);
+ str_initialized = 1;
+ (*dst)->mat_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) {
+ str_release(&(*dst)->name);
+ str_release(&(*dst)->prog_name);
+ str_release(&(*dst)->args);
+ }
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_t_boundary_prog
+ (struct t_boundary_prog* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ str_release(&bound->prog_name);
+ str_release(&bound->args);
+ if(bound->prog_data)
+ bound->release(bound->prog_data);
+ /* library_close call is managed at lib_data level */
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_t_boundary_prog
+ (struct str* str,
+ const struct t_boundary_prog* b)
+{
+ res_T res = RES_OK;
+ ASSERT(str && b);
+ ERR(str_append_printf(str,
+ "programmed T boundary for solid '%s': lib='%s', args=[%s] "
+ "(using medium %u as external medium)",
+ str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args),
+ b->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
+
diff --git a/src/stardis-tbound-prog.h b/src/stardis-tbound-prog.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_TBOUND_PROG_H
+#define SDIS_TBOUND_PROG_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+#include "stardis-prog-properties.h"
+
+struct mem_allocator;
+struct program;
+
+/*******************************************************************************
+ * T boundary prog data
+ ******************************************************************************/
+struct t_boundary_prog {
+ void* prog_data; /* result of the create() call */
+ struct str name;
+ struct str prog_name;
+ struct str args;
+ /* lib handle and function ptrs */
+ struct program* program;
+ void* (*create)
+ (const struct stardis_description_create_context*, void*, char*);
+ void (*release)(void*);
+ double (*temperature)(const struct stardis_interface_fragment*, void*);
+ double* (*t_range)(void*, double trange[2]);
+ unsigned mat_id;
+};
+
+res_T
+init_t_boundary_prog
+ (struct mem_allocator* allocator,
+ struct t_boundary_prog** dst);
+
+void
+release_t_boundary_prog
+ (struct t_boundary_prog* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_t_boundary_prog
+ (struct str* str,
+ const struct t_boundary_prog* bound);
+
+#endif
+
diff --git a/src/stardis-tbound.c b/src/stardis-tbound.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "stardis-app.h"
+#include "stardis-tbound.h"
+#include "stardis-fluid.h"
+#include "stardis-intface.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/str.h>
+
+#include <sdis.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
+res_T
+init_t_boundary
+ (struct mem_allocator* allocator,
+ struct t_boundary** dst)
+{
+ res_T res = RES_OK;
+ int str_initialized = 0;
+ ASSERT(allocator && dst && *dst == NULL);
+ *dst = MEM_CALLOC(allocator, 1, sizeof(**dst));
+ if(! *dst) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ str_init(allocator, &(*dst)->name);
+ str_initialized = 1;
+ (*dst)->imposed_temperature = -1;
+ (*dst)->mat_id = UINT_MAX;
+end:
+ return res;
+error:
+ if(str_initialized) str_release(&(*dst)->name);
+ if(*dst) MEM_RM(allocator, *dst);
+ goto end;
+}
+
+void
+release_t_boundary
+ (struct t_boundary* bound,
+ struct mem_allocator* allocator)
+{
+ ASSERT(bound && allocator);
+ str_release(&bound->name);
+ MEM_RM(allocator, bound);
+}
+
+res_T
+str_print_t_boundary
+ (struct str* str,
+ const struct t_boundary* b)
+{
+ res_T res = RES_OK;
+ ASSERT(str && b);
+ ERR(str_append_printf(str,
+ "T boundary for solid '%s': T=%g (using medium %u as external medium)",
+ str_cget(&b->name), b->imposed_temperature, b->mat_id));
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-tbound.h b/src/stardis-tbound.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SDIS_TBOUND_H
+#define SDIS_TBOUND_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct mem_allocator;
+
+/*******************************************************************************
+ * H boundary type
+ ******************************************************************************/
+struct t_boundary {
+ struct str name;
+ double imposed_temperature;
+ unsigned mat_id;
+};
+
+res_T
+init_t_boundary
+ (struct mem_allocator* allocator,
+ struct t_boundary** dst);
+
+void
+release_t_boundary
+ (struct t_boundary* bound,
+ struct mem_allocator* allocator);
+
+res_T
+str_print_t_boundary
+ (struct str* str,
+ const struct t_boundary* bound);
+
+#endif
diff --git a/stardis-prog-properties/stardis-prog-properties-config-version.cmake.in b/stardis-prog-properties/stardis-prog-properties-config-version.cmake.in
@@ -0,0 +1,22 @@
+# Copyright (C) 2018-2022 |Meso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+SET(PACKAGE_VERSION @STARDIS_PROG_PROPERTIES_VERSION@)
+
+IF (${PACKAGE_FIND_VERSION_MAJOR} EQUAL @STARDIS_PROG_PROPERTIES_VERSION@)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ELSE()
+ SET(PACKAGE_VERSION_UNSUITABLE 1)
+ENDIF()
diff --git a/stardis-prog-properties/stardis-prog-properties-config.cmake b/stardis-prog-properties/stardis-prog-properties-config.cmake
@@ -0,0 +1,28 @@
+# Copyright (C) 2013-2017, 2021 Vincent Forest (vaplv@free.fr)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+cmake_minimum_required(VERSION 3.1)
+include(SelectLibraryConfigurations)
+
+# Try to find stardis-prog-properties
+
+# Look for stardis-prog-properties header
+find_path(SPROG_INCLUDE_DIR stardis/stardis-prog-properties.h)
+
+# Check the package
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(stardis-prog-properties DEFAULT_MSG
+ SPROG_INCLUDE_DIR)
+