stardis-fluid.c (5097B)
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.h" 17 #include "stardis-app.h" 18 19 #include <sdis.h> 20 21 #include <rsys/mem_allocator.h> 22 23 #include <limits.h> 24 25 /******************************************************************************* 26 * Local Functions 27 ******************************************************************************/ 28 29 static double 30 fluid_get_calorific_capacity 31 (const struct sdis_rwalk_vertex* vtx, 32 struct sdis_data* data) 33 { 34 const struct fluid* const* fluid_props = sdis_data_cget(data); 35 (void)vtx; 36 return (*fluid_props)->cp; 37 } 38 39 static double 40 fluid_get_volumic_mass 41 (const struct sdis_rwalk_vertex* vtx, 42 struct sdis_data* data) 43 { 44 const struct fluid* const* fluid_props = sdis_data_cget(data); 45 (void)vtx; 46 return (*fluid_props)->rho; 47 } 48 49 static double 50 fluid_get_temperature 51 (const struct sdis_rwalk_vertex* vtx, 52 struct sdis_data* data) 53 { 54 const struct fluid* const* fluid_props = sdis_data_cget(data); 55 if(SDIS_TEMPERATURE_IS_KNOWN((*fluid_props)->imposed_temperature)) 56 /* If there is an imposed temp, it is imposed regardless of time */ 57 return (*fluid_props)->imposed_temperature; 58 if(vtx->time <= (*fluid_props)->t0) { 59 /* If time is <= t0: use tinit */ 60 if(SDIS_TEMPERATURE_IS_UNKNOWN((*fluid_props)->tinit)) { 61 if(str_is_empty(&(*fluid_props)->name)) { 62 FATAL("fluid_get_temperature: getting undefined Tinit\n"); 63 } else { 64 VFATAL("fluid_get_temperature: getting undefined Tinit (fluid '%s')\n", 65 ARG1(str_cget(&(*fluid_props)->name))); 66 } 67 } 68 return (*fluid_props)->tinit; 69 } 70 return SDIS_TEMPERATURE_NONE; /* Unknown temperature */ 71 } 72 73 /******************************************************************************* 74 * Public Functions 75 ******************************************************************************/ 76 77 res_T 78 create_solver_fluid 79 (struct stardis* stardis, 80 const struct fluid* fluid_props) 81 { 82 res_T res = RES_OK; 83 struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL; 84 struct sdis_data* data = NULL; 85 const struct fluid** props; 86 87 ASSERT(stardis && fluid_props); 88 fluid_shader.calorific_capacity = fluid_get_calorific_capacity; 89 fluid_shader.volumic_mass = fluid_get_volumic_mass; 90 fluid_shader.temperature = fluid_get_temperature; 91 fluid_shader.t0 = stardis->initial_time; 92 ERR(sdis_data_create(stardis->dev, sizeof(struct fluid*), ALIGNOF(struct fluid*), 93 NULL, &data)); 94 95 props = sdis_data_get(data); /* Fetch the allocated memory space */ 96 *props = fluid_props; 97 if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) { 98 ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1)); 99 } 100 ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]); 101 ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data, 102 darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id)); 103 104 end: 105 if(data) SDIS(data_ref_put(data)); 106 return res; 107 error: 108 goto end; 109 } 110 111 res_T 112 init_fluid(struct mem_allocator* allocator, struct fluid** dst) 113 { 114 res_T res = RES_OK; 115 int str_initialized = 0; 116 ASSERT(allocator && dst && *dst == NULL); 117 *dst = MEM_ALLOC(allocator, sizeof(struct fluid)); 118 if(! *dst) { 119 res = RES_MEM_ERR; 120 goto error; 121 } 122 str_init(allocator, &(*dst)->name); 123 str_initialized = 1; 124 (*dst)->rho = 1; 125 (*dst)->cp = 1; 126 (*dst)->tinit = SDIS_TEMPERATURE_NONE; 127 (*dst)->imposed_temperature = SDIS_TEMPERATURE_NONE; 128 (*dst)->t0 = 0; 129 (*dst)->is_outside = 0; 130 (*dst)->is_green = 0; 131 (*dst)->desc_id = UINT_MAX; 132 (*dst)->fluid_id = UINT_MAX; 133 end: 134 return res; 135 error: 136 if(str_initialized) str_release(&(*dst)->name); 137 if(*dst) MEM_RM(allocator, *dst); 138 goto end; 139 } 140 141 void 142 release_fluid 143 (struct fluid* fluid, 144 struct mem_allocator* allocator) 145 { 146 ASSERT(fluid && allocator); 147 str_release(&fluid->name); 148 MEM_RM(allocator, fluid); 149 } 150 151 res_T 152 str_print_fluid(struct str* str, const struct fluid* f) 153 { 154 res_T res = RES_OK; 155 ASSERT(str && f); 156 ERR(str_append_printf(str, "Fluid '%s': rho=%g cp=%g", 157 str_cget(&f->name), f->rho, f->cp)); 158 if(SDIS_TEMPERATURE_IS_KNOWN(f->tinit)) { 159 ERR(str_append_printf(str, " Tinit=%g", f->tinit)); 160 } 161 if(SDIS_TEMPERATURE_IS_KNOWN(f->imposed_temperature)) { 162 ERR(str_append_printf(str, " Temp=%g", f->imposed_temperature)); 163 } 164 ERR(str_append_printf(str, " (it is medium %u)", f->fluid_id)); 165 end: 166 return res; 167 error: 168 goto end; 169 }