atrstm_svx.c (6131B)
1 /* Copyright (C) 2022, 2023 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2020, 2021 Centre National de la Recherche Scientifique 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #include "atrstm.h" 18 #include "atrstm_c.h" 19 #include "atrstm_log.h" 20 #include "atrstm_svx.h" 21 22 #include <star/svx.h> 23 24 #include <rsys/cstr.h> 25 26 /******************************************************************************* 27 * Helper functions 28 ******************************************************************************/ 29 static INLINE int 30 check_fetch_radcoefs_svx_args 31 (const struct atrstm* atrstm, 32 const struct atrstm_fetch_radcoefs_svx_args* args, 33 const char* func_name) 34 { 35 ASSERT(atrstm && func_name); 36 37 if(!args 38 || !(args->radcoefs_mask & ATRSTM_RADCOEFS_MASK_ALL) 39 || !(args->components_mask & ATRSTM_CPNTS_MASK_ALL) 40 || !(args->operations_mask & ATRSTM_SVX_OPS_MASK_ALL)) 41 return 0; 42 43 if(atrstm->spectral_type != ATRSTM_SPECTRAL_SW) { 44 log_err(atrstm, "%s: only shortwave is currently supported.\n", 45 func_name); 46 return 0; 47 } 48 49 return 1; 50 } 51 52 static INLINE int 53 check_fetch_radcoefs_svx_voxel_args 54 (const struct atrstm* atrstm, 55 const struct atrstm_fetch_radcoefs_svx_voxel_args* args, 56 const char* func_name) 57 { 58 ASSERT(atrstm && func_name); 59 60 if(!args 61 || SVX_VOXEL_NONE(&args->voxel) 62 || !(args->radcoefs_mask & ATRSTM_RADCOEFS_MASK_ALL) 63 || !(args->components_mask & ATRSTM_CPNTS_MASK_ALL) 64 || !(args->operations_mask & ATRSTM_SVX_OPS_MASK_ALL)) 65 return 0; 66 67 if(atrstm->spectral_type != ATRSTM_SPECTRAL_SW) { 68 log_err(atrstm, "%s: only shortwave is currently supported.\n", 69 func_name); 70 return 0; 71 } 72 73 return 1; 74 } 75 76 static INLINE int 77 check_trace_ray_args 78 (const struct atrstm* atrstm, 79 const struct atrstm_trace_ray_args* args, 80 const char* func_name) 81 { 82 ASSERT(atrstm && func_name); 83 84 if(!args) return 0; 85 86 if(atrstm->spectral_type != ATRSTM_SPECTRAL_SW) { 87 log_err(atrstm, "%s: only shortwave is currently supported.\n", 88 func_name); 89 return 0; 90 } 91 92 return 1; 93 } 94 95 static INLINE void 96 reset_radcoefs 97 (double radcoefs[ATRSTM_RADCOEFS_COUNT__][ATRSTM_SVX_OPS_COUNT__]) 98 { 99 ASSERT(radcoefs); 100 memset(radcoefs, 0, 101 sizeof(double[ATRSTM_RADCOEFS_COUNT__][ATRSTM_SVX_OPS_COUNT__])); 102 } 103 104 /******************************************************************************* 105 * Exported functions 106 ******************************************************************************/ 107 res_T 108 atrstm_fetch_radcoefs_svx 109 (const struct atrstm* atrstm, 110 const struct atrstm_fetch_radcoefs_svx_args* args, 111 atrstm_radcoefs_svx_T radcoefs) /* In m^-1 */ 112 { 113 114 struct atrstm_fetch_radcoefs_svx_voxel_args voxel_args; 115 struct svx_voxel voxel = SVX_VOXEL_NULL; 116 res_T res = RES_OK; 117 118 if(!atrstm 119 || !check_fetch_radcoefs_svx_args(atrstm, args, FUNC_NAME) 120 || !radcoefs) { 121 res = RES_BAD_ARG; 122 goto error; 123 } 124 125 /* Retrieve the voxel into which the queried position lies */ 126 SVX(tree_at(atrstm->octree, args->pos, NULL, NULL, &voxel)); 127 if(SVX_VOXEL_NONE(&voxel)) { 128 log_warn(atrstm, 129 "%s: the position {%g, %g, %g} does not belong to the Star-VoXel structure.\n" 130 "medium.\n", FUNC_NAME, SPLIT3(args->pos)); 131 reset_radcoefs(radcoefs); 132 goto exit; 133 } 134 135 /* Retrieve the radiative coefficients of the voxel */ 136 voxel_args = ATRSTM_FETCH_RADCOEFS_SVX_VOXEL_ARGS_DEFAULT; 137 voxel_args.voxel = voxel; 138 voxel_args.iband = args->iband; 139 voxel_args.iquad = args->iquad; 140 voxel_args.radcoefs_mask = args->radcoefs_mask; 141 voxel_args.components_mask = args->components_mask; 142 voxel_args.operations_mask = args->operations_mask; 143 res = atrstm_fetch_radcoefs_svx_voxel(atrstm, &voxel_args, radcoefs); 144 if(res != RES_OK) goto error; 145 146 exit: 147 return res; 148 error: 149 goto exit; 150 } 151 152 res_T 153 atrstm_fetch_radcoefs_svx_voxel 154 (const struct atrstm* atrstm, 155 const struct atrstm_fetch_radcoefs_svx_voxel_args* args, 156 atrstm_radcoefs_svx_T radcoefs) /* In m^-1 */ 157 { 158 int cpnt, radcoef, op; 159 res_T res = RES_OK; 160 161 if(!atrstm 162 || !check_fetch_radcoefs_svx_voxel_args(atrstm, args, FUNC_NAME) 163 || !radcoefs) { 164 res = RES_BAD_ARG; 165 goto error; 166 } 167 168 reset_radcoefs(radcoefs); 169 170 FOR_EACH(cpnt, 0, ATRSTM_CPNTS_COUNT__) { 171 if((args->components_mask & BIT(cpnt)) == 0) continue; 172 173 FOR_EACH(radcoef, 0, ATRSTM_RADCOEFS_COUNT__) { 174 if((args->radcoefs_mask & BIT(radcoef)) == 0) continue; 175 176 FOR_EACH(op, 0, ATRSTM_SVX_OPS_COUNT__) { 177 double k; 178 if((args->operations_mask & BIT(op)) == 0) continue; 179 180 /* Add component contribution to the current radiative coef */ 181 k = vox_get(args->voxel.data, cpnt, radcoef, op); 182 radcoefs[radcoef][op] += k; 183 } 184 } 185 } 186 187 exit: 188 return res; 189 error: 190 goto exit; 191 } 192 193 res_T 194 atrstm_trace_ray 195 (const struct atrstm* atrstm, 196 const struct atrstm_trace_ray_args* args, 197 struct svx_hit* hit) 198 { 199 res_T res = RES_OK; 200 if(!atrstm || !check_trace_ray_args(atrstm, args, FUNC_NAME) || !hit) { 201 res = RES_BAD_ARG; 202 goto error; 203 } 204 205 /* Reset the hit */ 206 *hit = SVX_HIT_NULL; 207 208 res = svx_tree_trace_ray(atrstm->octree, args->ray_org, args->ray_dir, 209 args->ray_range, args->challenge, args->filter, args->context, hit); 210 if(res != RES_OK) { 211 log_err(atrstm, 212 "%s: error tracing the ray: origin = {%g, %g, %g}; " 213 "direction = {%g, %g, %g}; range = {%g, %g} -- %s.\n", 214 FUNC_NAME, SPLIT3(args->ray_org), SPLIT3(args->ray_dir), 215 SPLIT2(args->ray_range), res_to_cstr(res)); 216 goto error; 217 } 218 219 exit: 220 return res; 221 error: 222 goto exit; 223 }