stardis-extern-source.c (7128B)
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-extern-source.h" 18 19 #include <sdis.h> 20 #include <rsys/cstr.h> 21 #include <rsys/logger.h> 22 23 /******************************************************************************* 24 * Helper functions 25 ******************************************************************************/ 26 static void 27 sphere_get_position(const double time, double pos[3], struct sdis_data* data) 28 { 29 const struct spherical_source* src = NULL; 30 ASSERT(pos); 31 (void)time; 32 33 src = *((const struct spherical_source* const*)sdis_data_cget(data)); 34 pos[0] = src->position[0]; 35 pos[1] = src->position[1]; 36 pos[2] = src->position[2]; 37 } 38 39 static double 40 sphere_get_power(const double time, struct sdis_data* data) 41 { 42 const struct spherical_source* src = NULL; 43 (void)time; 44 45 src = *((const struct spherical_source* const*)sdis_data_cget(data)); 46 return src->power; /* [W] */ 47 } 48 49 static double 50 sphere_get_diffuse_radiance 51 (const double time, 52 const double dir[3], 53 struct sdis_data* data) 54 { 55 const struct spherical_source* src = NULL; 56 (void)time, (void)dir; 57 58 src = *((const struct spherical_source* const*)sdis_data_cget(data)); 59 return src->diffuse_radiance; /* [W/m^2/sr] */ 60 } 61 62 static res_T 63 create_solver_source_sphere 64 (struct extern_source* src, 65 struct stardis* stardis) 66 { 67 struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL; 68 struct sdis_data* data = NULL; 69 res_T res = RES_OK; 70 ASSERT(src && src->type == EXTERN_SOURCE_SPHERE && stardis); 71 72 /* Register with the solver source a pointer to the external source */ 73 res = sdis_data_create(stardis->dev, sizeof(struct spherical_source*), 74 ALIGNOF(struct spherical_source*), NULL, &data); 75 if(res != RES_OK) goto error; 76 *((struct spherical_source**)sdis_data_get(data)) = &src->data.sphere; 77 78 /* Create the spherical source */ 79 shader.position = sphere_get_position; 80 shader.power = sphere_get_power; 81 shader.diffuse_radiance = sphere_get_diffuse_radiance; 82 shader.radius = src->data.sphere.radius; 83 res = sdis_spherical_source_create(stardis->dev, &shader, data, &src->sdis_src); 84 if(res != RES_OK) goto error; 85 86 exit: 87 /* Release the local reference on the data: it is kept by the sdis source */ 88 if(data) SDIS(data_ref_put(data)); 89 return res; 90 error: 91 logger_print(stardis->logger, LOG_ERROR, 92 "Error when creating the external spherical source for the solver -- %s\n", 93 res_to_cstr(res)); 94 goto exit; 95 } 96 97 static void 98 sphere_prog_get_position(const double time, double pos[3], struct sdis_data* data) 99 { 100 const struct spherical_source_prog* src = NULL; 101 ASSERT(pos); 102 103 src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); 104 src->position(time, pos, src->data);; 105 } 106 107 static double 108 sphere_prog_get_power(const double time, struct sdis_data* data) 109 { 110 const struct spherical_source_prog* src = NULL; 111 112 src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); 113 return src->power(time, src->data); 114 } 115 116 static double 117 sphere_prog_get_diffuse_radiance 118 (const double time, 119 const double dir[3], 120 struct sdis_data* data) 121 { 122 const struct spherical_source_prog* src = NULL; 123 124 src = *((const struct spherical_source_prog* const*)sdis_data_cget(data)); 125 return src->diffuse_radiance(time, dir, src->data); 126 } 127 128 static res_T 129 create_solver_source_sphere_prog 130 (struct extern_source* src, 131 struct stardis* stardis) 132 { 133 struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL; 134 struct sdis_data* data = NULL; 135 res_T res = RES_OK; 136 ASSERT(src && src->type == EXTERN_SOURCE_SPHERE_PROG && stardis); 137 138 /* Register a pointer to the external source with the solver source */ 139 res = sdis_data_create(stardis->dev, sizeof(struct spherical_source_prog*), 140 ALIGNOF(struct spherical_source_prog*), NULL, &data); 141 if(res != RES_OK) goto error; 142 *((struct spherical_source_prog**)sdis_data_get(data)) = &src->data.sphere_prog; 143 144 /* Create the spherical source */ 145 shader.position = sphere_prog_get_position; 146 shader.power = sphere_prog_get_power; 147 shader.diffuse_radiance = sphere_prog_get_diffuse_radiance; 148 shader.radius = src->data.sphere_prog.radius; 149 res = sdis_spherical_source_create(stardis->dev, &shader, data, &src->sdis_src); 150 if(res != RES_OK) goto error; 151 152 exit: 153 /* Release the local reference on the data: it is kept by the sdis source */ 154 if(data) SDIS(data_ref_put(data)); 155 return res; 156 error: 157 logger_print(stardis->logger, LOG_ERROR, 158 "Error when creating the external spherical source for the solver -- %s\n", 159 res_to_cstr(res)); 160 goto exit; 161 } 162 163 /******************************************************************************* 164 * Local functions 165 ******************************************************************************/ 166 res_T 167 extern_source_init_sphere 168 (struct mem_allocator* allocator, 169 struct extern_source* src) 170 { 171 ASSERT(src); 172 (void)allocator; 173 src->type = EXTERN_SOURCE_SPHERE; 174 src->data.sphere = SPHERICAL_SOURCE_NULL; 175 return RES_OK; 176 } 177 178 res_T 179 extern_source_init_sphere_prog 180 (struct mem_allocator* allocator, 181 struct extern_source* src) 182 { 183 ASSERT(src); 184 src->type = EXTERN_SOURCE_SPHERE_PROG; 185 src->data.sphere_prog = SPHERICAL_SOURCE_PROG_NULL; 186 src->data.sphere_prog.allocator = allocator; 187 str_init(allocator, &src->data.sphere_prog.prog_name); 188 return RES_OK; 189 } 190 191 void 192 extern_source_release(struct extern_source* src) 193 { 194 ASSERT(src); 195 if(src->type == EXTERN_SOURCE_SPHERE_PROG) { 196 struct spherical_source_prog* src_prog = &src->data.sphere_prog; 197 size_t i; 198 199 if(src_prog->data) { 200 ASSERT(src_prog->release); 201 src_prog->release(src_prog->data); 202 } 203 204 str_release(&src_prog->prog_name); 205 FOR_EACH(i, 0, src_prog->argc) { 206 MEM_RM(src_prog->allocator, src_prog->argv[i]); 207 } 208 209 MEM_RM(src_prog->allocator, src_prog->argv); 210 } 211 212 if(src->sdis_src) SDIS(source_ref_put(src->sdis_src)); 213 } 214 215 res_T 216 extern_source_create_solver_source 217 (struct extern_source* src, 218 struct stardis* stardis) 219 { 220 res_T res = RES_OK; 221 ASSERT(src); 222 223 switch(src->type) { 224 case EXTERN_SOURCE_SPHERE: 225 res = create_solver_source_sphere(src, stardis); 226 if(res != RES_OK) goto error; 227 break; 228 case EXTERN_SOURCE_SPHERE_PROG: 229 res = create_solver_source_sphere_prog(src, stardis); 230 if(res != RES_OK) goto error; 231 break; 232 default: FATAL("Unreachable code\n"); break; 233 } 234 235 exit: 236 return res; 237 error: 238 goto exit; 239 }