commit e61eb3a158492092793a2d0734da0cf707ae2d65
parent f2f579aa001224a42e8f2c5c442fd7855e536c8d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sun, 20 Mar 2016 14:14:05 +0100
Add the ellipsoid distribution to the YAML fileformat
Diffstat:
3 files changed, 119 insertions(+), 3 deletions(-)
diff --git a/src/schiff_args.c b/src/schiff_args.c
@@ -116,6 +116,10 @@ geometry_release(struct schiff_geometry* geom)
{
ASSERT(geom);
switch(geom->type) {
+ case SCHIFF_ELLIPSOID:
+ param_release(&geom->data.ellipsoid.a);
+ param_release(&geom->data.ellipsoid.b);
+ param_release(&geom->data.ellipsoid.c);
case SCHIFF_CYLINDER:
param_release(&geom->data.cylinder.radius);
param_release(&geom->data.cylinder.height);
@@ -496,6 +500,113 @@ parse_yaml_param_distribution
}
static res_T
+parse_yaml_ellipsoid
+ (const char* filename,
+ yaml_document_t* doc,
+ const yaml_node_t* node,
+ struct schiff_geometry* geom,
+ double* geom_proba)
+{
+ enum {
+ PROBA = BIT(0),
+ LENGTH_a = BIT(1),
+ LENGTH_b = BIT(2),
+ LENGTH_c = BIT(3),
+ SLICES = BIT(4)
+ };
+ int mask = 0; /* Register the parsed histogram attributes */
+ size_t nattrs;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(filename && doc && node && geom && geom_proba);
+
+ if(node->type != YAML_MAPPING_NODE) {
+ log_err(filename, node, "expecting a mapping of ellipsoid attributes.\n");
+ return RES_BAD_ARG;
+ }
+
+ nattrs = (size_t)
+ (node->data.mapping.pairs.top - node->data.mapping.pairs.start);
+
+ FOR_EACH(i, 0, nattrs) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, node->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, node->data.mapping.pairs.start[i].value);
+ ASSERT(key->type == YAML_SCALAR_NODE);
+
+ if(!strcmp((char*)key->data.scalar.value, "proba")) {
+ if(mask & PROBA) {
+ log_err(filename, node, "the sphere proba is already defined.\n");
+ return RES_BAD_ARG;
+ }
+ mask |= PROBA;
+ res = parse_yaml_double(filename, val, geom_proba);
+
+ /* # slices used to discretized the triangular ellipsoid */
+ } else if(!strcmp((char*)key->data.scalar.value, "slices")) {
+ if(mask & SLICES) {
+ log_err(filename, key,
+ "the ellipsoid number of slices is already defined.\n");
+ return RES_BAD_ARG;
+ }
+ mask |= SLICES;
+ res = parse_yaml_uint(filename, val, &geom->data.ellipsoid.nslices);
+ }
+
+ /* Length of the ellipsoid semi-principal axis */
+ #define PARSE_SEMI_PRINCIPAL_AXIS(Axis) { \
+ if(mask & LENGTH_ ## Axis) { \
+ log_err(filename, node, \
+ "the ellipsoid \""STR(Axis)"\" parameter is alread defined.\n"); \
+ return RES_BAD_ARG; \
+ } \
+ mask |= LENGTH_ ## Axis; \
+ res = parse_yaml_param_distribution \
+ (filename, doc, val, &geom->data.ellipsoid.Axis); \
+ } (void)0
+ else if(!strcmp((char*)key->data.scalar.value, "a")) {
+ PARSE_SEMI_PRINCIPAL_AXIS(a);
+ } else if(!strcmp((char*)key->data.scalar.value, "b")) {
+ PARSE_SEMI_PRINCIPAL_AXIS(b);
+ } else if(!strcmp((char*)key->data.scalar.value, "c")) {
+ PARSE_SEMI_PRINCIPAL_AXIS(c);
+ }
+ #undef PARSE_SEMI_PRINCIPAL_AXIS
+
+ /* Error */
+ else {
+ log_err(filename, key, "unkown sphere attribute `%s'.\n",
+ key->data.scalar.value);
+ return RES_BAD_ARG;
+ }
+ if(res != RES_OK) return res;
+ }
+
+ /* Ensure the completness of the ellipsoid distribution */
+ #define CHECK_SEMI_PRINCIPAL_AXIS(Axis) { \
+ if(!(mask & LENGTH_ ## Axis)) { \
+ log_err(filename, node, \
+ "missing the length of the semi principal axis \""STR(Axis)"\".\n"); \
+ return RES_BAD_ARG; \
+ } \
+ } (void)0
+ CHECK_SEMI_PRINCIPAL_AXIS(a);
+ CHECK_SEMI_PRINCIPAL_AXIS(b);
+ CHECK_SEMI_PRINCIPAL_AXIS(c);
+ #undef CHECK_SEMI_PRINCIPAL_AXIS
+ if(!(mask & PROBA)) { /* Default proba */
+ *geom_proba = 1.0;
+ }
+ if(!(mask & SLICES)) { /* Default number of slices */
+ geom->data.ellipsoid.nslices = SCHIFF_ELLIPSOID_DEFAULT.nslices;
+ }
+ geom->type = SCHIFF_ELLIPSOID;
+ return RES_OK;
+}
+
+static res_T
parse_yaml_cylinder
(const char* filename,
yaml_document_t* doc,
@@ -674,7 +785,7 @@ parse_yaml_sphere
res = parse_yaml_param_distribution
(filename, doc, val, &geom->data.sphere.radius);
- /* # slices used to discretized the triangulare sphere */
+ /* # slices used to discretized the triangular sphere */
} else if(!strcmp((char*)key->data.scalar.value, "slices")) {
if(mask & SLICES) {
log_err(filename, key,
@@ -731,7 +842,9 @@ parse_yaml_geom_distrib
val = yaml_document_get_node(doc, node->data.mapping.pairs.start[0].value);
ASSERT(key->type == YAML_SCALAR_NODE);
- if(!strcmp((char*)key->data.scalar.value, "cylinder")) {
+ if(!strcmp((char*)key->data.scalar.value, "ellipsoid")) {
+ res = parse_yaml_ellipsoid(filename, doc, val, geom, proba);
+ } else if(!strcmp((char*)key->data.scalar.value, "cylinder")) {
res = parse_yaml_cylinder(filename, doc, val, geom, proba);
} else if(!strcmp((char*)key->data.scalar.value, "sphere")) {
res = parse_yaml_sphere(filename, doc, val, geom, proba);
diff --git a/src/schiff_geometry.c b/src/schiff_geometry.c
@@ -489,7 +489,8 @@ schiff_geometry_distribution_init
struct geometry_distribution_context* ctx = NULL;
size_t i;
res_T res = RES_OK;
- ASSERT(distrib && geoms && ngeoms && ran_geoms && properties);
+ ASSERT(distrib && geoms && ngeoms && ran_geoms);
+ /* Note that properties may be NULL if the "-G" option is defined */
*distrib = SSCHIFF_NULL_GEOMETRY_DISTRIBUTION;
diff --git a/src/schiff_geometry.h b/src/schiff_geometry.h
@@ -67,6 +67,8 @@ struct schiff_ellipsoid {
#define SCHIFF_ELLIPSOID_DEFAULT__ \
{SCHIFF_PARAM_DEFAULT__, SCHIFF_PARAM_DEFAULT__, SCHIFF_PARAM_DEFAULT__, 64}
+static const struct schiff_ellipsoid SCHIFF_ELLIPSOID_DEFAULT =
+ SCHIFF_ELLIPSOID_DEFAULT__;
struct schiff_sphere {
struct schiff_param radius;