stardis

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

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:
Mcmake/CMakeLists.txt | 41+++++++++++++++++++++++++++++++++++++++--
Acmake/stardis-prog-properties/CMakeLists.txt | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/stardis-input.5.txt | 288++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mdoc/stardis.1.txt.in | 4+++-
Msrc/stardis-app.c | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/stardis-app.h | 656+++++--------------------------------------------------------------------------
Msrc/stardis-args.c | 1+
Msrc/stardis-args.h | 13++++++-------
Msrc/stardis-compute.c | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/stardis-compute.h | 7+++----
Asrc/stardis-description.c | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-description.h | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound-prog.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound-prog.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fluid-prog.c | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fluid-prog.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-fluid.c | 11+++++------
Msrc/stardis-fluid.h | 8++++----
Asrc/stardis-hbound-prog.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hbound-prog.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hbound.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hbound.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-intface.c | 455++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/stardis-intface.h | 17+++++++++++++----
Msrc/stardis-main.c | 1+
Msrc/stardis-output.c | 23++++++++++++++---------
Msrc/stardis-output.h | 32++++++++++++++++----------------
Msrc/stardis-parsing.c | 929+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/stardis-parsing.h | 28+++++++++-------------------
Asrc/stardis-prog-properties.h.in | 501+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-program.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-program.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-sfconnect-prog.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-sfconnect-prog.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-sfconnect.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-sfconnect.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-solid-prog.c | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-solid-prog.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-solid.c | 13++++++-------
Msrc/stardis-solid.h | 10+++++-----
Asrc/stardis-ssconnect-prog.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-ssconnect-prog.h | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-ssconnect.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-ssconnect.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound-prog.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound-prog.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Astardis-prog-properties/stardis-prog-properties-config-version.cmake.in | 22++++++++++++++++++++++
Astardis-prog-properties/stardis-prog-properties-config.cmake | 28++++++++++++++++++++++++++++
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(&degenerated); } @@ -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) +