commit 592fdcacb4d294c779742ebca5015b83042cdd48
parent e45d99ac04661e02893ef06a2c2d412048ab4943
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 7 Feb 2019 11:51:03 +0100
Implement the internal green function API
Diffstat:
6 files changed, 433 insertions(+), 10 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -57,6 +57,7 @@ set(SDIS_FILES_SRC
sdis_data.c
sdis_device.c
sdis_estimator.c
+ sdis_green.c
sdis_heat_path.c
sdis_interface.c
sdis_medium.c
@@ -71,6 +72,7 @@ set(SDIS_FILES_INC
sdis_camera.h
sdis_device_c.h
sdis_estimator_c.h
+ sdis_green.h
sdis_heat_path.h
sdis_heat_path_boundary_Xd.h
sdis_heat_path_conductive_Xd.h
diff --git a/src/sdis.h b/src/sdis.h
@@ -60,6 +60,7 @@ struct sdis_camera;
struct sdis_data;
struct sdis_device;
struct sdis_estimator;
+struct sdis_green_function;
struct sdis_interface;
struct sdis_medium;
struct sdis_scene;
diff --git a/src/sdis_green.c b/src/sdis_green.c
@@ -0,0 +1,228 @@
+/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com)
+ *
+ * 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 "sdis_device_c.h"
+#include "sdis_green.h"
+#include "sdis_medium_c.h"
+#include "sdis_interface_c.h"
+
+#include <rsys/mem_allocator.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static struct green_medium*
+fetch_green_medium
+ (struct sdis_green_function* green, struct sdis_medium* mdm)
+{
+ struct green_medium* gmdm = NULL;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(green && mdm);
+
+ i = medium_get_id(mdm);
+
+ /* Ensure that the LUT can store the medium */
+ if(i >= darray_green_medium_size_get(&green->media)) {
+ res = darray_green_medium_resize(&green->media, i+1);
+ if(res != RES_OK) goto error;
+ }
+
+ gmdm = darray_green_medium_data_get(&green->media) + i;
+ if(!gmdm->mdm) {
+ /* Register the medium against the green function */
+ SDIS(medium_ref_get(mdm));
+ gmdm->mdm = mdm;
+ }
+
+exit:
+ return res != RES_OK ? NULL : gmdm;
+error:
+ goto exit;
+}
+
+static struct green_interface*
+fetch_green_interface
+ (struct sdis_green_function* green, struct sdis_interface* interf)
+{
+ struct green_interface* ginterf = NULL;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(green && interf);
+
+ i = interface_get_id(interf);
+
+ /* Ensure that the LUT can store the interface */
+ if(i >= darray_green_interface_size_get(&green->interfaces)) {
+ res = darray_green_interface_resize(&green->interfaces, i+1);
+ if(res != RES_OK) goto error;
+ }
+
+ ginterf = darray_green_interface_data_get(&green->interfaces) + i;
+ if(!ginterf->interf) {
+ /* Register the interface against the green function */
+ SDIS(interface_ref_get(interf));
+ ginterf->interf = interf;
+ }
+
+exit:
+ return res != RES_OK ? NULL : ginterf;
+error:
+ goto exit;
+}
+
+static void
+green_function_clear(struct sdis_green_function* green)
+{
+ size_t i, n;
+ struct green_medium* media;
+ struct green_interface* interfaces;
+ ASSERT(green);
+
+ n = darray_green_medium_size_get(&green->media);
+ media = darray_green_medium_data_get(&green->media);
+ FOR_EACH(i, 0, n) {
+ if(media[i].mdm) {
+ SDIS(medium_ref_put(media[i].mdm));
+ }
+ }
+ darray_green_medium_clear(&green->media);
+
+ n = darray_green_interface_size_get(&green->interfaces);
+ interfaces = darray_green_interface_data_get(&green->interfaces);
+ FOR_EACH(i, 0, n) {
+ if(interfaces[i].interf) {
+ SDIS(interface_ref_put(interfaces[i].interf));
+ }
+ }
+ darray_green_interface_clear(&green->interfaces);
+}
+
+static void
+green_function_release(ref_T* ref)
+{
+ struct sdis_device* dev;
+ struct sdis_green_function* green;
+ ASSERT(ref);
+ green = CONTAINER_OF(ref, struct sdis_green_function, ref);
+ dev = green->dev;
+ green_function_clear(green);
+ darray_green_medium_release(&green->media);
+ darray_green_interface_release(&green->interfaces);
+ MEM_RM(dev->allocator, green);
+ SDIS(device_ref_put(dev));
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+green_function_create
+ (struct sdis_device* dev, struct sdis_green_function** out_green)
+{
+ struct sdis_green_function* green = NULL;
+ res_T res = RES_OK;
+ ASSERT(dev && out_green);
+
+ green = MEM_CALLOC(dev->allocator, 1, sizeof(*green));
+ if(!green) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&green->ref);
+ SDIS(device_ref_get(dev));
+ green->dev = dev;
+ darray_green_medium_init(dev->allocator, &green->media);
+ darray_green_interface_init(dev->allocator, &green->interfaces);
+
+exit:
+ *out_green = green;
+ return res;
+error:
+ if(green) {
+ green_function_ref_put(green);
+ green = NULL;
+ }
+ goto exit;
+}
+
+void
+green_function_ref_get(struct sdis_green_function* green)
+{
+ ASSERT(green);
+ ref_get(&green->ref);
+}
+
+void
+green_function_ref_put(struct sdis_green_function* green)
+{
+ ASSERT(green);
+ ref_put(&green->ref, green_function_release);
+}
+
+res_T
+green_function_add_medium_limit_vertex
+ (struct sdis_green_function* green,
+ struct sdis_medium* mdm,
+ const struct green_vertex* vertex)
+{
+ struct green_medium* gmdm = NULL;
+ ASSERT(green && mdm && vertex);
+ gmdm = fetch_green_medium(green, mdm);
+ if(!gmdm) return RES_MEM_ERR;
+ return darray_green_vertex_push_back(&gmdm->limit_vertices, vertex);
+}
+
+res_T
+green_function_add_interface_limit_vertex
+ (struct sdis_green_function* green,
+ struct sdis_interface* interf,
+ const struct green_vertex* vertex)
+{
+ struct green_interface* ginterf = NULL;
+ ASSERT(green && interf && vertex);
+ ginterf = fetch_green_interface(green, interf);
+ if(!ginterf) return RES_MEM_ERR;
+ return darray_green_vertex_push_back(&ginterf->limit_vertices, vertex);
+}
+
+res_T
+green_function_add_power_term
+ (struct sdis_green_function* green,
+ struct sdis_medium* mdm,
+ const double term)
+{
+ struct green_medium* gmdm = NULL;
+ ASSERT(green && mdm && term >= 0);
+ gmdm = fetch_green_medium(green, mdm);
+ if(!gmdm) return RES_MEM_ERR;
+ gmdm->power_term += term;
+ return RES_OK;
+}
+
+res_T
+green_function_add_flux_term
+ (struct sdis_green_function* green,
+ struct sdis_interface* interf,
+ const double term)
+{
+ struct green_interface* ginterf = NULL;
+ ASSERT(green && interf && term >= 0);
+ ginterf = fetch_green_interface(green, interf);
+ if(!ginterf) return RES_MEM_ERR;
+ ginterf->flux_term += term;
+ return RES_OK;
+}
+
diff --git a/src/sdis_green.h b/src/sdis_green.h
@@ -0,0 +1,196 @@
+/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com)
+ *
+ * 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 SDIS_GREEN_H
+#define SDIS_GREEN_H
+
+#include <rsys/dynamic_array.h>
+#include <rsys/ref_count.h>
+
+/*******************************************************************************
+ * Spatio temporal vertices registered against the green function
+ ******************************************************************************/
+struct green_vertex {
+ double pos[3];
+ double delta_time; /* Time spent into the system */
+};
+
+/* Generate the dynamic array of green vertices */
+#define DARRAY_NAME green_vertex
+#define DARRAY_DATA struct green_vertex
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * Medium registered against the green function
+ ******************************************************************************/
+struct green_medium {
+ struct sdis_medium* mdm;
+ double power_term;
+ struct darray_green_vertex limit_vertices;
+};
+
+static INLINE void
+green_medium_init
+ (struct mem_allocator* allocator, struct green_medium* gmdm)
+{
+ ASSERT(gmdm);
+ gmdm->mdm = NULL;
+ gmdm->power_term = 0;
+ darray_green_vertex_init(allocator, &gmdm->limit_vertices);
+}
+
+static INLINE void
+green_medium_release(struct green_medium* gmdm)
+{
+ ASSERT(gmdm);
+ darray_green_vertex_release(&gmdm->limit_vertices);
+}
+
+static INLINE res_T
+green_medium_copy
+ (struct green_medium* dst, const struct green_medium* src)
+{
+ ASSERT(dst && src);
+ dst->mdm = src->mdm;
+ dst->power_term = src->power_term;
+ return darray_green_vertex_copy(&dst->limit_vertices, &src->limit_vertices);
+}
+
+static INLINE res_T
+green_medium_copy_and_release
+ (struct green_medium* dst, struct green_medium* src)
+{
+ ASSERT(dst && src);
+ dst->mdm = src->mdm;
+ dst->power_term = src->power_term;
+ return darray_green_vertex_copy_and_release
+ (&dst->limit_vertices, &src->limit_vertices);
+}
+
+/* Generate the dynamic array of media registered in the green function */
+#define DARRAY_NAME green_medium
+#define DARRAY_DATA struct green_medium
+#define DARRAY_FUNCTOR_INIT green_medium_init
+#define DARRAY_FUNCTOR_RELEASE green_medium_release
+#define DARRAY_FUNCTOR_COPY green_medium_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE green_medium_copy_and_release
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * Interface registered against the green function
+ ******************************************************************************/
+struct green_interface {
+ struct sdis_interface* interf;
+ double flux_term;
+ struct darray_green_vertex limit_vertices;
+};
+
+static INLINE void
+green_interface_init
+ (struct mem_allocator* allocator, struct green_interface* ginter)
+{
+ ASSERT(ginter);
+ ginter->interf = NULL;
+ ginter->flux_term = 0;
+ darray_green_vertex_init(allocator, &ginter->limit_vertices);
+}
+
+static INLINE void
+green_interface_release(struct green_interface* ginter)
+{
+ ASSERT(ginter);
+ darray_green_vertex_release(&ginter->limit_vertices);
+}
+
+static INLINE res_T
+green_interface_copy
+ (struct green_interface* dst, const struct green_interface* src)
+{
+ ASSERT(dst && src);
+ dst->interf = src->interf;
+ dst->flux_term = src->flux_term;
+ return darray_green_vertex_copy(&dst->limit_vertices, &src->limit_vertices);
+}
+
+static INLINE res_T
+green_interface_copy_and_release
+ (struct green_interface* dst, struct green_interface* src)
+{
+ ASSERT(dst && src);
+ dst->interf = src->interf;
+ dst->flux_term = src->flux_term;
+ return darray_green_vertex_copy_and_release
+ (&dst->limit_vertices, &src->limit_vertices);
+}
+
+/* Generate the dynamic array of interfaces registered in the green function */
+#define DARRAY_NAME green_interface
+#define DARRAY_DATA struct green_interface
+#define DARRAY_FUNCTOR_INIT green_interface_init
+#define DARRAY_FUNCTOR_RELEASE green_interface_release
+#define DARRAY_FUNCTOR_COPY green_interface_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE green_interface_copy_and_release
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * Green function private API
+ ******************************************************************************/
+struct sdis_green_function {
+ struct darray_green_medium media;
+ struct darray_green_interface interfaces;
+
+ ref_T ref;
+ struct sdis_device* dev;
+};
+
+extern LOCAL_SYM res_T
+green_function_create
+ (struct sdis_device* dev,
+ struct sdis_green_function** green);
+
+extern LOCAL_SYM void
+green_function_ref_get
+ (struct sdis_green_function* greeN);
+
+extern LOCAL_SYM void
+green_function_ref_put
+ (struct sdis_green_function* green);
+
+extern LOCAL_SYM res_T
+green_function_add_medium_limit_vertex
+ (struct sdis_green_function* green,
+ struct sdis_medium* mdm,
+ const struct green_vertex* vertex);
+
+extern LOCAL_SYM res_T
+green_function_add_interface_limit_vertex
+ (struct sdis_green_function* green,
+ struct sdis_interface* interf,
+ const struct green_vertex* vertex);
+
+extern LOCAL_SYM res_T
+green_function_add_power_term
+ (struct sdis_green_function* green,
+ struct sdis_medium* mdm,
+ const double term);
+
+extern LOCAL_SYM res_T
+green_function_add_flux_term
+ (struct sdis_green_function* green,
+ struct sdis_interface* interf,
+ const double term);
+
+#endif /* SDIS_GREEN_H */
+
diff --git a/src/sdis_interface.c b/src/sdis_interface.c
@@ -201,13 +201,6 @@ interface_get_medium
return mdm;
}
-unsigned
-interface_get_id(const struct sdis_interface* interf)
-{
- ASSERT(interf);
- return interf->id.index;
-}
-
void
setup_interface_fragment_2d
(struct sdis_interface_fragment* frag,
diff --git a/src/sdis_interface_c.h b/src/sdis_interface_c.h
@@ -41,9 +41,12 @@ interface_get_medium
(const struct sdis_interface* interf,
const enum sdis_side side);
-extern LOCAL_SYM unsigned
-interface_get_id
- (const struct sdis_interface* interf);
+static FINLINE unsigned
+interface_get_id(const struct sdis_interface* interf)
+{
+ ASSERT(interf);
+ return interf->id.index;
+}
extern LOCAL_SYM void
setup_interface_fragment_2d