commit b86f53e5d1ca111de535029a180c217702cb53ed
parent 1d4e30628fe1424684cfc6365095bae6bb70d51c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 7 Sep 2022 14:50:31 +0200
Implement the octree storage descriptor
Diffstat:
3 files changed, 285 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -66,12 +66,14 @@ set(RNATM_FILES_SRC
rnatm_log.c
rnatm_mesh.c
rnatm_octree.c
+ rnatm_octrees_storage.c
rnatm_properties.c
rnatm_voxel_partition.c
rnatm_write_vtk.c)
set(RNATM_FILES_INC
rnatm_c.h
rnatm_log.h
+ rnatm_octrees_storage.h
rnatm_voxel.h
rnatm_voxel_partition.h)
set(RNATM_FILES_INC_API rnatm.h)
diff --git a/src/rnatm_octrees_storage.c b/src/rnatm_octrees_storage.c
@@ -0,0 +1,223 @@
+/* Copyright (C) 2022 Centre National de la Recherche Scientifique
+ * Copyright (C) 2022 Institut de Physique du Globe de Paris
+ * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université de Reims Champagne-Ardenne
+ * Copyright (C) 2022 Université de Versaille Saint-Quentin
+ * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "rnatm_c.h"
+#include "rnatm_log.h"
+#include "rnatm_octrees_storage.h"
+
+#include <star/sars.h>
+#include <star/sck.h>
+#include <star/suvm.h>
+#include <rsys/cstr.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+register_gas_signature
+ (const struct gas* gas,
+ const size_t ibands[2], /* Limits are inclusive */
+ struct sha256_ctx* ctx)
+{
+ hash256_T hash;
+ struct suvm_mesh_desc mesh;
+ size_t iband;
+ res_T res = RES_OK;
+ ASSERT(gas && ibands && ctx && ibands[0] <= ibands[1]);
+
+ /* Hash the mesh */
+ res = suvm_volume_get_mesh_desc(gas->volume, &mesh);
+ if(res != RES_OK) goto error;
+ res = suvm_mesh_desc_compute_hash(&mesh, hash);
+ if(res != RES_OK) goto error;
+ sha256_ctx_update(ctx, hash, sizeof(hash256_T));
+
+ /* Hash the radiative properties to consider */
+ FOR_EACH(iband, ibands[0], ibands[1]+1) {
+ res = sck_band_compute_hash(gas->ck, iband, hash);
+ if(res != RES_OK) goto error;
+ sha256_ctx_update(ctx, hash, sizeof(hash256_T));
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+register_aerosol_signature
+ (const struct aerosol* aerosol,
+ const size_t ibands[2], /* Limits are inclusive */
+ struct sha256_ctx* ctx)
+{
+ hash256_T hash;
+ struct suvm_mesh_desc mesh;
+ size_t iband;
+ res_T res = RES_OK;
+ ASSERT(aerosol && ibands && ctx && ibands[0] <= ibands[1]);
+
+ /* Hash the mesh */
+ res = suvm_volume_get_mesh_desc(aerosol->volume, &mesh);
+ if(res != RES_OK) goto error;
+ res = suvm_mesh_desc_compute_hash(&mesh, hash);
+ if(res != RES_OK) goto error;
+ sha256_ctx_update(ctx, hash, sizeof(hash256_T));
+
+ /* Hash the radiative properties to consider */
+ FOR_EACH(iband, ibands[0], ibands[1]+1) {
+ res = sars_band_compute_hash(aerosol->sars, iband, hash);
+ if(res != RES_OK) goto error;
+ sha256_ctx_update(ctx, hash, sizeof(hash256_T));
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+compute_octrees_signature(const struct rnatm* atm, hash256_T signature)
+{
+ struct sha256_ctx ctx;
+ size_t ibands[2];
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(atm && signature);
+
+ sha256_ctx_init(&ctx);
+
+ /* Compute the gas signature for the considered spectral range */
+ res = sck_find_bands(atm->gas.ck, atm->spectral_range, ibands);
+ if(res != RES_OK) goto error;
+ res = register_gas_signature(&atm->gas, ibands, &ctx);
+ if(res != RES_OK) goto error;
+
+ /* Compute the aerosol signatures for the considered spectral range */
+ FOR_EACH(i, 0, darray_aerosol_size_get(&atm->aerosols)) {
+ const struct aerosol* aerosol = darray_aerosol_cdata_get(&atm->aerosols)+i;
+ res = sars_find_bands(aerosol->sars, atm->spectral_range, ibands);
+ if(res != RES_OK) goto error;
+ res = register_aerosol_signature(aerosol, ibands, &ctx);
+ if(res != RES_OK) goto error;
+ }
+
+ sha256_ctx_finalize(&ctx, signature);
+
+exit:
+ return res;
+error:
+ log_err(atm, "signature calculation error -- %s\n", res_to_cstr(res));
+ goto exit;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+setup_octrees_storage_desc
+ (const struct rnatm* atm,
+ struct octrees_storage_desc* desc)
+{
+ res_T res = RES_OK;
+ ASSERT(atm && desc);
+
+ desc->version = OCTREES_STORAGE_VERSION;
+ desc->spectral_range[0] = atm->spectral_range[0];
+ desc->spectral_range[1] = atm->spectral_range[1];
+ desc->optical_thickness = atm->optical_thickness;
+ desc->grid_definition[0] = atm->grid_definition[0];
+ desc->grid_definition[1] = atm->grid_definition[1];
+ desc->grid_definition[2] = atm->grid_definition[2];
+
+ log_info(atm, "sign octree data\n");
+ res = compute_octrees_signature(atm, desc->signature);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+write_octrees_storage_desc
+ (const struct rnatm* atm,
+ const struct octrees_storage_desc* desc,
+ FILE* stream)
+{
+ res_T res = RES_OK;
+ ASSERT(atm && desc && stream);
+
+ #define WRITE(Var, N) { \
+ if(fwrite((Var), sizeof(*(Var)), (N), stream) != (N)) { \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ WRITE(&desc->version, 1);
+ WRITE(desc->spectral_range, 2);
+ WRITE(&desc->optical_thickness, 1);
+ WRITE(desc->grid_definition, 3);
+ WRITE(desc->signature, sizeof(hash256_T));
+ #undef WRITE
+
+exit:
+ return res;
+error:
+ log_err(atm, "unable to write tree storage descriptor\n");
+ goto exit;
+}
+
+res_T
+read_octrees_storage_desc
+ (const struct rnatm* atm,
+ struct octrees_storage_desc* desc,
+ FILE* stream)
+{
+ res_T res = RES_OK;
+ ASSERT(atm && desc && stream);
+
+ #define READ(Var, N) { \
+ if(fread((Var), sizeof(*(Var)), (N), stream) != (N)) { \
+ if(feof(stream)) { \
+ res = RES_BAD_ARG; \
+ } else if(ferror(stream)) { \
+ res = RES_IO_ERR; \
+ } else { \
+ res = RES_UNKNOWN_ERR; \
+ } \
+ goto error; \
+ } \
+ } (void)0
+ READ(&desc->version, 1);
+ READ(desc->spectral_range, 2);
+ READ(&desc->optical_thickness, 1);
+ READ(desc->grid_definition, 3);
+ READ(desc->signature, sizeof(hash256_T));
+ #undef READ
+
+exit:
+ return res;
+error:
+ log_err(atm, "unable to read tree storage descriptor\n");
+ goto exit;
+}
diff --git a/src/rnatm_octrees_storage.h b/src/rnatm_octrees_storage.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2022 Centre National de la Recherche Scientifique
+ * Copyright (C) 2022 Institut de Physique du Globe de Paris
+ * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université de Reims Champagne-Ardenne
+ * Copyright (C) 2022 Université de Versaille Saint-Quentin
+ * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef RNATM_OCTREES_STORAGE_H
+#define RNATM_OCTREES_STORAGE_H
+
+#include <rsys/hash.h>
+#include <rsys/rsys.h>
+
+struct rnatm;
+
+/* Storage version. It must be incremented and versioning must be performed on
+ * serialized data when its memory layout is updated */
+static const int OCTREES_STORAGE_VERSION = 0;
+
+struct octrees_storage_desc {
+ double spectral_range[2]; /* In nm. Limits are inclusive */
+ double optical_thickness; /* Threshold used during octree construction */
+ unsigned grid_definition[3];
+
+ hash256_T signature; /* Signature of the data used to build the octrees */
+
+ int version;
+};
+
+extern LOCAL_SYM res_T
+setup_octrees_storage_desc
+ (const struct rnatm* atm,
+ struct octrees_storage_desc* desc);
+
+extern LOCAL_SYM res_T
+write_octrees_storage_desc
+ (const struct rnatm* atm,
+ const struct octrees_storage_desc* desc,
+ FILE* stream);
+
+extern LOCAL_SYM res_T
+read_octrees_storage_desc
+ (const struct rnatm* atm,
+ struct octrees_storage_desc* desc,
+ FILE* stream);
+
+#endif /* RNATM_OCTREES_STORAGE_H */