stardis-radiative-env.c (6362B)
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-app.h" 17 #include "stardis-radiative-env.h" 18 19 #include <sdis.h> 20 #include <rsys/cstr.h> 21 #include <rsys/logger.h> 22 23 /******************************************************************************* 24 * Helper functions 25 ******************************************************************************/ 26 static double 27 radenv_get_temperature 28 (const struct sdis_radiative_ray* ray, 29 struct sdis_data* data) 30 { 31 const struct radiative_env_const* props = sdis_data_cget(data); 32 (void)ray; 33 return props->temperature; 34 } 35 36 static double 37 radenv_get_reference_temperature 38 (const struct sdis_radiative_ray* ray, 39 struct sdis_data* data) 40 { 41 const struct radiative_env_const* props = sdis_data_cget(data); 42 (void)ray; 43 return props->reference_temperature; 44 } 45 46 static res_T 47 create_radenv_const 48 (struct radiative_env* radenv, 49 struct stardis* stardis) 50 { 51 struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; 52 struct sdis_data* data = NULL; 53 struct radiative_env_const* props = NULL; 54 res_T res = RES_OK; 55 ASSERT(radenv && radenv->type == RADIATIVE_ENV_CONST && stardis); 56 57 res = sdis_data_create(stardis->dev, sizeof(struct radiative_env_const), 58 ALIGNOF(struct radiative_env_const), NULL, &data); 59 if(res != RES_OK) goto error; 60 props = sdis_data_get(data); 61 *props = radenv->data.cst; 62 63 shader.temperature = radenv_get_temperature; 64 shader.reference_temperature = radenv_get_reference_temperature; 65 res = sdis_radiative_env_create 66 (stardis->dev, &shader, data, &radenv->sdis_radenv); 67 if(res != RES_OK) goto error; 68 69 exit: 70 /* Release the local reference on the data: it is kept by the sdis radenv */ 71 if(data) SDIS(data_ref_put(data)); 72 return res; 73 error: 74 logger_print(stardis->logger, LOG_ERROR, 75 "Error when creating the radiative environment for the solver -- %s\n", 76 res_to_cstr(res)); 77 goto exit; 78 } 79 80 static double 81 radenv_prog_get_temperature 82 (const struct sdis_radiative_ray* ray, 83 struct sdis_data* data) 84 { 85 const struct radiative_env_prog* radenv = NULL; 86 87 radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); 88 return radenv->temperature(ray->time, ray->dir, radenv->data); 89 } 90 91 static double 92 radenv_prog_get_reference_temperature 93 (const struct sdis_radiative_ray* ray, 94 struct sdis_data* data) 95 { 96 const struct radiative_env_prog* radenv = NULL; 97 98 radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); 99 return radenv->reference_temperature(ray->time, ray->dir, radenv->data); 100 } 101 102 static res_T 103 create_radenv_prog 104 (struct radiative_env* radenv, 105 struct stardis* stardis) 106 { 107 struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; 108 struct sdis_data* data = NULL; 109 res_T res = RES_OK; 110 ASSERT(radenv && radenv->type == RADIATIVE_ENV_PROG && stardis); 111 112 /* Register a pointer to the radiative environment with the solver radiative 113 * environment */ 114 res = sdis_data_create(stardis->dev, sizeof(struct radiative_env_prog*), 115 ALIGNOF(struct radiative_env_prog*), NULL, &data); 116 if(res != RES_OK) goto error; 117 *((struct radiative_env_prog**)sdis_data_get(data)) = &radenv->data.prg; 118 119 /* Create the radiative environment */ 120 shader.temperature = radenv_prog_get_temperature; 121 shader.reference_temperature = radenv_prog_get_reference_temperature; 122 res = sdis_radiative_env_create 123 (stardis->dev, &shader, data, &radenv->sdis_radenv); 124 if(res != RES_OK) goto error; 125 126 exit: 127 /* Release the local reference on the data: it is kept by the sdis radenv */ 128 if(data) SDIS(data_ref_put(data)); 129 return res; 130 error: 131 logger_print(stardis->logger, LOG_ERROR, 132 "Error when creating the radiative environment for the solver -- %s\n", 133 res_to_cstr(res)); 134 goto exit; 135 } 136 137 /******************************************************************************* 138 * Local function 139 ******************************************************************************/ 140 res_T 141 radiative_env_init_const 142 (struct mem_allocator* allocator, 143 struct radiative_env* radenv) 144 { 145 ASSERT(radenv); 146 (void)allocator; 147 radenv->type = RADIATIVE_ENV_CONST; 148 radenv->data.cst = RADIATIVE_ENV_CONST_DEFAULT; 149 return RES_OK; 150 } 151 152 res_T 153 radiative_env_init_prog 154 (struct mem_allocator* allocator, 155 struct radiative_env* radenv) 156 { 157 ASSERT(radenv); 158 radenv->type = RADIATIVE_ENV_PROG; 159 radenv->data.prg = RADIATIVE_ENV_PROG_NULL; 160 radenv->data.prg.allocator = allocator; 161 str_init(allocator, &radenv->data.prg.prog_name); 162 return RES_OK; 163 } 164 165 void 166 radiative_env_release(struct radiative_env* radenv) 167 { 168 ASSERT(radenv); 169 170 if(radenv->type == RADIATIVE_ENV_PROG) { 171 struct radiative_env_prog* radenv_prog = &radenv->data.prg; 172 size_t i = 0; 173 174 if(radenv_prog->data) { 175 ASSERT(radenv_prog->release); 176 radenv_prog->release(radenv_prog->data); 177 } 178 179 str_release(&radenv_prog->prog_name); 180 FOR_EACH(i, 0, radenv_prog->argc) { 181 MEM_RM(radenv_prog->allocator, radenv_prog->argv[i]); 182 } 183 MEM_RM(radenv_prog->allocator, radenv_prog->argv); 184 } 185 186 if(radenv->sdis_radenv) SDIS(radiative_env_ref_put(radenv->sdis_radenv)); 187 radenv->sdis_radenv = NULL; 188 } 189 190 res_T 191 radiative_env_create_solver_radiative_env 192 (struct radiative_env* radenv, 193 struct stardis* stardis) 194 { 195 res_T res = RES_OK; 196 ASSERT(radenv && stardis); 197 198 switch(radenv->type) { 199 case RADIATIVE_ENV_CONST: 200 res = create_radenv_const(radenv, stardis); 201 if(res != RES_OK) goto error; 202 break; 203 case RADIATIVE_ENV_PROG: 204 res = create_radenv_prog(radenv, stardis); 205 if(res != RES_OK) goto error; 206 break; 207 default: FATAL("Unreachable code\n"); break; 208 } 209 210 exit: 211 return res; 212 error: 213 goto exit; 214 }