star-phor-input

File format for describing photoreactor configurations
git clone https://www.edstar.cnrs.fr/git/star-phor-input.git
Log | Files | Refs | README | LICENSE

commit 55db9d064e592ed010d5e2420f0bb2be2fecfa8f
parent d455bd9660c60a24525c3d4450841465be11a4f3
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date:   Wed, 21 May 2025 17:56:09 +0200

Refactor: Add suffixes to sensor and source structs/functions

Although the concepts of sources and sensors are common to both surfaces
and volumes, their definitions (both in a physical problem, and in the
numerical representation, as consequence) differ significantly between
the two cases. Up to this point, there was only one definition for the
source struct, which corresponded to surface sources, and a single
sensor struct that included only one member variable, response_function,
which happens to be shared by both volume and surface sensors.

Because only a small subset of member variables is common to both volume
and surface implementations, it makes sense to define separate structs
for each physical entity.

In this commit, the original sensor struct has been split into
sphin_sensor_surface and sphin_sensor_volume, reflecting their specific
contexts. Where functionality is shared —such as in
parse_response_function — it has been preserved across both
implementations. Additionally, all existing source references have been
renamed with the _surface suffix, as the current implementation supports
only surface sources. Volume sources will be introduced in a new
source_volume struct in subsequent work.

