commit 12b4baed7d0dd73b11b2dc16c84f8b142f56f159
parent 9d1152d78345c0db8905fa2c1bf6ecee66f106f0
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 23 Dec 2021 17:49:01 +0100
Add first programmable description (fluid_prog)
Diffstat:
8 files changed, 467 insertions(+), 24 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -126,8 +126,12 @@ set(SDIS_FILES_SRC
stardis-main.c
stardis-output.c
stardis-parsing.c
+ stardis-prog.c
stardis-solid.c)
+set(SDIS_FILES_INC_API
+ stardis-prog-common.h)
+
set(SDIS_FILES_INC
stardis-app.h
stardis-args.h
@@ -137,6 +141,7 @@ set(SDIS_FILES_INC
stardis-intface.h
stardis-output.h
stardis-parsing.h
+ stardis-prog.h
stardis-solid.h
stardis-version.h.in)
@@ -145,6 +150,7 @@ set(SDIS_FILES_DOC COPYING README.md)
# Prepend each file by `SDIS_SOURCE_DIR'
rcmake_prepend_path(SDIS_FILES_SRC ${SDIS_SOURCE_DIR})
rcmake_prepend_path(SDIS_FILES_INC ${SDIS_SOURCE_DIR})
+rcmake_prepend_path(SDIS_FILES_INC_API ${SDIS_SOURCE_DIR})
rcmake_prepend_path(SDIS_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
add_executable(stardis
@@ -171,6 +177,7 @@ install(TARGETS stardis
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
+install(FILES ${SDIS_FILES_INC_API} DESTINATION include/)
install(FILES ${SDIS_FILES_DOC} DESTINATION share/doc/stardis)
rcmake_copy_runtime_libraries(stardis)
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -21,6 +21,7 @@
#include "stardis-default.h"
#include "stardis-solid.h"
#include "stardis-fluid.h"
+#include "stardis-prog.h"
#include <star/sstl.h>
#include <star/sg3d.h>
@@ -98,6 +99,7 @@ enum properties_conflict_t {
enum description_type {
DESC_MAT_SOLID,
DESC_MAT_FLUID,
+ DESC_MAT_FLUID_PROG,
DESC_BOUND_H_FOR_FLUID,
DESC_BOUND_H_FOR_SOLID,
DESC_BOUND_T_FOR_SOLID,
@@ -114,10 +116,16 @@ enum description_type {
((D) == DESC_BOUND_T_FOR_SOLID)
#define DESC_IS_F(D) \
((D) == DESC_BOUND_F_FOR_SOLID)
+#define DESC_IS_SOLID(D) \
+ ((D) == DESC_MAT_SOLID)
+#define DESC_IS_FLUID(D) \
+ ((D) == DESC_MAT_FLUID || (D) == DESC_MAT_FLUID_PROG)
#define DESC_IS_MEDIUM(D) \
- ((D) == DESC_MAT_SOLID || (D) == DESC_MAT_FLUID)
+ (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_PROG(D) \
+ ((D) == DESC_MAT_FLUID_PROG)
#define DARRAY_NAME interface_ptrs
#define DARRAY_DATA struct sdis_interface*
@@ -198,6 +206,7 @@ error:
/******************************************************************************/
struct fluid;
+struct fluid_prog;
struct solid;
struct t_boundary;
struct f_boundary;
@@ -209,6 +218,7 @@ struct description {
enum description_type type;
union {
struct fluid* fluid;
+ struct fluid_prog* fluid_prog;
struct solid* solid;
struct t_boundary* t_boundary;
struct f_boundary* f_boundary;
@@ -549,6 +559,9 @@ release_description
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);
@@ -587,6 +600,9 @@ str_print_description
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;
@@ -622,6 +638,8 @@ get_description_name
return &desc->d.solid->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_H_FOR_SOLID:
@@ -651,6 +669,9 @@ description_get_medium_id
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;
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -245,7 +245,7 @@ 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) {
+ if(DESC_IS_SOLID(filter_ctx.desc->type)) {
struct solid* solid = filter_ctx.desc->d.solid;
ASSERT(solid->delta < INF);
logger_print(stardis->logger, LOG_OUTPUT,
@@ -272,9 +272,18 @@ check_probe_conform_to_type
filter_ctx.dist / solid->delta);
}
} else {
+ ASSERT(DESC_IS_FLUID(filter_ctx.desc->type));
/* TODO: check move length wrt local geometry? */
- logger_print(stardis->logger, LOG_OUTPUT,
- "Probe was in fluid '%s'.\n", str_cget(&filter_ctx.desc->d.fluid->name));
+ if(filter_ctx.desc->type == DESC_MAT_FLUID) {
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Probe was in fluid '%s'.\n",
+ str_cget(&filter_ctx.desc->d.fluid->name));
+ } else {
+ ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG);
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Probe was in programmed fluid '%s'.\n",
+ str_cget(&filter_ctx.desc->d.fluid_prog->name));
+ }
logger_print(stardis->logger, LOG_OUTPUT,
"Probe distance from closest boundary was %g.\n", filter_ctx.dist);
}
@@ -328,9 +337,7 @@ 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) {
+ if(DESC_IS_SOLID(filter_ctx.desc->type)) {
struct solid* solid = filter_ctx.desc->d.solid;
if(filter_ctx.dist < 0.25 * solid->delta) {
logger_print(stardis->logger, LOG_ERROR,
@@ -353,11 +360,20 @@ check_probe_conform_to_type
filter_ctx.dist / solid->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->type));
/* 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 '%s': computing fluid temperature, "
+ "not using a specific position.\n",
+ str_cget(&filter_ctx.desc->d.fluid_prog->name));
+ }
}
}
diff --git a/src/stardis-intface.c b/src/stardis-intface.c
@@ -172,6 +172,13 @@ create_intface
front_med = media[id];
fluid_side_shader = &interface_shader.front;
break;
+ case DESC_MAT_FLUID_PROG:
+ fluid_count++;
+ id = descriptions[fd].d.fluid_prog->fluid_id;
+ interface_props->front_medium_id = id;
+ front_med = media[id];
+ fluid_side_shader = &interface_shader.front;
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -193,6 +200,15 @@ create_intface
* fluids and this case lead to an error */
fluid_side_shader = &interface_shader.back;
break;
+ case DESC_MAT_FLUID_PROG:
+ fluid_count++;
+ id = descriptions[bd].d.fluid_prog->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 */
+ fluid_side_shader = &interface_shader.back;
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -216,12 +232,12 @@ create_intface
}
if(front_defined) {
def_medium = front_med;
- fluid_side_shader = (descriptions[fd].type == DESC_MAT_FLUID)
+ fluid_side_shader = DESC_IS_FLUID(descriptions[fd].type)
? &interface_shader.front : &interface_shader.back;
} else {
ASSERT(back_defined);
def_medium = back_med;
- fluid_side_shader = (descriptions[bd].type == DESC_MAT_FLUID)
+ fluid_side_shader = DESC_IS_FLUID(descriptions[bd].type)
? &interface_shader.back : &interface_shader.front;
}
interface_props->desc_id = cd;
diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c
@@ -24,6 +24,7 @@
#include <rsys/double3.h>
#include <sdis_version.h>
#include <rsys/logger.h>
+#include <rsys/library.h>
#include <getopt.h>
#include <stdlib.h>
@@ -140,7 +141,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,
@@ -171,9 +172,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");
@@ -257,7 +258,7 @@ description_set_name
res_T res = RES_OK;
double foo;
const char* keywords[] = {
- "AUTO", "BACK", "BOTH", "FLUID", "FRONT", "F_BOUNDARY_FOR_SOLID",
+ "AUTO", "BACK", "BOTH", "FLUID", "FLUID_PROG", "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" };
@@ -405,8 +406,7 @@ process_h
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));
@@ -790,7 +790,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;
@@ -879,7 +878,6 @@ process_solid
/* Actual solid creation is defered until geometry is read to allow
* enclosure shape VS delta analysis (and auto delta computation) */
- ASSERT(sz <= UINT_MAX);
ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx));
end:
@@ -910,9 +908,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;
@@ -973,9 +969,136 @@ 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 Prog_filename 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;
+ struct str tmp;
+ size_t sz;
+ struct fluid_prog* fluid_prog;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.fmed_count++;
+
+ 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), "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;
+ }
+
+ 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 */
+ if(tok_ctx) {
+ ERR(str_set(&fluid_prog->args, *tok_ctx));
+ }
+
+ fluid_prog->lib = library_open(lib_name);
+ if(!fluid_prog->lib) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot open library: %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->create
+ = library_get_symbol(fluid_prog->lib, "create_fluid_data");
+ if(!fluid_prog->create) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'create_fluid_data' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ fluid_prog->prog_data = fluid_prog->create();
+ if(!fluid_prog->prog_data) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot create fluid data %s\n", str_cget(&fluid_prog->name));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->init
+ = library_get_symbol(fluid_prog->lib, "init_fluid_data");
+ if(!fluid_prog->init) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'init_fluid_data' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* duplicate args to allow init() to modify them */
+ str_init(stardis->allocator, &tmp);
+ ERR(str_copy(&tmp, &fluid_prog->args));
+ if(fluid_prog->init(fluid_prog->prog_data, str_get(&tmp))) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot init fluid_prog data %s\n", str_cget(&fluid_prog->name));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->release
+ = library_get_symbol(fluid_prog->lib, "release_fluid_data");
+ if(!fluid_prog->release) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'release_fluid_data' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->cp
+ = library_get_symbol(fluid_prog->lib, "calorific_capacity");
+ if(!fluid_prog->cp) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'calorific_capacity()' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->rho
+ = library_get_symbol(fluid_prog->lib, "volumic_mass");
+ if(!fluid_prog->rho) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'volumic_mass()' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *(void**)&fluid_prog->temp
+ = library_get_symbol(fluid_prog->lib, "temperature");
+ if(!fluid_prog->temp) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot find function 'temperature()' in lib %s\n", lib_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ ERR(create_solver_fluid_prog(stardis, fluid_prog));
+
end:
return res;
error:
@@ -1106,6 +1229,8 @@ process_model_line
ERR(process_solid(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, "SCALE"))
ERR(process_scale(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "TRAD"))
diff --git a/src/stardis-prog-common.h b/src/stardis-prog-common.h
@@ -0,0 +1,31 @@
+
+/* 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_COMMON_H__
+#define STARDIS_PROG_COMMON_H__
+
+enum stardis_return_codes {
+ STARDIS_SUCCESS,
+ STARDIS_FAILURE
+};
+
+struct walk_vertex {
+ double P[3]; /* World space position */
+ double time; /* "Time" of the vertex */
+};
+
+#endif
+
diff --git a/src/stardis-prog.c b/src/stardis-prog.c
@@ -0,0 +1,162 @@
+/* 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-prog.h"
+#include "stardis-compute.h"
+#include "stardis-app.h"
+
+#include <rsys/library.h>
+#include <rsys/logger.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);
+ return (*fluid_props)->cp(vtx, (*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);
+ return (*fluid_props)->rho(vtx, (*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);
+ return (*fluid_props)->temp(vtx, (*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
+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_ALLOC(allocator, sizeof(struct fluid_prog));
+ 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)->prog_data = NULL;
+ (*dst)->is_outside = 0;
+ (*dst)->desc_id = UINT_MAX;
+ (*dst)->fluid_id = UINT_MAX;
+ (*dst)->lib = NULL;
+ (*dst)->cp = NULL;
+ (*dst)->rho = NULL;
+ (*dst)->temp = NULL;
+ (*dst)->create = NULL;
+ (*dst)->release = NULL;
+ (*dst)->init = NULL;
+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(fluid->prog_data);
+ fluid->prog_data = NULL;
+ }
+ 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);
+ STR_APPEND_PRINTF(str, "programmed fluid '%s': lib='%s', args=[%s]",
+ ARG3( str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args) ) );
+ STR_APPEND_PRINTF(str, " (it is medium %u)", ARG1( f->fluid_id ) );
+end:
+ return res;
+error:
+ goto end;
+}
diff --git a/src/stardis-prog.h b/src/stardis-prog.h
@@ -0,0 +1,65 @@
+/* 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_PROG_H
+#define SDIS_PROG_H
+
+#include <sdis.h>
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct stardis;
+
+/*******************************************************************************
+ * Fluid prog data
+ ******************************************************************************/
+struct fluid_prog {
+ /* This field must come first as a struct fluid_prog* must be usable as
+ * an struct custom_data** */
+ void* prog_data; /* result of the init_fluid() 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 */
+ void* lib;
+ double (*cp)(const struct sdis_rwalk_vertex*, struct sdis_data*);
+ double (*rho)(const struct sdis_rwalk_vertex*, struct sdis_data*);
+ double (*temp)(const struct sdis_rwalk_vertex*, struct sdis_data*);
+ void* (*create)();
+ int (*init)(void*, const char*);
+ void (*release)(void*);
+};
+
+res_T
+create_solver_fluid_prog
+ (struct stardis* stardis,
+ const struct fluid_prog* fluid_props);
+
+LOCAL_SYM res_T
+init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst);
+
+LOCAL_SYM void
+release_fluid_prog
+ (struct fluid_prog* fluid,
+ struct mem_allocator* allocator);
+
+LOCAL_SYM res_T
+str_print_fluid_prog(struct str* str, const struct fluid_prog* s);
+
+#endif