stardis-fluid-prog.c (6495B)
1 /* Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "stardis-fluid-prog.h" 17 #include "stardis-app.h" 18 #include "stardis-prog-properties.h" 19 #include "stardis-app.h" 20 21 #include <rsys/mem_allocator.h> 22 23 #include <sdis.h> 24 25 #include <limits.h> 26 27 /******************************************************************************* 28 * Local Functions 29 ******************************************************************************/ 30 static double 31 fluid_prog_get_calorific_capacity 32 (const struct sdis_rwalk_vertex* vtx, 33 struct sdis_data* data) 34 { 35 const struct fluid_prog* const* fluid_props = sdis_data_cget(data); 36 struct stardis_vertex v; 37 d3_set(v.P, vtx->P); 38 v.time = vtx->time; 39 return (*fluid_props)->cp(&v, (*fluid_props)->prog_data); 40 } 41 42 static double 43 fluid_prog_get_volumic_mass 44 (const struct sdis_rwalk_vertex* vtx, 45 struct sdis_data* data) 46 { 47 const struct fluid_prog* const* fluid_props = sdis_data_cget(data); 48 struct stardis_vertex v; 49 d3_set(v.P, vtx->P); 50 v.time = vtx->time; 51 return (*fluid_props)->rho(&v, (*fluid_props)->prog_data); 52 } 53 54 static double 55 fluid_prog_get_temperature 56 (const struct sdis_rwalk_vertex* vtx, 57 struct sdis_data* data) 58 { 59 const struct fluid_prog* const* fluid_props = sdis_data_cget(data); 60 struct stardis_vertex v; 61 double temp = 0; 62 d3_set(v.P, vtx->P); 63 v.time = vtx->time; 64 temp = (*fluid_props)->temp(&v, (*fluid_props)->prog_data); 65 return STARDIS_TEMPERATURE_IS_KNOWN(temp) ? temp : SDIS_TEMPERATURE_NONE;; 66 } 67 68 /******************************************************************************* 69 * Public Functions 70 ******************************************************************************/ 71 res_T 72 create_solver_fluid_prog 73 (struct stardis* stardis, 74 const struct fluid_prog* fluid_props) 75 { 76 res_T res = RES_OK; 77 struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL; 78 struct sdis_data* data = NULL; 79 const struct fluid_prog** props; 80 81 ASSERT(stardis && fluid_props); 82 fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity; 83 fluid_shader.volumic_mass = fluid_prog_get_volumic_mass; 84 fluid_shader.temperature = fluid_prog_get_temperature; 85 fluid_shader.t0 = stardis->initial_time; 86 ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*), 87 ALIGNOF(struct fluid_prog*), NULL, &data)); 88 89 props = sdis_data_get(data); /* Fetch the allocated memory space */ 90 *props = fluid_props; 91 if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) { 92 ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1)); 93 } 94 ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]); 95 ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data, 96 darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id)); 97 98 end: 99 if(data) SDIS(data_ref_put(data)); 100 return res; 101 error: 102 goto end; 103 } 104 105 res_T 106 create_solver_external_fluid_prog 107 (struct stardis* stardis, 108 const struct fluid_prog* fluid_props) 109 { 110 res_T res = RES_OK; 111 struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL; 112 struct sdis_data* data = NULL; 113 const struct fluid_prog** props; 114 115 ASSERT(stardis && fluid_props); 116 fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity; 117 fluid_shader.volumic_mass = fluid_prog_get_volumic_mass; 118 fluid_shader.temperature = fluid_prog_get_temperature; 119 fluid_shader.t0 = stardis->initial_time; 120 /* temperature has to be provided by h_boundary_prog */ 121 ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*), 122 ALIGNOF(struct fluid_prog*), NULL, &data)); 123 124 props = sdis_data_get(data); /* Fetch the allocated memory space */ 125 *props = fluid_props; 126 if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) { 127 ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1)); 128 } 129 ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]); 130 ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data, 131 darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id)); 132 133 end: 134 if(data) SDIS(data_ref_put(data)); 135 return res; 136 error: 137 goto end; 138 } 139 140 res_T 141 init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst) 142 { 143 res_T res = RES_OK; 144 int str_initialized = 0; 145 ASSERT(allocator && dst && *dst == NULL); 146 *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); 147 if(! *dst) { 148 res = RES_MEM_ERR; 149 goto error; 150 } 151 str_init(allocator, &(*dst)->name); 152 str_init(allocator, &(*dst)->prog_name); 153 str_initialized = 1; 154 (*dst)->desc_id = UINT_MAX; 155 (*dst)->fluid_id = UINT_MAX; 156 end: 157 return res; 158 error: 159 if(str_initialized) { 160 str_release(&(*dst)->name); 161 str_release(&(*dst)->prog_name); 162 } 163 if(*dst) MEM_RM(allocator, *dst); 164 goto end; 165 } 166 167 void 168 release_fluid_prog 169 (struct fluid_prog* fluid, 170 struct mem_allocator* allocator) 171 { 172 size_t i; 173 ASSERT(fluid && allocator); 174 str_release(&fluid->name); 175 str_release(&fluid->prog_name); 176 if(fluid->prog_data 177 && fluid->release) /* can be NULL if external fluid */ 178 { 179 fluid->release(fluid->prog_data); 180 } 181 for(i = 0; i < fluid->argc; i++) MEM_RM(allocator, fluid->argv[i]); 182 MEM_RM(allocator, fluid->argv); 183 /* library_close call is managed at lib_data level */ 184 MEM_RM(allocator, fluid); 185 } 186 187 res_T 188 str_print_fluid_prog(struct str* str, const struct fluid_prog* f) 189 { 190 res_T res = RES_OK; 191 ASSERT(str && f); 192 ASSERT(f->argc >= 1); /* At least one argument which is the program name */ 193 194 ERR(str_append_printf(str, 195 "programmed fluid '%s': lib='%s', it is medium %u)", 196 str_cget(&f->name), str_cget(&f->prog_name), f->fluid_id)); 197 198 if(f->argc > 1) { 199 size_t i; 200 ERR(str_append_printf(str, ", provided arguments:\n")); 201 for(i = 1; i < f->argc; i++) { 202 ERR(str_append_printf(str, (i+1 == f->argc ? "\t%s" : "\t%s\n"), f->argv[i])); 203 } 204 } 205 end: 206 return res; 207 error: 208 goto end; 209 }