Diffstat:
M.gitignore | 1+
MMakefile | 4+++-
Msrc/sphin.h | 113+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/sphin_sensor.c | 175+++----------------------------------------------------------------------------
Msrc/sphin_sensor.h | 11+++++------
Asrc/sphin_sensor_surface.c | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/sphin_sensor_surface.h | 40++++++++++++++++++++++++++++++++++++++++
Asrc/sphin_sensor_volume.c | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/sphin_sensor_volume.h | 40++++++++++++++++++++++++++++++++++++++++
Dsrc/sphin_source.c | 429-------------------------------------------------------------------------------
Dsrc/sphin_source.h | 40----------------------------------------
Asrc/sphin_source_surface.c | 429+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/sphin_source_surface.h | 40++++++++++++++++++++++++++++++++++++++++
Msrc/sphin_surface.c | 51++++++++++++++++++++++++++-------------------------
Msrc/sphin_volume.c | 29++++++++++++++++-------------
Msrc/test_sphin_load_source.c | 40++++++++++++++++++++--------------------
Msrc/test_sphin_load_volume.c | 20++++++++++----------
17 files changed, 1105 insertions(+), 763 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -9,6 +9,7 @@ file.txt *.stl tags star-phor-input.5 +sphin.1 sphin test_sphin test_sphin_load_geometry diff --git a/Makefile b/Makefile @@ -42,7 +42,9 @@ SRC =\ src/sphin_config.c\ src/sphin_geometry.c\ src/sphin_sensor.c\ - src/sphin_source.c\ + src/sphin_sensor_surface.c\ + src/sphin_sensor_volume.c\ + src/sphin_source_surface.c\ src/sphin_surface.c\ src/sphin_volume.c OBJ = $(SRC:.c=.o) diff --git a/src/sphin.h b/src/sphin.h @@ -62,8 +62,7 @@ enum sphin_photon_unit { SPHIN_PHOTON_UNIT_NONE__ }; -/* TODO Maybe change this to source_surface* */ -enum sphin_source_direction_distribution_type { +enum sphin_source_surface_direction_distribution_type { SPHIN_SOURCE_DIRECTION_COLLIM, SPHIN_SOURCE_DIRECTION_COS_POW_N, SPHIN_SOURCE_DIRECTION_ISOTROPIC, @@ -105,43 +104,43 @@ static const struct sphin_brdf_specular SPHIN_BRDF_SPECULAR_NULL = SPHIN_BRDF_SPECULAR_NULL__ \ } -struct sphin_source_flux_density { +struct sphin_source_surface_flux_density { double flux_density; /* either [umol/m^2/s] or [W/m^2] */ enum sphin_photon_unit unit; }; -#define SPHIN_SOURCE_FLUX_DENSITY_NULL__ {0, SPHIN_PHOTON_UNIT_NONE__} -static const struct sphin_source_flux_density SPHIN_SOURCE_FLUX_DENSITY_NULL = - SPHIN_SOURCE_FLUX_DENSITY_NULL__; +#define SPHIN_SOURCE_SURFACE_FLUX_DENSITY_NULL__ {0, SPHIN_PHOTON_UNIT_NONE__} +static const struct sphin_source_surface_flux_density SPHIN_SOURCE_SURFACE_FLUX_DENSITY_NULL = + SPHIN_SOURCE_SURFACE_FLUX_DENSITY_NULL__; -struct sphin_source_direction_distribution_cos_pow_n { +struct sphin_source_surface_direction_distribution_cos_pow_n { double collimation_degree; }; -#define SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__ {0} -static const struct sphin_source_direction_distribution_cos_pow_n - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL = - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__; +#define SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__ {0} +static const struct sphin_source_surface_direction_distribution_cos_pow_n + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL = + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__; -struct sphin_source_direction_distribution_collim { +struct sphin_source_surface_direction_distribution_collim { double direction[3]; /* {0,0,0} <=> use surface normal */ }; -#define SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL__ {{0,0,0}} -static const struct sphin_source_direction_distribution_collim - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL = - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL__; - -struct sphin_source_direction_distribution { - enum sphin_source_direction_distribution_type type; - struct sphin_source_direction_distribution_cos_pow_n cos_pow_n; - struct sphin_source_direction_distribution_collim collim; +#define SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL__ {{0,0,0}} +static const struct sphin_source_surface_direction_distribution_collim + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL = + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL__; + +struct sphin_source_surface_direction_distribution { + enum sphin_source_surface_direction_distribution_type type; + struct sphin_source_surface_direction_distribution_cos_pow_n cos_pow_n; + struct sphin_source_surface_direction_distribution_collim collim; }; -#define SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL__ { \ +#define SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_NULL__ { \ SPHIN_SOURCE_DIRECTION_NONE__, \ - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__, \ - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL__ \ + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL__, \ + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL__ \ } -static const struct sphin_source_direction_distribution - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL = - SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL__; +static const struct sphin_source_surface_direction_distribution + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_NULL = + SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_NULL__; /* This structure, by design, describe a mesh in the simplest possible way, * without making assumptions about how it will be used. It provides only the @@ -195,9 +194,9 @@ struct sphin; /* Library handler */ struct sphin_config; /* Physical configuration */ struct sphin_brdf; struct sphin_geometry; -struct sphin_sensor; -struct sphin_source; -struct sphin_source_power; +struct sphin_sensor_surface; +struct sphin_sensor_volume; +struct sphin_source_surface; struct sphin_surface; struct sphin_volume; @@ -282,9 +281,9 @@ sphin_volume_get_ka double* ka); SPHIN_API res_T -sphin_volume_get_sensor +sphin_volume_get_sensor_volume (struct sphin_volume* volume, - struct sphin_sensor** sensor); + struct sphin_sensor_volume** sensor_volume); SPHIN_API res_T sphin_volume_get_geometry_count @@ -316,7 +315,7 @@ sphin_surface_get_brdf SPHIN_API res_T sphin_surface_get_source (const struct sphin_surface* surface, - struct sphin_source** source); /* May be NULL <=> no source */ + struct sphin_source_surface** source_surface); /* May be NULL <=> no source */ SPHIN_API res_T sphin_surface_get_geometry_count @@ -338,22 +337,22 @@ sphin_surface_source_get_power * API of the source ******************************************************************************/ SPHIN_API res_T -sphin_source_ref_get - (struct sphin_source* source); +sphin_source_surface_ref_get + (struct sphin_source_surface* source_surface); SPHIN_API res_T -sphin_source_ref_put - (struct sphin_source* source); +sphin_source_surface_ref_put + (struct sphin_source_surface* source_surface); SPHIN_API res_T -sphin_source_get_direction_distribution - (const struct sphin_source* source, - struct sphin_source_direction_distribution* distrib); +sphin_source_surface_get_direction_distribution + (const struct sphin_source_surface* source_surface, + struct sphin_source_surface_direction_distribution* distrib); SPHIN_API res_T sphin_source_surface_get_flux_density - (const struct sphin_source* source, - struct sphin_source_flux_density* density); + (const struct sphin_source_surface* source_surface, + struct sphin_source_surface_flux_density* density); /******************************************************************************* * API of the BRDF @@ -377,19 +376,35 @@ sphin_brdf_specular_get_reflectivity double* reflectivity); /******************************************************************************* - * API of the sensor + * API of the sensor_volume ******************************************************************************/ SPHIN_API res_T -sphin_sensor_ref_get - (struct sphin_sensor* sensor); +sphin_sensor_volume_ref_get + (struct sphin_sensor_volume* sensor_volume); SPHIN_API res_T -sphin_sensor_ref_put - (struct sphin_sensor* sensor); +sphin_sensor_volume_ref_put + (struct sphin_sensor_volume* sensor_volume); SPHIN_API res_T -sphin_sensor_get_response_function - (struct sphin_sensor* sensor, +sphin_sensor_volume_get_response_function + (struct sphin_sensor_volume* sensor_volume, + double* response_function); + +/******************************************************************************* + * API of the sensor_surface + ******************************************************************************/ +SPHIN_API res_T +sphin_sensor_surface_ref_get + (struct sphin_sensor_surface* sensor_surface); + +SPHIN_API res_T +sphin_sensor_surface_ref_put + (struct sphin_sensor_surface* sensor_surface); + +SPHIN_API res_T +sphin_sensor_surface_get_response_function + (struct sphin_sensor_surface* sensor_surface, double* response_function); /******************************************************************************* diff --git a/src/sphin_sensor.c b/src/sphin_sensor.c @@ -23,9 +23,6 @@ * 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_sensor.h" #include <rsys/cstr.h> @@ -35,78 +32,20 @@ struct txtrdr; -struct sphin_sensor { - struct str name; - double response_function; - struct sphin* sphin; - ref_T ref; -}; - /******************************************************************************* - * Helper functions + * Local functions ******************************************************************************/ -static res_T -sensor_create - (struct sphin* sphin, - const char* name, - struct sphin_sensor** out_sensor) -{ - struct sphin_sensor* sensor = NULL; - res_T res = RES_OK; - - ASSERT(NULL != sphin); - ASSERT(NULL != out_sensor); - ASSERT(NULL != name); - ASSERT('\0' != name[0]); /* Name can't be empty */ - - sensor = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_sensor)); - if (NULL == sensor) { res = RES_MEM_ERR; goto error; } - ref_init(&sensor->ref); - SPHIN(ref_get(sphin)); - sensor->sphin = sphin; - - str_init(sphin->allocator, &sensor->name); - res = str_set(&sensor->name, name); - if (RES_OK != res) { goto error; } - -exit: - *out_sensor = sensor; - return res; -error: - if (NULL != sensor) { - SPHIN(sensor_ref_put(sensor)); - sensor = NULL; - } - goto exit; -} - -static void -release_sensor - (ref_T* address) -{ - struct sphin_sensor* sensor = NULL; - struct sphin* sphin = NULL; - - ASSERT(NULL != address); - sensor = CONTAINER_OF(address, struct sphin_sensor, ref); - str_release(&sensor->name); - sphin = sensor->sphin; - MEM_RM(sphin->allocator, sensor); - SPHIN(ref_put(sphin)); -} - -static res_T +res_T parse_response_function - (struct sphin_sensor* sensor, + (double* out_response_function, struct txtrdr* txtrdr, char* value) { char* token = NULL; char* token_ptr = NULL; res_T res = RES_OK; - double response_function; + double response_function = 0; - ASSERT(NULL != sensor); ASSERT(NULL != txtrdr); if (NULL == value) { res = RES_BAD_ARG; goto error; } @@ -116,7 +55,6 @@ parse_response_function res = cstr_to_double(token, &response_function); if (RES_OK != res) { goto error; } if (response_function < 0) { res = RES_BAD_ARG; goto error; } - sensor->response_function = response_function; token = strtok_r(NULL, " \t", &token_ptr); if (NULL != token) { res = RES_BAD_ARG; goto error; } @@ -125,111 +63,8 @@ parse_response_function if (RES_OK != res) { goto error; } exit: + *out_response_function = response_function; return res; error: goto exit; } - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -parse_sensor - (struct sphin* sphin, - struct txtrdr* txtrdr, - const char* name, - struct sphin_sensor** out_sensor) -{ - char* keyword = NULL; - char* token = NULL; - char* token_ptr = NULL; - char* value = NULL; - struct sphin_sensor* sensor = NULL; - struct str line; - res_T res = RES_OK; - - ASSERT(NULL != sphin); - ASSERT(NULL != txtrdr); - ASSERT(NULL != name); - ASSERT(NULL != out_sensor); - - str_init(sphin->allocator, &line); - - res = sensor_create(sphin, name, &sensor); - 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); - value = token; - /* Parse response function */ - if (0 == strcmp(keyword, "response_function")){ - res = parse_response_function(sensor, txtrdr, value); - } - else { - break; - } - if (RES_OK != res) { goto error; } - } - -exit: - str_release(&line); - *out_sensor = sensor; - return res; -error: - if (sensor != NULL){ - SPHIN(sensor_ref_put(sensor)); - sensor = NULL; - } - goto exit; -} - -/******************************************************************************* - * Exported functions - ******************************************************************************/ -res_T -sphin_sensor_ref_get - (struct sphin_sensor* sensor) -{ - if (NULL == sensor) { - return RES_BAD_ARG; - } - ref_get(&sensor->ref); - return RES_OK; -} - -res_T -sphin_sensor_ref_put - (struct sphin_sensor* sensor) -{ - if (NULL == sensor) { - return RES_BAD_ARG; - } - ref_put(&sensor->ref, release_sensor); - return RES_OK; -} - -res_T -sphin_sensor_get_response_function - (struct sphin_sensor* sensor, - double* response_function) -{ - if (NULL == sensor || NULL == response_function){ - return RES_BAD_ARG; - } - - *response_function = sensor->response_function; - return RES_OK; -} diff --git a/src/sphin_sensor.h b/src/sphin_sensor.h @@ -27,14 +27,13 @@ #include <rsys/rsys.h> -struct sphin_sensor; +struct sphin_sensor_surface; struct txtrdr; extern LOCAL_SYM res_T -parse_sensor - (struct sphin* sphin, +parse_response_function + (double* out_response_function, struct txtrdr* txtrdr, - const char* name, - struct sphin_sensor** out_sensor); + char* value); -#endif /* SPHIN_SENSOR */ +#endif /* SPHIN_SENSOR_H */ diff --git a/src/sphin_sensor_surface.c b/src/sphin_sensor_surface.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_sensor.h" +#include "sphin_sensor_surface.h" + +#include <rsys/cstr.h> +#include <rsys/ref_count.h> +#include <rsys/str.h> +#include <rsys/text_reader.h> + +struct txtrdr; + +struct sphin_sensor_surface { + struct str name; + double response_function; + + struct sphin* sphin; + ref_T ref; +}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static res_T +sensor_surface_create + (struct sphin* sphin, + const char* name, + struct sphin_sensor_surface** out_sensor_surface) +{ + struct sphin_sensor_surface* sensor_surface = NULL; + res_T res = RES_OK; + + ASSERT(NULL != sphin); + ASSERT(NULL != out_sensor_surface); + ASSERT(NULL != name); + ASSERT('\0' != name[0]); /* Name can't be empty */ + + sensor_surface = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_sensor_surface)); + if (NULL == sensor_surface) { res = RES_MEM_ERR; goto error; } + ref_init(&sensor_surface->ref); + SPHIN(ref_get(sphin)); + sensor_surface->sphin = sphin; + + str_init(sphin->allocator, &sensor_surface->name); + res = str_set(&sensor_surface->name, name); + if (RES_OK != res) { goto error; } + +exit: + *out_sensor_surface = sensor_surface; + return res; +error: + if (NULL != sensor_surface) { + SPHIN(sensor_surface_ref_put(sensor_surface)); + sensor_surface = NULL; + } + goto exit; +} + +static void +release_sensor_surface + (ref_T* address) +{ + struct sphin_sensor_surface* sensor_surface = NULL; + struct sphin* sphin = NULL; + + ASSERT(NULL != address); + sensor_surface = CONTAINER_OF(address, struct sphin_sensor_surface, ref); + str_release(&sensor_surface->name); + sphin = sensor_surface->sphin; + MEM_RM(sphin->allocator, sensor_surface); + SPHIN(ref_put(sphin)); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +parse_sensor_surface + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_sensor_surface** out_sensor_surface) +{ + char* keyword = NULL; + char* token = NULL; + char* token_ptr = NULL; + char* value = NULL; + struct sphin_sensor_surface* sensor_surface = NULL; + struct str line; + res_T res = RES_OK; + + ASSERT(NULL != sphin); + ASSERT(NULL != txtrdr); + ASSERT(NULL != name); + ASSERT(NULL != out_sensor_surface); + + str_init(sphin->allocator, &line); + + res = sensor_surface_create(sphin, name, &sensor_surface); + 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); + value = token; + /* Parse response function */ + if (0 == strcmp(keyword, "response_function")){ + res = parse_response_function(&sensor_surface->response_function, + txtrdr, value); + } + else { + break; + } + if (RES_OK != res) { goto error; } + } + +exit: + str_release(&line); + *out_sensor_surface = sensor_surface; + return res; +error: + if (sensor_surface != NULL){ + SPHIN(sensor_surface_ref_put(sensor_surface)); + sensor_surface = NULL; + } + goto exit; +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sphin_sensor_surface_ref_get + (struct sphin_sensor_surface* sensor_surface) +{ + if (NULL == sensor_surface) { + return RES_BAD_ARG; + } + ref_get(&sensor_surface->ref); + return RES_OK; +} + +res_T +sphin_sensor_surface_ref_put + (struct sphin_sensor_surface* sensor_surface) +{ + if (NULL == sensor_surface) { + return RES_BAD_ARG; + } + ref_put(&sensor_surface->ref, release_sensor_surface); + return RES_OK; +} + +res_T +sphin_sensor_surface_get_response_function + (struct sphin_sensor_surface* sensor_surface, + double* response_function) +{ + if (NULL == sensor_surface || NULL == response_function){ + return RES_BAD_ARG; + } + + *response_function = sensor_surface->response_function; + return RES_OK; +} diff --git a/src/sphin_sensor_surface.h b/src/sphin_sensor_surface.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_SENSOR_SURFACE_H +#define SPHIN_SENSOR_SURFACE_H + +#include <rsys/rsys.h> + +struct sphin_sensor_surface; +struct txtrdr; + +extern LOCAL_SYM res_T +parse_sensor_surface + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_sensor_surface** out_sensor_surface); + +#endif /* SPHIN_SENSOR_SURFACE_H */ diff --git a/src/sphin_sensor_volume.c b/src/sphin_sensor_volume.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_sensor.h" +#include "sphin_sensor_volume.h" + +#include <rsys/cstr.h> +#include <rsys/ref_count.h> +#include <rsys/str.h> +#include <rsys/text_reader.h> + +struct txtrdr; + +struct sphin_sensor_volume { + struct str name; + double response_function; + + struct sphin* sphin; + ref_T ref; +}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static res_T +sensor_volume_create + (struct sphin* sphin, + const char* name, + struct sphin_sensor_volume** out_sensor_volume) +{ + struct sphin_sensor_volume* sensor_volume = NULL; + res_T res = RES_OK; + + ASSERT(NULL != sphin); + ASSERT(NULL != out_sensor_volume); + ASSERT(NULL != name); + ASSERT('\0' != name[0]); /* Name can't be empty */ + + sensor_volume = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_sensor_volume)); + if (NULL == sensor_volume) { res = RES_MEM_ERR; goto error; } + ref_init(&sensor_volume->ref); + SPHIN(ref_get(sphin)); + sensor_volume->sphin = sphin; + + str_init(sphin->allocator, &sensor_volume->name); + res = str_set(&sensor_volume->name, name); + if (RES_OK != res) { goto error; } + +exit: + *out_sensor_volume = sensor_volume; + return res; +error: + if (NULL != sensor_volume) { + SPHIN(sensor_volume_ref_put(sensor_volume)); + sensor_volume = NULL; + } + goto exit; +} + +static void +release_sensor_volume + (ref_T* address) +{ + struct sphin_sensor_volume* sensor_volume = NULL; + struct sphin* sphin = NULL; + + ASSERT(NULL != address); + sensor_volume = CONTAINER_OF(address, struct sphin_sensor_volume, ref); + str_release(&sensor_volume->name); + sphin = sensor_volume->sphin; + MEM_RM(sphin->allocator, sensor_volume); + SPHIN(ref_put(sphin)); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +parse_sensor_volume + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_sensor_volume** out_sensor_volume) +{ + char* keyword = NULL; + char* token = NULL; + char* token_ptr = NULL; + char* value = NULL; + struct sphin_sensor_volume* sensor_volume = NULL; + struct str line; + res_T res = RES_OK; + + ASSERT(NULL != sphin); + ASSERT(NULL != txtrdr); + ASSERT(NULL != name); + ASSERT(NULL != out_sensor_volume); + + str_init(sphin->allocator, &line); + + res = sensor_volume_create(sphin, name, &sensor_volume); + 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); + value = token; + /* Parse response function */ + if (0 == strcmp(keyword, "response_function")){ + res = parse_response_function(&sensor_volume->response_function, + txtrdr, value); + } + else { + break; + } + if (RES_OK != res) { goto error; } + } + +exit: + str_release(&line); + *out_sensor_volume = sensor_volume; + return res; +error: + if (sensor_volume != NULL){ + SPHIN(sensor_volume_ref_put(sensor_volume)); + sensor_volume = NULL; + } + goto exit; +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sphin_sensor_volume_ref_get + (struct sphin_sensor_volume* sensor_volume) +{ + if (NULL == sensor_volume) { + return RES_BAD_ARG; + } + ref_get(&sensor_volume->ref); + return RES_OK; +} + +res_T +sphin_sensor_volume_ref_put + (struct sphin_sensor_volume* sensor_volume) +{ + if (NULL == sensor_volume) { + return RES_BAD_ARG; + } + ref_put(&sensor_volume->ref, release_sensor_volume); + return RES_OK; +} + +res_T +sphin_sensor_volume_get_response_function + (struct sphin_sensor_volume* sensor_volume, + double* response_function) +{ + if (NULL == sensor_volume || NULL == response_function){ + return RES_BAD_ARG; + } + + *response_function = sensor_volume->response_function; + return RES_OK; +} diff --git a/src/sphin_sensor_volume.h b/src/sphin_sensor_volume.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_SENSOR_VOLUME_H +#define SPHIN_SENSOR_VOLUME_H + +#include <rsys/rsys.h> + +struct sphin_sensor_volume; +struct txtrdr; + +extern LOCAL_SYM res_T +parse_sensor_volume + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_sensor_volume** out_sensor_volume); + +#endif /* SPHIN_SENSOR_VOLUME_H */ diff --git a/src/sphin_source.c b/src/sphin_source.c @@ -1,429 +0,0 @@ -/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique - * Copyright (C) 2024-2025 Clermont Auvergne INP - * Copyright (C) 2024-2025 INSA Lyon - * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse - * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) - * Copyright (C) 2024-2025 Université de Lorraine - * Copyright (C) 2024-2025 Université Paul Sabatier - * Copyright (C) 2024-2025 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 "sphin_surface.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_source_direction_distribution direction_distribution; - struct sphin_source_flux_density flux_density; - - struct sphin* sphin; - 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_SOURCE_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_lambertian_direction_distribution - (struct sphin_source_direction_distribution* dir_dist, - struct txtrdr* txtrdr, - char* token) -{ - char* token_ptr = NULL; - - ASSERT(NULL != dir_dist); - ASSERT(NULL != txtrdr); - - (void)txtrdr; - - token = strtok_r(token, " \t", &token_ptr); - if (NULL != token) { return RES_BAD_ARG; } - - dir_dist->type = SPHIN_SOURCE_DIRECTION_ISOTROPIC; - return RES_OK; -} - -static res_T -parse_collim_direction_distribution - (struct sphin_source_direction_distribution* dir_dist, - struct txtrdr* txtrdr, - char* token) -{ - char* str_direction = NULL; - char* token_ptr = NULL; - double direction[3]; - res_T res = RES_OK; - - (void)txtrdr; - - ASSERT(NULL != dir_dist); - ASSERT(NULL != txtrdr); - - if (NULL == token) { res = RES_BAD_ARG; goto error; } - - dir_dist->type = SPHIN_SOURCE_DIRECTION_COLLIM; - str_direction = strtok_r(token, " \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 */ - res = RES_BAD_ARG; goto error; - } - - d3_set(dir_dist->collim.direction, direction); - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_cos_pow_n_direction_distribution - (struct sphin_source_direction_distribution* dir_dist, - struct txtrdr* txtrdr, - char* token) -{ - char* str_collimation_degree = NULL; - char* token_ptr = NULL; - double collimation_degree; - res_T res = RES_OK; - - (void)txtrdr; - - ASSERT(NULL != dir_dist); - ASSERT(NULL != txtrdr); - - if (NULL == token) { res = RES_BAD_ARG; goto error; } - - dir_dist->type = SPHIN_SOURCE_DIRECTION_COS_POW_N; - - str_collimation_degree = strtok_r(token, " \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; } - dir_dist->cos_pow_n.collimation_degree = collimation_degree; - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_direction_distribution - (struct sphin_source* source, - struct txtrdr* txtrdr, - char* value) -{ - char* direction_distribution_type = NULL; - char* token_ptr = NULL; - res_T res = RES_OK; - - ASSERT(NULL != source); - ASSERT(NULL != txtrdr); - - if (NULL == value) { res = RES_BAD_ARG; goto error; }; - - /* 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")){ - res = parse_lambertian_direction_distribution( - &source->direction_distribution, - txtrdr, - token_ptr); - } - - /* Collimated source */ - else if (0 == strcmp(direction_distribution_type, "COLLIM")){ - res = parse_collim_direction_distribution( - &source->direction_distribution, - txtrdr, - token_ptr); - } - - /* Cos^n model of direction distribution */ - else if (0 == strcmp(direction_distribution_type, "COS_POW_N")){ - res = parse_cos_pow_n_direction_distribution( - &source->direction_distribution, - txtrdr, - token_ptr); - } - else { res = RES_BAD_ARG; goto error; } - if (RES_OK != res) {goto error;} - - res = txtrdr_read_line(txtrdr); - if (RES_OK != res) { 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_unit = NULL; - char* str_flux_density = NULL; - char* token_ptr = NULL; - double flux_density; - res_T res = RES_OK; - - ASSERT(NULL != source); - ASSERT(NULL != txtrdr); - - if (NULL == value) { 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; - - /* Parse unit */ - flux_density_unit = strtok_r(NULL, " \t", &token_ptr); - if (NULL == flux_density_unit){ res = RES_BAD_ARG; goto error; } - - /* Parse kinetic flux density unit */ - if (0 == strcmp(flux_density_unit, "mol/m^2/s") - || 0 == strcmp(flux_density_unit, "mol.m^-2.s^-1")) { - source->flux_density.unit= SPHIN_PHOTON_UNIT_MOL; - source->flux_density.flux_density *= 1e6; /* From mol to umol */ - } - else if (0 == strcmp(flux_density_unit, "umol/m^2/s") - || 0 == strcmp(flux_density_unit, "umol.m^-2.s^-1")) { - source->flux_density.unit= SPHIN_PHOTON_UNIT_MOL; - source->flux_density.flux_density *= 1; /* No conversion */ - } - - /* Energy flux density energy */ - else if (0 == strcmp(flux_density_unit, "mW/m^2") - || 0 == strcmp(flux_density_unit, "mW.m^-2")) { - source->flux_density.unit= SPHIN_PHOTON_UNIT_JOULE; - source->flux_density.flux_density *= 1e-3; /* From mWatt to Watt*/ - } - else if (0 == strcmp(flux_density_unit, "W/m^2") - || 0 == strcmp(flux_density_unit, "W.m^-2") - || 0 == strcmp(flux_density_unit, "J.m^-2.s^-1") - || 0 == strcmp(flux_density_unit, "J/m^2/s")) { - source->flux_density.unit= SPHIN_PHOTON_UNIT_JOULE; - source->flux_density.flux_density *= 1; /* No conversion */ - } - else { res = RES_BAD_ARG; goto error; } - - res = txtrdr_read_line(txtrdr); - if (RES_OK != res) { goto error; } - -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")){ - res = parse_flux_density(source, txtrdr, value); - } - else if (0 == strcmp(keyword, "direction")){ - res = parse_direction_distribution(source, txtrdr, value); - } - else { - break; - } - if (RES_OK != res) { goto error; } - } - -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; -} - -res_T -sphin_source_get_direction_distribution - (const struct sphin_source* source, - struct sphin_source_direction_distribution* distrib) -{ - if (NULL == source || NULL == distrib) { - return RES_BAD_ARG; - } - - *distrib = source->direction_distribution; - return RES_OK; -} - -res_T -sphin_source_surface_get_flux_density - (const struct sphin_source* source, - struct sphin_source_flux_density* density) -{ - if (NULL == source || NULL == density) { - return RES_BAD_ARG; - } - - *density = source->flux_density; - return RES_OK; -} diff --git a/src/sphin_source.h b/src/sphin_source.h @@ -1,40 +0,0 @@ -/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique - * Copyright (C) 2024-2025 Clermont Auvergne INP - * Copyright (C) 2024-2025 INSA Lyon - * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse - * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) - * Copyright (C) 2024-2025 Université de Lorraine - * Copyright (C) 2024-2025 Université Paul Sabatier - * Copyright (C) 2024-2025 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 */ diff --git a/src/sphin_source_surface.c b/src/sphin_source_surface.c @@ -0,0 +1,429 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_surface.h" +#include "sphin_surface.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_surface { + struct str name; + struct sphin_source_surface_direction_distribution direction_distribution; + struct sphin_source_surface_flux_density flux_density; + + struct sphin* sphin; + ref_T ref; +}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static res_T +source_surface_create + (struct sphin* sphin, + const char* name, + struct sphin_source_surface** out_source) +{ + struct sphin_source_surface* 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_surface)); + 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_SURFACE_DIRECTION_DISTRIBUTION_NULL; + source->flux_density = SPHIN_SOURCE_SURFACE_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_surface_ref_put(source)); + source = NULL; + } + goto exit; +} + +static void +release_source_surface + (ref_T* address) +{ + struct sphin_source_surface* source = NULL; + struct sphin* sphin = NULL; + + ASSERT(NULL != address); + + source = CONTAINER_OF(address, struct sphin_source_surface, ref); + str_release(&source->name); + sphin = source->sphin; + MEM_RM(sphin->allocator, source); + SPHIN(ref_put(sphin)); +} + +static res_T +parse_lambertian_direction_distribution + (struct sphin_source_surface_direction_distribution* dir_dist, + struct txtrdr* txtrdr, + char* token) +{ + char* token_ptr = NULL; + + ASSERT(NULL != dir_dist); + ASSERT(NULL != txtrdr); + + (void)txtrdr; + + token = strtok_r(token, " \t", &token_ptr); + if (NULL != token) { return RES_BAD_ARG; } + + dir_dist->type = SPHIN_SOURCE_DIRECTION_ISOTROPIC; + return RES_OK; +} + +static res_T +parse_collim_direction_distribution + (struct sphin_source_surface_direction_distribution* dir_dist, + struct txtrdr* txtrdr, + char* token) +{ + char* str_direction = NULL; + char* token_ptr = NULL; + double direction[3]; + res_T res = RES_OK; + + (void)txtrdr; + + ASSERT(NULL != dir_dist); + ASSERT(NULL != txtrdr); + + if (NULL == token) { res = RES_BAD_ARG; goto error; } + + dir_dist->type = SPHIN_SOURCE_DIRECTION_COLLIM; + str_direction = strtok_r(token, " \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 */ + res = RES_BAD_ARG; goto error; + } + + d3_set(dir_dist->collim.direction, direction); + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_cos_pow_n_direction_distribution + (struct sphin_source_surface_direction_distribution* dir_dist, + struct txtrdr* txtrdr, + char* token) +{ + char* str_collimation_degree = NULL; + char* token_ptr = NULL; + double collimation_degree; + res_T res = RES_OK; + + (void)txtrdr; + + ASSERT(NULL != dir_dist); + ASSERT(NULL != txtrdr); + + if (NULL == token) { res = RES_BAD_ARG; goto error; } + + dir_dist->type = SPHIN_SOURCE_DIRECTION_COS_POW_N; + + str_collimation_degree = strtok_r(token, " \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; } + dir_dist->cos_pow_n.collimation_degree = collimation_degree; + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_direction_distribution + (struct sphin_source_surface* source, + struct txtrdr* txtrdr, + char* value) +{ + char* direction_distribution_type = NULL; + char* token_ptr = NULL; + res_T res = RES_OK; + + ASSERT(NULL != source); + ASSERT(NULL != txtrdr); + + if (NULL == value) { res = RES_BAD_ARG; goto error; }; + + /* 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")){ + res = parse_lambertian_direction_distribution( + &source->direction_distribution, + txtrdr, + token_ptr); + } + + /* Collimated source */ + else if (0 == strcmp(direction_distribution_type, "COLLIM")){ + res = parse_collim_direction_distribution( + &source->direction_distribution, + txtrdr, + token_ptr); + } + + /* Cos^n model of direction distribution */ + else if (0 == strcmp(direction_distribution_type, "COS_POW_N")){ + res = parse_cos_pow_n_direction_distribution( + &source->direction_distribution, + txtrdr, + token_ptr); + } + else { res = RES_BAD_ARG; goto error; } + if (RES_OK != res) {goto error;} + + res = txtrdr_read_line(txtrdr); + if (RES_OK != res) { goto error; } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_flux_density + (struct sphin_source_surface* source, + struct txtrdr* txtrdr, + char* value) +{ + char* flux_density_unit = NULL; + char* str_flux_density = NULL; + char* token_ptr = NULL; + double flux_density; + res_T res = RES_OK; + + ASSERT(NULL != source); + ASSERT(NULL != txtrdr); + + if (NULL == value) { 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; + + /* Parse unit */ + flux_density_unit = strtok_r(NULL, " \t", &token_ptr); + if (NULL == flux_density_unit){ res = RES_BAD_ARG; goto error; } + + /* Parse kinetic flux density unit */ + if (0 == strcmp(flux_density_unit, "mol/m^2/s") + || 0 == strcmp(flux_density_unit, "mol.m^-2.s^-1")) { + source->flux_density.unit= SPHIN_PHOTON_UNIT_MOL; + source->flux_density.flux_density *= 1e6; /* From mol to umol */ + } + else if (0 == strcmp(flux_density_unit, "umol/m^2/s") + || 0 == strcmp(flux_density_unit, "umol.m^-2.s^-1")) { + source->flux_density.unit= SPHIN_PHOTON_UNIT_MOL; + source->flux_density.flux_density *= 1; /* No conversion */ + } + + /* Energy flux density energy */ + else if (0 == strcmp(flux_density_unit, "mW/m^2") + || 0 == strcmp(flux_density_unit, "mW.m^-2")) { + source->flux_density.unit= SPHIN_PHOTON_UNIT_JOULE; + source->flux_density.flux_density *= 1e-3; /* From mWatt to Watt*/ + } + else if (0 == strcmp(flux_density_unit, "W/m^2") + || 0 == strcmp(flux_density_unit, "W.m^-2") + || 0 == strcmp(flux_density_unit, "J.m^-2.s^-1") + || 0 == strcmp(flux_density_unit, "J/m^2/s")) { + source->flux_density.unit= SPHIN_PHOTON_UNIT_JOULE; + source->flux_density.flux_density *= 1; /* No conversion */ + } + else { res = RES_BAD_ARG; goto error; } + + res = txtrdr_read_line(txtrdr); + if (RES_OK != res) { goto error; } + +exit: + return res; +error: + goto exit; +} +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +parse_source_surface + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_source_surface** out_source) +{ + struct sphin_source_surface* 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_surface_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")){ + res = parse_flux_density(source, txtrdr, value); + } + else if (0 == strcmp(keyword, "direction")){ + res = parse_direction_distribution(source, txtrdr, value); + } + else { + break; + } + if (RES_OK != res) { goto error; } + } + +exit: + str_release(&line); + *out_source = source; + return res; +error: + if (NULL != source) { + SPHIN(source_surface_ref_put(source)); + source = NULL; + } + goto exit; +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sphin_source_surface_ref_get + (struct sphin_source_surface* source) +{ + if (NULL == source) { + return RES_BAD_ARG; + } + ref_get(&source->ref); + return RES_OK; +} + +res_T +sphin_source_surface_ref_put + (struct sphin_source_surface* source) +{ + if (NULL == source) { + return RES_BAD_ARG; + } + ref_put(&source->ref, release_source_surface); + return RES_OK; +} + +res_T +sphin_source_surface_get_direction_distribution + (const struct sphin_source_surface* source, + struct sphin_source_surface_direction_distribution* distrib) +{ + if (NULL == source || NULL == distrib) { + return RES_BAD_ARG; + } + + *distrib = source->direction_distribution; + return RES_OK; +} + +res_T +sphin_source_surface_get_flux_density + (const struct sphin_source_surface* source, + struct sphin_source_surface_flux_density* density) +{ + if (NULL == source || NULL == density) { + return RES_BAD_ARG; + } + + *density = source->flux_density; + return RES_OK; +} diff --git a/src/sphin_source_surface.h b/src/sphin_source_surface.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2024-2025 Centre National de la Recherche Scientifique + * Copyright (C) 2024-2025 Clermont Auvergne INP + * Copyright (C) 2024-2025 INSA Lyon + * Copyright (C) 2024-2025 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2024-2025 Institut National Polytechnique de Toulouse + * Copyright (C) 2024-2025 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2024-2025 PhotonLyX (info@photonlyx.com) + * Copyright (C) 2024-2025 Université de Lorraine + * Copyright (C) 2024-2025 Université Paul Sabatier + * Copyright (C) 2024-2025 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_SURFACE_H +#define SPHIN_SOURCE_SURFACE_H + +#include <rsys/rsys.h> + +struct sphin_source; +struct txtrdr; + +extern LOCAL_SYM res_T +parse_source_surface + (struct sphin* sphin, + struct txtrdr* txtrdr, + const char* name, + struct sphin_source_surface** out_source); + +#endif /* SPHIN_SOURCE_SURFACE_H */ diff --git a/src/sphin_surface.c b/src/sphin_surface.c @@ -28,8 +28,8 @@ #include "sphin_c.h" #include "sphin_config.h" #include "sphin_geometry.h" -#include "sphin_sensor.h" -#include "sphin_source.h" +#include "sphin_sensor_surface.h" +#include "sphin_source_surface.h" #include "sphin_surface.h" #include <rsys/cstr.h> @@ -43,8 +43,8 @@ struct sphin_surface { struct sphin_brdf* brdf; struct darray_sphin_geometry_ptr geometries; /* dynamic array of struct geometry. see rsys/dynamic_array.h */ - struct sphin_sensor* sensor; - struct sphin_source* source; + struct sphin_sensor_surface* sensor_surface; + struct sphin_source_surface* source_surface; ref_T ref; }; @@ -73,8 +73,8 @@ surface_create SPHIN(ref_get(sphin)); surface->sphin = sphin; surface->brdf = NULL; - surface->sensor = NULL; - surface->source = NULL; + surface->sensor_surface= NULL; + surface->source_surface = NULL; str_init(sphin->allocator, &surface->name); darray_sphin_geometry_ptr_init(sphin->allocator, &surface->geometries); @@ -100,8 +100,8 @@ release_surface struct sphin* sphin = NULL; struct sphin_brdf* brdf = NULL; struct sphin_geometry** geometries = NULL; - struct sphin_sensor* sensor = NULL; - struct sphin_source* source = NULL; + struct sphin_sensor_surface* sensor_surface = NULL; + struct sphin_source_surface* source_surface = NULL; struct sphin_surface* surface = NULL; ASSERT(NULL != address); @@ -124,14 +124,14 @@ release_surface sphin = surface->sphin; brdf = surface->brdf; - sensor = surface->sensor; - source = surface->source; + sensor_surface = surface->sensor_surface; + source_surface = surface->source_surface; MEM_RM(sphin->allocator, surface); - if (NULL != source) { - SPHIN(source_ref_put(source)); + if (NULL != source_surface) { + SPHIN(source_surface_ref_put(source_surface)); } - if (NULL != sensor) { - SPHIN(sensor_ref_put(sensor)); + if (NULL != sensor_surface) { + SPHIN(sensor_surface_ref_put(sensor_surface)); } if (NULL != brdf) { SPHIN(brdf_ref_put(brdf)); @@ -221,15 +221,16 @@ parse_surface * check if there is only tabs and spaces after : */ token = strtok_r(NULL, " \t", &token_ptr); if (NULL != token) { res = RES_BAD_ARG; goto error; } - res = parse_source(surface->sphin, txtrdr, name, &surface->source); + res = parse_source_surface(surface->sphin, + txtrdr, name, &surface->source_surface); } else if (0 == strcmp(keyword, "sensor")) { - /* sensor should not have a name. + /* sensor_surface should not have a name. * strings are not allowed in the input file after the : * check if there is only tabs and spaces after : */ token = strtok_r(NULL, " \t", &token_ptr); if (NULL != token) { res = RES_BAD_ARG; goto error; } - res = parse_sensor(surface->sphin, txtrdr, name, &surface->sensor); + res = parse_sensor_surface(surface->sphin, txtrdr, name, &surface->sensor_surface); } else { break; @@ -292,13 +293,13 @@ sphin_surface_get_brdf res_T sphin_surface_get_source (const struct sphin_surface* surface, - struct sphin_source** source) + struct sphin_source_surface** source_surface) { - if (NULL == surface || NULL == source) { + if (NULL == surface || NULL == source_surface) { return RES_BAD_ARG; } - *source = surface->source; /* NULL if surface has no source */ + *source_surface = surface->source_surface; /* NULL if surface has no source */ return RES_OK; } @@ -347,18 +348,18 @@ sphin_surface_source_get_power size_t geometry_count = 0; size_t i = 0; struct sphin_geometry* geometry = NULL; - struct sphin_source* source = NULL; - struct sphin_source_flux_density density = SPHIN_SOURCE_FLUX_DENSITY_NULL; + struct sphin_source_surface* source_surface = NULL; + struct sphin_source_surface_flux_density density = SPHIN_SOURCE_SURFACE_FLUX_DENSITY_NULL; res_T res = RES_OK; - source = surface->source; + source_surface = surface->source_surface; - if (NULL == source) { + if (NULL == source_surface) { res = RES_BAD_ARG; goto error; } - res = sphin_source_surface_get_flux_density(source, &density); + res = sphin_source_surface_get_flux_density(source_surface, &density); if (RES_OK != res) { goto error; } geometry_count = darray_sphin_geometry_ptr_size_get(&surface->geometries); diff --git a/src/sphin_volume.c b/src/sphin_volume.c @@ -27,7 +27,7 @@ #include "sphin_c.h" #include "sphin_config.h" #include "sphin_geometry.h" -#include "sphin_sensor.h" +#include "sphin_sensor_volume.h" #include "sphin_volume.h" #include <rsys/cstr.h> /* str_to_double */ @@ -40,7 +40,7 @@ struct sphin_volume { double ka; struct darray_sphin_geometry_ptr geometries; /* dynamic array of struct geometry. see rsys/dynamic_array.h */ - struct sphin_sensor* sensor; + struct sphin_sensor_volume* sensor_volume; struct sphin* sphin; ref_T ref; }; @@ -69,7 +69,7 @@ volume_create ref_init(&volume->ref); SPHIN(ref_get(sphin)); volume->sphin = sphin; - volume->sensor = NULL; + volume->sensor_volume = NULL; str_init(sphin->allocator, &volume->name); darray_sphin_geometry_ptr_init(sphin->allocator, &volume->geometries); @@ -94,7 +94,7 @@ release_volume size_t i, ngeometries; struct sphin_geometry** geometries = NULL; struct sphin* sphin = NULL; - struct sphin_sensor* sensor = NULL; + struct sphin_sensor_volume* sensor_volume = NULL; struct sphin_volume* volume = NULL; ASSERT(NULL != address); @@ -115,10 +115,10 @@ release_volume } sphin = volume->sphin; - sensor = volume->sensor; + sensor_volume = volume->sensor_volume; MEM_RM(sphin->allocator, volume); - if (NULL != sensor) { - SPHIN(sensor_ref_put(sensor)); + if (NULL != sensor_volume) { + SPHIN(sensor_volume_ref_put(sensor_volume)); } SPHIN(ref_put(sphin)); } @@ -254,12 +254,13 @@ parse_volume res = parse_ka(volume, txtrdr, token); } else if (0 == strcmp(keyword, "sensor")) { - /* for the sensor, + /* for the sensor_volume, * strings are not allowed in the input file after the : * check if there is only tabs and spaces after : */ token = strtok_r(NULL, "\t ", &token_ptr); if (NULL != token) { res = RES_BAD_ARG; goto error; } - res = parse_sensor(volume->sphin, txtrdr, name, &volume->sensor); + res = parse_sensor_volume(volume->sphin, txtrdr, + name, &volume->sensor_volume); } else { break; @@ -320,14 +321,16 @@ sphin_volume_get_ka } res_T -sphin_volume_get_sensor +sphin_volume_get_sensor_volume (struct sphin_volume* volume, - struct sphin_sensor** sensor) + struct sphin_sensor_volume** sensor_volume) { - if (NULL == volume || NULL == sensor || NULL == volume->sensor ) { + if (NULL == volume + || NULL == sensor_volume + || NULL == volume->sensor_volume ) { return RES_BAD_ARG; } - *sensor = volume->sensor; + *sensor_volume = volume->sensor_volume; return RES_OK; } diff --git a/src/test_sphin_load_source.c b/src/test_sphin_load_source.c @@ -58,9 +58,9 @@ test_source_api size_t nsurfaces, ngeometries; struct sphin_config* config = NULL; struct sphin_surface* surface = NULL; - struct sphin_source* source = NULL; - struct sphin_source_direction_distribution dir_dist = SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL; - struct sphin_source_flux_density flux_density = SPHIN_SOURCE_FLUX_DENSITY_NULL; + struct sphin_source_surface* source = NULL; + struct sphin_source_surface_direction_distribution dir_dist = SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_NULL; + struct sphin_source_surface_flux_density flux_density = SPHIN_SOURCE_SURFACE_FLUX_DENSITY_NULL; FILE* fp = NULL; @@ -90,29 +90,29 @@ test_source_api CHK(sphin_surface_get_geometry_count(NULL, &ngeometries) == RES_BAD_ARG); CHK(sphin_surface_get_geometry_count(surface, &ngeometries) == RES_OK); CHK(sphin_surface_get_source(surface, &source) == RES_OK); - CHK(sphin_source_get_direction_distribution(NULL, &dir_dist) == RES_BAD_ARG); - CHK(sphin_source_get_direction_distribution(source, NULL) == RES_BAD_ARG); - CHK(sphin_source_get_direction_distribution(source, &dir_dist) == RES_OK); + CHK(sphin_source_surface_get_direction_distribution(NULL, &dir_dist) == RES_BAD_ARG); + CHK(sphin_source_surface_get_direction_distribution(source, NULL) == RES_BAD_ARG); + CHK(sphin_source_surface_get_direction_distribution(source, &dir_dist) == RES_OK); CHK(dir_dist.type == SPHIN_SOURCE_DIRECTION_ISOTROPIC); - CHK(dir_dist.cos_pow_n.collimation_degree == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL.collimation_degree); - CHK(dir_dist.collim.direction[0] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[0]); - CHK(dir_dist.collim.direction[1] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[1]); - CHK(dir_dist.collim.direction[2] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[2]); + CHK(dir_dist.cos_pow_n.collimation_degree == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL.collimation_degree); + CHK(dir_dist.collim.direction[0] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[0]); + CHK(dir_dist.collim.direction[1] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[1]); + CHK(dir_dist.collim.direction[2] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[2]); CHK(sphin_source_surface_get_flux_density(NULL, &flux_density) == RES_BAD_ARG); CHK(sphin_source_surface_get_flux_density(source, NULL) == RES_BAD_ARG); CHK(sphin_source_surface_get_flux_density(source, &flux_density) == RES_OK); CHK(eq_eps(flux_density.flux_density, 200, 1e-15)); CHK(flux_density.unit == SPHIN_PHOTON_UNIT_MOL); - CHK(sphin_source_ref_get(NULL) == RES_BAD_ARG); - CHK(sphin_source_ref_put(NULL) == RES_BAD_ARG); - CHK(sphin_source_ref_get(source) == RES_OK); - CHK(sphin_source_ref_put(source) == RES_OK); + CHK(sphin_source_surface_ref_get(NULL) == RES_BAD_ARG); + CHK(sphin_source_surface_ref_put(NULL) == RES_BAD_ARG); + CHK(sphin_source_surface_ref_get(source) == RES_OK); + CHK(sphin_source_surface_ref_put(source) == RES_OK); CHK(sphin_config_get_surface(config, 1, &surface) == RES_OK); CHK(sphin_surface_get_source(surface, &source) == RES_OK); - CHK(sphin_source_get_direction_distribution(source, &dir_dist) == RES_OK); + CHK(sphin_source_surface_get_direction_distribution(source, &dir_dist) == RES_OK); CHK(dir_dist.type == SPHIN_SOURCE_DIRECTION_COLLIM); - CHK(dir_dist.cos_pow_n.collimation_degree == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL.collimation_degree); + CHK(dir_dist.cos_pow_n.collimation_degree == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COS_POW_N_NULL.collimation_degree); CHK(dir_dist.collim.direction[0] == 0); CHK(dir_dist.collim.direction[1] == 0); CHK(dir_dist.collim.direction[2] == 0); @@ -122,12 +122,12 @@ test_source_api CHK(sphin_config_get_surface(config, 2, &surface) == RES_OK); CHK(sphin_surface_get_source(surface, &source) == RES_OK); - CHK(sphin_source_get_direction_distribution(source, &dir_dist) == RES_OK); + CHK(sphin_source_surface_get_direction_distribution(source, &dir_dist) == RES_OK); CHK(dir_dist.type == SPHIN_SOURCE_DIRECTION_COS_POW_N); CHK(eq_eps(dir_dist.cos_pow_n.collimation_degree, 1, 1e-15)); - CHK(dir_dist.collim.direction[0] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[0]); - CHK(dir_dist.collim.direction[1] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[1]); - CHK(dir_dist.collim.direction[2] == SPHIN_SOURCE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[2]); + CHK(dir_dist.collim.direction[0] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[0]); + CHK(dir_dist.collim.direction[1] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[1]); + CHK(dir_dist.collim.direction[2] == SPHIN_SOURCE_SURFACE_DIRECTION_DISTRIBUTION_COLLIM_NULL.direction[2]); CHK(sphin_source_surface_get_flux_density(source, NULL) == RES_BAD_ARG); CHK(sphin_source_surface_get_flux_density(NULL, &flux_density) == RES_BAD_ARG); CHK(sphin_source_surface_get_flux_density(source, &flux_density) == RES_OK); diff --git a/src/test_sphin_load_volume.c b/src/test_sphin_load_volume.c @@ -92,7 +92,7 @@ test_volume_api struct sphin_config* config = NULL; const char* path = "file.txt"; struct sphin_volume* volume = NULL; - struct sphin_sensor* sensor = NULL; + struct sphin_sensor_volume* sensor_volume = NULL; size_t nvolumes; double ka, response_function; FILE* fp = NULL; @@ -131,14 +131,14 @@ test_volume_api CHK(sphin_volume_get_ka(volume, NULL) == RES_BAD_ARG); CHK(sphin_volume_get_ka(volume, &ka) == RES_OK); CHK(eq_eps(ka, 2.11, 1e-15)); - CHK(sphin_volume_get_sensor(NULL, NULL) == RES_BAD_ARG); - CHK(sphin_volume_get_sensor(NULL, &sensor) == RES_BAD_ARG); - CHK(sphin_volume_get_sensor(volume, NULL) == RES_BAD_ARG); - CHK(sphin_volume_get_sensor(volume, &sensor) == RES_OK); - CHK(sphin_sensor_get_response_function(NULL, NULL) == RES_BAD_ARG); - CHK(sphin_sensor_get_response_function(NULL, &response_function) == RES_BAD_ARG); - CHK(sphin_sensor_get_response_function(sensor, NULL) == RES_BAD_ARG); - CHK(sphin_sensor_get_response_function(sensor, &response_function) == RES_OK); + CHK(sphin_volume_get_sensor_volume(NULL, NULL) == RES_BAD_ARG); + CHK(sphin_volume_get_sensor_volume(NULL, &sensor_volume) == RES_BAD_ARG); + CHK(sphin_volume_get_sensor_volume(volume, NULL) == RES_BAD_ARG); + CHK(sphin_volume_get_sensor_volume(volume, &sensor_volume) == RES_OK); + CHK(sphin_sensor_volume_get_response_function(NULL, NULL) == RES_BAD_ARG); + CHK(sphin_sensor_volume_get_response_function(NULL, &response_function) == RES_BAD_ARG); + CHK(sphin_sensor_volume_get_response_function(sensor_volume, NULL) == RES_BAD_ARG); + CHK(sphin_sensor_volume_get_response_function(sensor_volume, &response_function) == RES_OK); CHK(eq_eps(response_function, 1, 1e-15)); CHK(sphin_volume_ref_get(volume) == RES_OK); CHK(sphin_volume_ref_put(volume) == RES_OK); @@ -147,7 +147,7 @@ test_volume_api CHK(sphin_config_get_volume(config, 1, &volume) == RES_OK); CHK(sphin_volume_get_ka(volume, &ka) == RES_OK); CHK(eq_eps(ka, 10, 1e-15)); - CHK(sphin_volume_get_sensor(volume, &sensor) == RES_BAD_ARG); /* Volume has no sensor */ + CHK(sphin_volume_get_sensor_volume(volume, &sensor_volume) == RES_BAD_ARG); /* Volume has no sensor_volume */ /* Test volume 2 */ CHK(sphin_config_get_volume(config, 2, &volume) == RES_OK);