htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 456f57b13128820c0659bad11d2072ba3c06a907
parent cce3c8234589564facefa24a29e424c5854d1efd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  6 Sep 2018 16:25:47 +0200

Clean up the sky/grid code

Add comments and refactor the code

Diffstat:
Msrc/htrdr_grid.c | 12+++++++++---
Msrc/htrdr_grid.h | 13+++++++++----
Msrc/htrdr_sky.c | 221++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/htrdr_sky.h | 10++++++++--
4 files changed, 155 insertions(+), 101 deletions(-)

diff --git a/src/htrdr_grid.c b/src/htrdr_grid.c @@ -33,11 +33,11 @@ const int32_t GRID_VERSION_NONE = -1; struct htrdr_grid { FILE* fp; - char* data; + char* data; /* Mapped data */ size_t definition[3]; /* Submitted definition */ size_t def_adjusted; /* Adjusted definition along the 3 dimensions */ - size_t cell_sz; - size_t pagesize; + size_t cell_sz; /* Size in bytes of a grid cell */ + size_t pagesize; /* Page size in bytes */ size_t data_sz; /* Size in bytes of the overall grid data + padding */ ref_T ref; @@ -145,6 +145,8 @@ htrdr_grid_create goto error; } + /* Adjust the grid definition in order to sort its data wrt the morton code + * of its voxel */ grid->def_adjusted = MMAX(MMAX(definition[0], definition[1]), definition[2]); grid->def_adjusted = round_up_pow2(grid->def_adjusted); mcode_max = grid->def_adjusted*grid->def_adjusted*grid->def_adjusted; @@ -174,6 +176,7 @@ htrdr_grid_create /* Avoid to be positionned on the EOF */ rewind(grid->fp); + /* Map the grid data */ grid->data = mmap(NULL, grid->data_sz, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, fileno(grid->fp), grid_offset); if(grid->data == MAP_FAILED) { @@ -341,6 +344,9 @@ htrdr_grid_at_mcode(struct htrdr_grid* grid, const uint64_t mcode) { ASSERT(grid); ASSERT(mcode < grid->def_adjusted*grid->def_adjusted*grid->def_adjusted); + ASSERT(morton3D_decode_u21(mcode>>2) < grid->definition[0]); + ASSERT(morton3D_decode_u21(mcode>>1) < grid->definition[1]); + ASSERT(morton3D_decode_u21(mcode>>0) < grid->definition[2]); return grid->data + mcode*grid->cell_sz; } diff --git a/src/htrdr_grid.h b/src/htrdr_grid.h @@ -22,13 +22,16 @@ struct htrdr; struct htrdr_grid; +/******************************************************************************* + * Out of core regular grid + ******************************************************************************/ extern LOCAL_SYM res_T htrdr_grid_create (struct htrdr* htrdr, - const size_t definition[3], + const size_t definition[3], /* #voxels in X, Y and Z */ const size_t sizeof_cell, /* Size of an cell in Bytes */ - const char* filename, - const int force_overwrite, + const char* filename, /* Filename where the grid data are stored */ + const int force_overwrite, /* Force the overwrite of the grid data */ struct htrdr_grid** grid); extern LOCAL_SYM res_T @@ -45,12 +48,14 @@ extern LOCAL_SYM void htrdr_grid_ref_put (struct htrdr_grid* grid); +/* Fetch the grid data from its 3D index */ extern LOCAL_SYM void* htrdr_grid_at (struct htrdr_grid* grid, const size_t xyz[3]); -/* Follow the convention of the morton_xyz_encode_u21 function. */ +/* Retrieve the voxel data from its morton code. The morton code is computed + * from the 3D indices following the morton_xyz_encode_u21 convention. */ extern LOCAL_SYM void* htrdr_grid_at_mcode (struct htrdr_grid* grid, diff --git a/src/htrdr_sky.c b/src/htrdr_sky.c @@ -41,6 +41,7 @@ #define GAS_CONSTANT 8.3144598 /* In kg.m^2.s^-2.mol^-1.K */ #define NFLOATS_PER_COMPONENT (HTRDR_SVX_OPS_COUNT__ * HTRDR_PROPERTIES_COUNT__) +#define NFLOATS_PER_VOXEL (NFLOATS_PER_COMPONENT * HTRDR_COMPONENTS_COUNT__) struct split { size_t index; /* Index of the current htcp voxel */ @@ -110,7 +111,23 @@ struct sw_band_prop { }; /* Encompass the hierarchical data structure of the cloud data and its - * associated descriptor */ + * associated descriptor. + * + * For each SVX voxel, the data of the optical property are stored + * linearly as N single precision floating point data, with N computed as + * bellow: + * + * N = HTRDR_PROPERTIES_COUNT__ #optical properties per voxel + * * HTRDR_SVX_OPS_COUNT__ #supported operations on each properties + * * HTRDR_COMPONENTS_COUNT__; #components on which properties are defined + * + * In a given voxel, the index `id' in [0, N-1] corresponding to the optical + * property `enum htrdr_sky_property P' of the component `enum + * htrdr_sky_component C' according to the operation `enum htrdr_svx_op O' is + * then computed as bellow: + * + * id = C * NFLOATS_PER_COMPONENT + P * HTRDR_SVX_OPS_COUNT__ + O; + * NFLOATS_PER_COMPONENT = HTRDR_SVX_OPS_COUNT__ * HTRDR_PROPERTIES_COUNT__; */ struct cloud { struct svx_tree* octree; struct svx_tree_desc octree_desc; @@ -126,9 +143,10 @@ struct htrdr_sky { struct htgop* htgop; /* ... Gas optical properties */ struct htmie* htmie; /* ... Mie's data */ - struct htcp_desc htcp_desc; + struct htcp_desc htcp_desc; /* Descriptor of the loaded LES data */ - /* Map the index in Z from the regular SVX to the irregular HTCP data */ + /* LUT used to map the index of a Z from the regular SVX to the irregular + * HTCP data */ struct darray_split svx2htcp_z; double lut_cell_sz; /* Size of a svx2htcp_z cell */ @@ -144,6 +162,29 @@ struct htrdr_sky { /******************************************************************************* * Helper function ******************************************************************************/ +static FINLINE float +voxel_get + (const float* data, + const enum htrdr_sky_component comp, + const enum htrdr_sky_property prop, + const enum htrdr_svx_op op) +{ + ASSERT(data); + return data[comp*NFLOATS_PER_COMPONENT+ prop*HTRDR_SVX_OPS_COUNT__ + op]; +} + +static FINLINE void +voxel_set + (float* data, + const enum htrdr_sky_component comp, + const enum htrdr_sky_property prop, + const enum htrdr_svx_op op, + const float val) +{ + ASSERT(data); + data[comp*NFLOATS_PER_COMPONENT+ prop*HTRDR_SVX_OPS_COUNT__ + op] = val; +} + /* Compute the dry air density in the cloud */ static FINLINE double cloud_dry_air_density @@ -252,7 +293,7 @@ register_leaf static void vox_get_particle (const size_t xyz[3], - float particle[], + float vox[], const struct build_octree_context* ctx) { double rct; @@ -264,7 +305,7 @@ vox_get_particle double Ca_avg; double Cs_avg; size_t i; - ASSERT(xyz && particle && ctx); + ASSERT(xyz && vox && ctx); i = ctx->iband - ctx->sky->sw_bands_range[0]; @@ -301,10 +342,10 @@ vox_get_particle ((vox_upp[2] - ctx->sky->htcp_desc.lower[2]) / ctx->sky->lut_cell_sz); ASSERT(ilut_low <= ilut_upp); + /* Prepare the iteration over the LES voxels overlapped by the SVX voxel */ ivox_z_prev = SIZE_MAX; ka_min = ks_min = kext_min = DBL_MAX; ka_max = ks_max = kext_max =-DBL_MAX; - pos_z = vox_low[2]; ASSERT(pos_z >= (double)ilut_low * ctx->sky->lut_cell_sz); ASSERT(pos_z <= (double)ilut_upp * ctx->sky->lut_cell_sz); @@ -356,18 +397,18 @@ vox_get_particle if(kext_min != (float)kext_min) kext_min = nextafterf((float)kext_min,-FLT_MAX); if(kext_max != (float)kext_max) kext_max = nextafterf((float)kext_max, FLT_MAX); - particle[HTRDR_Ka *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)ka_min; - particle[HTRDR_Ka *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)ka_max; - particle[HTRDR_Ks *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)ks_min; - particle[HTRDR_Ks *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)ks_max; - particle[HTRDR_Kext*HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)kext_min; - particle[HTRDR_Kext*HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)kext_max; + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Ka, HTRDR_SVX_MIN, (float)ka_min); + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Ka, HTRDR_SVX_MAX, (float)ka_max); + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Ks, HTRDR_SVX_MIN, (float)ks_min); + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Ks, HTRDR_SVX_MAX, (float)ks_max); + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Kext, HTRDR_SVX_MIN, (float)kext_min); + voxel_set(vox, HTRDR_PARTICLES__, HTRDR_Kext, HTRDR_SVX_MAX, (float)kext_max); } static void vox_get_gas (const size_t xyz[3], - float gas[], + float vox[], const struct build_octree_context* ctx) { struct htgop_layer layer; @@ -377,10 +418,10 @@ vox_get_gas size_t quad_range[2]; double x_h2o_range[2]; double vox_low[3], vox_upp[3]; /* Voxel AABB */ - double ka[2] = {DBL_MAX, -DBL_MAX}; - double ks[2] = {DBL_MAX, -DBL_MAX}; - double kext[2] = {DBL_MAX, -DBL_MAX}; - ASSERT(xyz && gas && ctx); + double ka_min, ka_max; + double ks_min, ks_max; + double kext_min, kext_max; + ASSERT(xyz && vox && ctx); /* Compute the AABB of the SVX voxel */ vox_low[0] = (double)xyz[0] * ctx->vxsz[0] + ctx->sky->htcp_desc.lower[0]; @@ -419,10 +460,10 @@ vox_get_gas ((vox_upp[2] - ctx->sky->htcp_desc.lower[2]) / ctx->sky->lut_cell_sz); ASSERT(ilut_low <= ilut_upp); + /* Prepare the iteration over the LES voxels overlapped by the SVX voxel */ ivox_z_prev = SIZE_MAX; x_h2o_range[0] = DBL_MAX; x_h2o_range[1] =-DBL_MAX; - pos_z = vox_low[2]; ASSERT(pos_z >= (double)ilut_low * ctx->sky->lut_cell_sz); ASSERT(pos_z <= (double)ilut_upp * ctx->sky->lut_cell_sz); @@ -458,9 +499,13 @@ vox_get_gas } } + /* Define the atmospheric layers overlapped by the SVX voxel */ HTGOP(position_to_layer_id(ctx->sky->htgop, vox_low[2], &layer_range[0])); HTGOP(position_to_layer_id(ctx->sky->htgop, vox_upp[2], &layer_range[1])); + ka_min = ks_min = kext_min = DBL_MAX; + ka_max = ks_max = kext_max =-DBL_MAX; + /* For each atmospheric layer that overlaps the SVX voxel ... */ FOR_EACH(ilayer, layer_range[0], layer_range[1]+1) { double k[2]; @@ -475,33 +520,33 @@ vox_get_gas /* ... and compute the radiative properties and upd their bounds */ HTGOP(layer_sw_spectral_interval_quadpoints_get_ka_bounds (&band, quad_range, x_h2o_range, k)); - ka[0] = MMIN(ka[0], k[0]); - ka[1] = MMAX(ka[1], k[1]); + ka_min = MMIN(ka_min, k[0]); + ka_max = MMAX(ka_max, k[1]); HTGOP(layer_sw_spectral_interval_quadpoints_get_ks_bounds (&band, quad_range, x_h2o_range, k)); - ks[0] = MMIN(ks[0], k[0]); - ks[1] = MMAX(ks[1], k[1]); + ks_min = MMIN(ks_min, k[0]); + ks_max = MMAX(ks_max, k[1]); HTGOP(layer_sw_spectral_interval_quadpoints_get_kext_bounds (&band, quad_range, x_h2o_range, k)); - kext[0] = MMIN(kext[0], k[0]); - kext[1] = MMAX(kext[1], k[1]); + kext_min = MMIN(kext_min, k[0]); + kext_max = MMAX(kext_max, k[1]); } /* Ensure that the single precision bounds include their double precision * version. */ - if(ka[0] != (float)ka[0]) ka[0] = nextafterf((float)ka[0],-FLT_MAX); - if(ka[1] != (float)ka[1]) ka[1] = nextafterf((float)ka[1], FLT_MAX); - if(ks[0] != (float)ks[0]) ks[0] = nextafterf((float)ks[0],-FLT_MAX); - if(ks[1] != (float)ks[1]) ks[1] = nextafterf((float)ks[1], FLT_MAX); - if(kext[0] != (float)kext[0]) kext[0] = nextafterf((float)kext[0],-FLT_MAX); - if(kext[1] != (float)kext[1]) kext[1] = nextafterf((float)kext[1], FLT_MAX); - - gas[HTRDR_Ka *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)ka[0]; - gas[HTRDR_Ka *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)ka[1]; - gas[HTRDR_Ks *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)ks[0]; - gas[HTRDR_Ks *HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)ks[1]; - gas[HTRDR_Kext*HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = (float)kext[0]; - gas[HTRDR_Kext*HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = (float)kext[1]; + if(ka_min != (float)ka_min) ka_min = nextafterf((float)ka_min,-FLT_MAX); + if(ka_max != (float)ka_max) ka_max = nextafterf((float)ka_max, FLT_MAX); + if(ks_min != (float)ks_min) ks_min = nextafterf((float)ks_min,-FLT_MAX); + if(ks_max != (float)ks_max) ks_max = nextafterf((float)ks_max, FLT_MAX); + if(kext_min != (float)kext_min) kext_min = nextafterf((float)kext_min,-FLT_MAX); + if(kext_max != (float)kext_max) kext_max = nextafterf((float)kext_max, FLT_MAX); + + voxel_set(vox, HTRDR_GAS__, HTRDR_Ka, HTRDR_SVX_MIN, (float)ka_min); + voxel_set(vox, HTRDR_GAS__, HTRDR_Ka, HTRDR_SVX_MAX, (float)ka_max); + voxel_set(vox, HTRDR_GAS__, HTRDR_Ks, HTRDR_SVX_MIN, (float)ks_min); + voxel_set(vox, HTRDR_GAS__, HTRDR_Ks, HTRDR_SVX_MAX, (float)ks_max); + voxel_set(vox, HTRDR_GAS__, HTRDR_Kext, HTRDR_SVX_MIN, (float)kext_min); + voxel_set(vox, HTRDR_GAS__, HTRDR_Kext, HTRDR_SVX_MAX, (float)kext_max); } static void @@ -512,19 +557,20 @@ vox_get(const size_t xyz[3], void* dst, void* context) if(ctx->grid) { /* Fetch voxel data from precomputed grid */ const float* vox_data = htrdr_grid_at(ctx->grid, xyz); - memcpy(dst, vox_data, NFLOATS_PER_COMPONENT*2*sizeof(float)); + memcpy(dst, vox_data, NFLOATS_PER_VOXEL * sizeof(float)); } else { /* No precomputed grid. Compute the voxel data at runtime */ - float* par = (float*)dst + 0*NFLOATS_PER_COMPONENT; /* Particles properties */ - float* gas = (float*)dst + 1*NFLOATS_PER_COMPONENT; /* Gas properties */ - vox_get_particle(xyz, par, ctx); - vox_get_gas(xyz, gas, ctx); + vox_get_particle(xyz, dst, ctx); + vox_get_gas(xyz, dst, ctx); } } static INLINE void vox_merge_component - (float* comp, const float* voxels[], const size_t off, const size_t nvoxs) + (float* vox_out, + const enum htrdr_sky_component comp, + const float* voxels[], + const size_t nvoxs) { float ka_min = FLT_MAX; float ka_max =-FLT_MAX; @@ -533,48 +579,41 @@ vox_merge_component float kext_min = FLT_MAX; float kext_max =-FLT_MAX; size_t ivox; - ASSERT(comp && voxels && nvoxs); + ASSERT(vox_out && voxels && nvoxs); FOR_EACH(ivox, 0, nvoxs) { - const float* ka = voxels[ivox] + off + HTRDR_Ka * HTRDR_SVX_OPS_COUNT__; - const float* ks = voxels[ivox] + off + HTRDR_Ks * HTRDR_SVX_OPS_COUNT__; - const float* kext = voxels[ivox] + off + HTRDR_Kext * HTRDR_SVX_OPS_COUNT__; - ASSERT(ka[HTRDR_SVX_MIN] <= ka[HTRDR_SVX_MAX]); - ASSERT(ks[HTRDR_SVX_MIN] <= ks[HTRDR_SVX_MAX]); - ASSERT(kext[HTRDR_SVX_MIN] <= kext[HTRDR_SVX_MAX]); - - ka_min = MMIN(ka_min, ka[HTRDR_SVX_MIN]); - ka_max = MMAX(ka_max, ka[HTRDR_SVX_MAX]); - ks_min = MMIN(ks_min, ks[HTRDR_SVX_MIN]); - ks_max = MMAX(ks_max, ks[HTRDR_SVX_MAX]); - kext_min = MMIN(kext_min, kext[HTRDR_SVX_MIN]); - kext_max = MMAX(kext_max, kext[HTRDR_SVX_MAX]); + const float* vox = voxels[ivox]; + + ka_min = MMIN(ka_min, voxel_get(vox, comp, HTRDR_Ka, HTRDR_SVX_MIN)); + ka_max = MMAX(ka_max, voxel_get(vox, comp, HTRDR_Ka, HTRDR_SVX_MAX)); + ks_min = MMIN(ks_min, voxel_get(vox, comp, HTRDR_Ks, HTRDR_SVX_MIN)); + ks_max = MMAX(ks_max, voxel_get(vox, comp, HTRDR_Ks, HTRDR_SVX_MAX)); + kext_min = MMIN(kext_min, voxel_get(vox, comp, HTRDR_Kext, HTRDR_SVX_MIN)); + kext_max = MMAX(kext_max, voxel_get(vox, comp, HTRDR_Kext, HTRDR_SVX_MAX)); } - comp[HTRDR_Ka * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = ka_min; - comp[HTRDR_Ka * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = ka_max; - comp[HTRDR_Ks * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = ks_min; - comp[HTRDR_Ks * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = ks_max; - comp[HTRDR_Kext * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MIN] = kext_min; - comp[HTRDR_Kext * HTRDR_SVX_OPS_COUNT__ + HTRDR_SVX_MAX] = kext_max; + voxel_set(vox_out, comp, HTRDR_Ka, HTRDR_SVX_MIN, ka_min); + voxel_set(vox_out, comp, HTRDR_Ka, HTRDR_SVX_MAX, ka_max); + voxel_set(vox_out, comp, HTRDR_Ks, HTRDR_SVX_MIN, ks_min); + voxel_set(vox_out, comp, HTRDR_Ks, HTRDR_SVX_MAX, ks_max); + voxel_set(vox_out, comp, HTRDR_Kext, HTRDR_SVX_MIN, kext_min); + voxel_set(vox_out, comp, HTRDR_Kext, HTRDR_SVX_MAX, kext_max); } static void vox_merge(void* dst, const void* voxels[], const size_t nvoxs, void* context) { - float* par = (float*)dst + 0*NFLOATS_PER_COMPONENT; /* Particles properties */ - float* gas = (float*)dst + 1*NFLOATS_PER_COMPONENT; /* Gas properties */ - ASSERT(dst && voxels); - (void) context; - vox_merge_component(par, (const float**)voxels, 0*NFLOATS_PER_COMPONENT, nvoxs); - vox_merge_component(gas, (const float**)voxels, 1*NFLOATS_PER_COMPONENT, nvoxs); + ASSERT(dst && voxels && nvoxs); + (void)context; + vox_merge_component(dst, HTRDR_PARTICLES__, (const float**)voxels, nvoxs); + vox_merge_component(dst, HTRDR_GAS__, (const float**)voxels, nvoxs); } static INLINE int vox_challenge_merge_component - (const float* voxels[], + (const enum htrdr_sky_component comp, + const float* voxels[], const size_t nvoxs, - const size_t off, struct build_octree_context* ctx) { float kext_min = FLT_MAX; @@ -583,10 +622,9 @@ vox_challenge_merge_component ASSERT(voxels && nvoxs && ctx); FOR_EACH(ivox, 0, nvoxs) { - const float* kext = voxels[ivox] + off + HTRDR_Kext * HTRDR_SVX_OPS_COUNT__; - ASSERT(kext[HTRDR_SVX_MIN] <= kext[HTRDR_SVX_MAX]); - kext_min = MMIN(kext_min, kext[HTRDR_SVX_MIN]); - kext_max = MMAX(kext_max, kext[HTRDR_SVX_MAX]); + const float* vox = voxels[ivox]; + kext_min = MMIN(kext_min, voxel_get(vox, comp, HTRDR_Kext, HTRDR_SVX_MIN)); + kext_max = MMAX(kext_max, voxel_get(vox, comp, HTRDR_Kext, HTRDR_SVX_MAX)); } return (kext_max - kext_min)*ctx->dst_max <= ctx->tau_threshold; } @@ -595,10 +633,10 @@ static int vox_challenge_merge (const void* voxels[], const size_t nvoxs, void* ctx) { - const float** vox = (const float**)voxels; + const float** voxs = (const float**)voxels; ASSERT(voxels); - return vox_challenge_merge_component(vox, nvoxs, 0*NFLOATS_PER_COMPONENT, ctx) - && vox_challenge_merge_component(vox, nvoxs, 1*NFLOATS_PER_COMPONENT, ctx); + return vox_challenge_merge_component(HTRDR_PARTICLES__, voxs, nvoxs, ctx) + && vox_challenge_merge_component(HTRDR_GAS__, voxs, nvoxs, ctx); } /* Create/load a grid of cloud data used by SVX to build the octree. The grid @@ -643,7 +681,7 @@ setup_cloud_grid CHK(RES_OK == str_append(&str, buf)); if(!force_update) { - /* Try to open the saved grid */ + /* Try to open an already saved grid */ res = htrdr_grid_open(sky->htrdr, str_cget(&str), &grid); if(res != RES_OK) { htrdr_log_warn(sky->htrdr, "cannot open the grid `%s'.\n", str_cget(&str)); @@ -692,27 +730,33 @@ setup_cloud_grid ASSERT(eq_eps(ctx.vxsz[2], sky->htcp_desc.vxsz_z[0], 1.e-6) || sky->htcp_desc.irregular_z); + /* Conservatively define the maximum morton code of the htrdr_grid */ mcode_max = MMAX(MMAX(definition[0], definition[1]), definition[2]); mcode_max = round_up_pow2(mcode_max); mcode_max = mcode_max*mcode_max*mcode_max; + /* Compute the overall number of voxels in the htrdr_grid */ ncells = definition[0] * definition[1] * definition[2]; fprintf(stderr, "Generating cloud grid %lu: %3u%%", iband, 0); fflush(stderr); omp_set_num_threads((int)sky->htrdr->nthreads); - #pragma omp parallel for for(mcode=0; mcode<mcode_max; ++mcode) { size_t xyz[3]; size_t pcent; size_t n; + + /* Discard out of bound voxels */ if((xyz[0] = morton3D_decode_u21(mcode >> 2)) >= definition[0]) continue; if((xyz[1] = morton3D_decode_u21(mcode >> 1)) >= definition[1]) continue; if((xyz[2] = morton3D_decode_u21(mcode >> 0)) >= definition[2]) continue; + + /* Compute the voxel data */ vox_get(xyz, htrdr_grid_at_mcode(grid, mcode), &ctx); + /* Update the progress message */ n = (size_t)ATOMIC_INCR(&ncells_computed); pcent = n * 100 / ncells; #pragma omp critical @@ -827,8 +871,7 @@ setup_clouds vox_desc.merge = vox_merge; vox_desc.challenge_merge = vox_challenge_merge; vox_desc.context = &ctx; - vox_desc.size = sizeof(float) - * HTRDR_SVX_OPS_COUNT__ * HTRDR_PROPERTIES_COUNT__ * 2/*Gas & particles*/; + vox_desc.size = sizeof(float) * NFLOATS_PER_VOXEL; /* Create as many cloud data structure than considered SW spectral bands */ nbands = htrdr_sky_get_sw_spectral_bands_count(sky); @@ -1359,9 +1402,6 @@ htrdr_sky_fetch_svx_voxel_property const size_t iquad, /* Index of the quadrature point in the spectral band */ const struct svx_voxel* voxel) { - const float* par_data = NULL; - const float* gas_data = NULL; - int comp_mask = components_mask; double gas = 0; double par = 0; ASSERT(sky && voxel); @@ -1369,14 +1409,11 @@ htrdr_sky_fetch_svx_voxel_property ASSERT((unsigned)op < HTRDR_SVX_OPS_COUNT__); (void)sky, (void)ispectral_band, (void)iquad; - par_data = (const float*)voxel->data + 0*NFLOATS_PER_COMPONENT; - gas_data = (const float*)voxel->data + 1*NFLOATS_PER_COMPONENT; - - if(comp_mask & HTRDR_PARTICLES) { - par = par_data[prop * HTRDR_SVX_OPS_COUNT__ + op]; + if(components_mask & HTRDR_PARTICLES) { + par = voxel_get(voxel->data, HTRDR_PARTICLES__, prop, op); } - if(comp_mask & HTRDR_GAS) { - gas = gas_data[prop * HTRDR_SVX_OPS_COUNT__ + op]; + if(components_mask & HTRDR_GAS) { + gas = voxel_get(voxel->data, HTRDR_GAS__, prop, op); } /* Interval arithmetic to ensure that the returned Min/Max includes the * Min/Max of the "gas + particles mixture" */ diff --git a/src/htrdr_sky.h b/src/htrdr_sky.h @@ -26,10 +26,16 @@ enum htrdr_sky_property { HTRDR_PROPERTIES_COUNT__ }; +enum htrdr_sky_component { /* FIXME */ + HTRDR_GAS__, + HTRDR_PARTICLES__, + HTRDR_COMPONENTS_COUNT__ +}; + /* Component of the sky for which the properties are queried */ enum htrdr_sky_component_flag { - HTRDR_GAS = BIT(0), - HTRDR_PARTICLES = BIT(1), + HTRDR_GAS = BIT(HTRDR_GAS__), + HTRDR_PARTICLES = BIT(HTRDR_PARTICLES__), HTRDR_ALL_COMPONENTS = HTRDR_GAS | HTRDR_PARTICLES };