commit f2625a85c5a32ea1d00b6d7a9fa933aa4bf3a3dd
parent 7e9a2c944cd75337a6e2536581d746216ca81369
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Mon, 24 Feb 2025 19:27:42 +0100
Implement the sphin_source structure and its associated parsing
Diffstat:
3 files changed, 328 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -34,7 +34,13 @@ default: build_library
################################################################################
# Library building
################################################################################
-SRC = src/sphin.c src/sphin_config.c src/sphin_volume.c src/sphin_surface.c src/sphin_geometry.c
+SRC = \
+ src/sphin.c \
+ src/sphin_config.c \
+ src/sphin_volume.c \
+ src/sphin_surface.c \
+ src/sphin_geometry.c \
+ src/sphin_source.c
OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)
diff --git a/src/sphin_source.c b/src/sphin_source.c
@@ -0,0 +1,281 @@
+/* Copyright (C) 2024 Centre National de la Recherche Scientifique
+ * Copyright (C) 2024 Clermont Auvergne INP
+ * Copyright (C) 2024 INSA Lyon
+ * Copyright (C) 2024 Institut Mines Télécom Albi-Carmaux
+ * Copyright (C) 2024 Institut National Polytechnique de Toulouse
+ * Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2024 PhotonLyX (info@photonlyx.com)
+ * Copyright (C) 2024 Université de Lorraine
+ * Copyright (C) 2024 Université Paul Sabatier
+ * Copyright (C) 2024 Université Toulouse - Jean Jaurès
+ *
+ * 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/>. */
+#define _POSIX_C_SOURCE 200112L /* for strtok_r support */
+
+#include "sphin.h"
+#include "sphin_c.h"
+#include "sphin_config.h"
+#include "sphin_source.h"
+
+#include <rsys/cstr.h>
+#include <rsys/double3.h>
+#include <rsys/ref_count.h>
+#include <rsys/str.h>
+#include <rsys/text_reader.h>
+
+struct sphin_source {
+ struct str name;
+ struct sphin* sphin;
+ struct sphin_source_direction_distribution direction_distribution;
+ struct sphin_flux_density flux_density;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+source_create
+ (struct sphin* sphin,
+ const char* name,
+ struct sphin_source** out_source)
+{
+ struct sphin_source* source = NULL;
+ res_T res = RES_OK;
+
+ ASSERT(NULL != sphin);
+ ASSERT(NULL != out_source);
+ ASSERT(NULL != name);
+ ASSERT('\0' != name[0]); /* Name can't be empty */
+
+ source = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_source));
+ if (NULL == source) { res = RES_MEM_ERR; goto error; }
+ ref_init(&source->ref);
+ SPHIN(ref_get(sphin));
+ source->sphin = sphin;
+ source->direction_distribution = SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL;
+ source->flux_density = SPHIN_FLUX_DENSITY_NULL;
+
+ str_init(sphin->allocator, &source->name);
+ res = str_set(&source->name, name);
+ if (RES_OK != res) { goto error; }
+
+exit:
+ *out_source = source;
+ return res;
+error:
+ if (NULL != source) {
+ SPHIN(source_ref_put(source));
+ source = NULL;
+ }
+ goto exit;
+}
+
+static void
+release_source(ref_T* address)
+{
+ struct sphin_source* source = NULL;
+ struct sphin* sphin = NULL;
+
+ ASSERT(NULL != address);
+
+ source = CONTAINER_OF(address, struct sphin_source, ref);
+ str_release(&source->name);
+ sphin = source->sphin;
+ MEM_RM(sphin->allocator, source);
+ SPHIN(ref_put(sphin));
+}
+
+static res_T
+parse_direction_distribution
+ (struct sphin_source* source,
+ struct txtrdr* txtrdr,
+ char* value)
+{
+ char* direction_distribution_type;
+ char* str_collimation_degree;
+ char* str_direction;
+ char* token_ptr;
+ double collimation_degree;
+ double direction[3] = {0, 0, 0};
+ res_T res = RES_OK;
+
+ ASSERT(NULL != source);
+ (void) txtrdr; /* Disable unused variable warning */
+
+ /* Parse direction distribution type */
+ direction_distribution_type = strtok_r(value, " \t", &token_ptr);
+ if (NULL == direction_distribution_type){ res = RES_BAD_ARG; goto error; }
+
+ /* Lambertian source */
+ if (0 == strcmp(direction_distribution_type, "LAMBERT")){
+ source->direction_distribution.type = SPHIN_SOURCE_DIRECTION_ISOTROPIC;
+ }
+
+ /* Collimated source */
+ else if (0 == strcmp(direction_distribution_type, "COLLIM")){
+ source->direction_distribution.type = SPHIN_SOURCE_DIRECTION_COLLIM;
+ str_direction = strtok_r(NULL, " \t", &token_ptr);
+ if(0 == strcmp(str_direction, "NORMAL")){
+ direction[0] = direction[1] = direction[2] = 0;
+ }
+ else{
+ /* TODO implement parsing of a vector, taking into account the formatting
+ * in the input file to be decided */
+ }
+ d3_set(source->direction_distribution.collim.direction, direction);
+ }
+
+ /* Cos^n model of direction distribution */
+ else if (0 == strcmp(direction_distribution_type, "COS_POW_N")){
+ source->direction_distribution.type = SPHIN_SOURCE_DIRECTION_COS_POW_N;
+ str_collimation_degree = strtok_r(NULL, " \t", &token_ptr);
+ res = cstr_to_double(str_collimation_degree, &collimation_degree);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+ if (collimation_degree < 0) { res = RES_BAD_ARG; goto error; }
+ }
+ else { res = RES_BAD_ARG; goto error; }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_flux_density
+ (struct sphin_source* source,
+ struct txtrdr* txtrdr,
+ char* value)
+{
+ char* flux_density_type;
+ char* str_flux_density;
+ char* token_ptr;
+ double flux_density;
+ res_T res = RES_OK;
+
+ ASSERT(NULL != source);
+ (void) txtrdr; /* Disable unused variable warning */
+
+ /* Parse unit */
+ flux_density_type = strtok_r(value, " \t", &token_ptr);
+ if (NULL == flux_density_type){ res = RES_BAD_ARG; goto error; }
+ if (0 == strcmp(flux_density_type, "MOL")){ source->flux_density.unit= SPHIN_FLUX_DENSITY_MOL; }
+ else if (0 == strcmp(flux_density_type, "POW")){ source->flux_density.unit = SPHIN_FLUX_DENSITY_POW; }
+ else { res = RES_BAD_ARG; goto error; }
+
+ /* Parse flux density value */
+ str_flux_density = strtok_r(value, " \t", &token_ptr);
+ res = cstr_to_double(str_flux_density, &flux_density);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+ if (flux_density< 0) { res = RES_BAD_ARG; goto error; }
+
+ source->flux_density.flux_density = flux_density;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+parse_source
+ (struct sphin* sphin,
+ struct txtrdr* txtrdr,
+ const char* name,
+ struct sphin_source** out_source)
+{
+ struct sphin_source* source = NULL;
+ struct str line;
+ char* keyword = NULL;
+ char* token = NULL;
+ char* token_ptr = NULL;
+ char* value = NULL;
+ res_T res = RES_OK;
+
+ ASSERT(NULL != sphin);
+ ASSERT(NULL != out_source);
+ ASSERT(NULL != txtrdr);
+ ASSERT(NULL != name);
+ ASSERT('\0' != name[0]); /* Name can't be empty */
+
+ str_init(sphin->allocator, &line);
+
+ res = source_create(sphin, name, &source);
+ if (RES_OK != res) { goto error; }
+
+ res = txtrdr_read_line(txtrdr);
+ if (RES_OK != res) { goto error; }
+
+ while (NULL != txtrdr_get_line(txtrdr)) {
+ res = str_set(&line, txtrdr_get_cline(txtrdr));
+ if (RES_OK != res) { goto error; }
+
+ /* parse keyword */
+ token = strtok_r(str_get(&line), ":", &token_ptr);
+ if (NULL == token){ res = RES_BAD_ARG; goto error; }
+ keyword = trim_keyword(token);
+ if (NULL == keyword){ res = RES_BAD_ARG; goto error; }
+
+ /* parse value */
+ token = strtok_r(NULL, "", &token_ptr);
+ if (NULL == token){ res = RES_BAD_ARG; goto error; }
+ value = token;
+ if (0 == strcmp(keyword, "flux_density")){
+ parse_flux_density(source, txtrdr, value);
+ }
+ else if (0 == strcmp(keyword, "direction")){
+ parse_direction_distribution(source, txtrdr, value);
+ }
+ else {
+ break;
+ }
+ }
+
+exit:
+ str_release(&line);
+ *out_source = source;
+ return res;
+error:
+ if (NULL != source) {
+ SPHIN(source_ref_put(source));
+ source = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sphin_source_ref_get(struct sphin_source* source)
+{
+ if(NULL == source) {
+ return RES_BAD_ARG;
+ }
+ ref_get(&source->ref);
+ return RES_OK;
+}
+
+res_T
+sphin_source_ref_put(struct sphin_source* source)
+{
+ if(NULL == source) {
+ return RES_BAD_ARG;
+ }
+ ref_put(&source->ref, release_source);
+ return RES_OK;
+}
diff --git a/src/sphin_source.h b/src/sphin_source.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2024 Centre National de la Recherche Scientifique
+ * Copyright (C) 2024 Clermont Auvergne INP
+ * Copyright (C) 2024 INSA Lyon
+ * Copyright (C) 2024 Institut Mines Télécom Albi-Carmaux
+ * Copyright (C) 2024 Institut National Polytechnique de Toulouse
+ * Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2024 PhotonLyX (info@photonlyx.com)
+ * Copyright (C) 2024 Université de Lorraine
+ * Copyright (C) 2024 Université Paul Sabatier
+ * Copyright (C) 2024 Université Toulouse - Jean Jaurès
+ *
+ * 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 SPHIN_SOURCE_H
+#define SPHIN_SOURCE_H
+
+#include "rsys/rsys.h"
+
+struct sphin_source;
+struct txtrdr;
+
+extern LOCAL_SYM res_T
+parse_source
+ (struct sphin* sphin,
+ struct txtrdr* txtrdr,
+ const char* name,
+ struct sphin_source** out_source);
+
+#endif /* SPHIN_SOURCE */