schiff

Estimate the radiative properties of soft particless
git clone git://git.meso-star.com/schiff.git
Log | Files | Refs | README | LICENSE

commit 4f9640f40316e86e1a3054293e45c9de62526a2a
parent 63bfccee6ba5d16d5314d703f6e9378efbc3f432
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 24 Mar 2016 14:00:50 +0100

Add the super_shape geometry to the YAML file format

Diffstat:
Msrc/schiff_args.c | 209++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 191 insertions(+), 18 deletions(-)

diff --git a/src/schiff_args.c b/src/schiff_args.c @@ -101,6 +101,7 @@ param_release(struct schiff_param* param) static void geometry_release(struct schiff_geometry* geom) { + int i; ASSERT(geom); switch(geom->type) { case SCHIFF_ELLIPSOID: @@ -119,6 +120,12 @@ geometry_release(struct schiff_geometry* geom) case SCHIFF_SPHERE: param_release(&geom->data.sphere.radius); break; + case SCHIFF_SUPER_SHAPE: + FOR_EACH(i, 0, 6) { + param_release(&geom->data.super_shape.formulas[0][i]); + param_release(&geom->data.super_shape.formulas[1][i]); + } + break; case SCHIFF_NONE: /* Do nothing */ break; default: FATAL("Unreachable code\n"); break; } @@ -534,6 +541,76 @@ parse_yaml_param_distribution } static res_T +parse_yaml_super_shape_formula + (const char* filename, + yaml_document_t* doc, + const yaml_node_t* node, + struct schiff_param formula[6]) +{ + int mask = 0; /* Register the parsed histogram attributes */ + size_t nattrs; + size_t i; + res_T res = RES_OK; + ASSERT(filename && doc && node && formula); + + if(node->type != YAML_MAPPING_NODE) { + log_err(filename, node, + "expecting a mapping of super-formula parameters.\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, *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); + + #define PARSE_SUPER_SHAPE_PARAM(Param) \ + if(!strcmp((char*)key->data.scalar.value, STR(Param))) { \ + if(mask & BIT(Param)) { \ + log_err(filename, key, \ + "the "STR(Param)" super-formula parameter is already defined.\n"); \ + return RES_BAD_ARG; \ + } \ + mask |= BIT(Param); \ + res = parse_yaml_param_distribution \ + (filename, doc, val, DBL_MIN, DBL_MAX, formula + Param); \ + if(res != RES_OK) return res; \ + continue; \ + } (void)0 + PARSE_SUPER_SHAPE_PARAM(A); + PARSE_SUPER_SHAPE_PARAM(B); + PARSE_SUPER_SHAPE_PARAM(M); + PARSE_SUPER_SHAPE_PARAM(N0); + PARSE_SUPER_SHAPE_PARAM(N1); + PARSE_SUPER_SHAPE_PARAM(N2); + #undef PARSE_SUPER_SHAPE_PARAM + + log_err(filename, key, "unknown super-formula parameter `%s'.\n", + key->data.scalar.value); + return RES_BAD_ARG; + } + #define CHECK_SUPER_SHAPE_PARAM(Param) \ + if(!(mask & BIT(Param))) { \ + log_err(filename, node, \ + "missing the "STR(Param)" super formula parameter.\n"); \ + return RES_BAD_ARG; \ + } (void)0 + CHECK_SUPER_SHAPE_PARAM(A); + CHECK_SUPER_SHAPE_PARAM(B); + CHECK_SUPER_SHAPE_PARAM(M); + CHECK_SUPER_SHAPE_PARAM(N0); + CHECK_SUPER_SHAPE_PARAM(N1); + CHECK_SUPER_SHAPE_PARAM(N2); + #undef CHECK_SUPER_SHAPE_PARAM + return RES_OK; +} + +static res_T parse_yaml_ellipsoid (const char* filename, yaml_document_t* doc, @@ -734,7 +811,7 @@ parse_yaml_cylinder res = parse_yaml_double (filename, val, DBL_MIN, DBL_MAX, &geom->data.cylinder.aspect_ratio); - /* # slices used to discretized the triangular cylinder */ + /* # slices used to discretized the cylinder */ } else if(!strcmp((char*)key->data.scalar.value, "slices")) { SETUP_MASK(SLICES, "cylinder number of slices"); res = parse_yaml_uint @@ -742,7 +819,7 @@ parse_yaml_cylinder /* Error */ } else { - log_err(filename, key, "unkown cylinder attribute `%s'.\n", + log_err(filename, key, "unknown cylinder attribute `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; } @@ -816,33 +893,28 @@ parse_yaml_sphere val = yaml_document_get_node(doc, node->data.mapping.pairs.start[i].value); ASSERT(key->type == YAML_SCALAR_NODE); + #define SETUP_MASK(Flag, Name) { \ + if(mask & Flag) { \ + log_err(filename, key, "the "Name" is already defined.\n"); \ + return RES_BAD_ARG; \ + } \ + mask |= Flag; \ + } (void)0 + /* Probality to sample this geometry */ 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; + SETUP_MASK(PROBA, "sphere proba"); res = parse_yaml_double(filename, val, DBL_MIN, DBL_MAX, geom_proba); /* Sphere radius */ } else if(!strcmp((char*)key->data.scalar.value, "radius")) { - if(mask & RADIUS) { - log_err(filename, key, "the sphere radius is already defined.\n"); - return RES_BAD_ARG; - } - mask |= RADIUS; + SETUP_MASK(RADIUS, "sphere radius"); res = parse_yaml_param_distribution (filename, doc, val, DBL_MIN, DBL_MAX, &geom->data.sphere.radius); /* # slices used to discretized the triangular sphere */ } else if(!strcmp((char*)key->data.scalar.value, "slices")) { - if(mask & SLICES) { - log_err(filename, key, - "the sphere number of slices is already defined.\n"); - return RES_BAD_ARG; - } - mask |= SLICES; + SETUP_MASK(SLICES, "sphere number of slices"); res = parse_yaml_uint (filename, val, 4, 32768, &geom->data.sphere.nslices); @@ -853,6 +925,8 @@ parse_yaml_sphere return RES_BAD_ARG; } if(res != RES_OK) return res; + + #undef SETUP_MASK } /* Ensure the completness of the spherical distribution */ @@ -871,6 +945,103 @@ parse_yaml_sphere } static res_T +parse_yaml_super_shape + (const char* filename, + yaml_document_t* doc, + const yaml_node_t* node, + struct schiff_geometry* geom, + double* geom_proba) +{ + enum { + FORMULA0 = BIT(0), + FORMULA1 = BIT(1), + PROBA = BIT(2), + SLICES = BIT(3) + }; + int mask = 0; /* Register the parsed 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 super-shape 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); + + #define SETUP_MASK(Flag, Name) { \ + if(mask & Flag) { \ + log_err(filename, key, "the "Name" is already defined.\n"); \ + return RES_BAD_ARG; \ + } \ + mask |= Flag; \ + } (void)0 + + /* Geometry probability */ + if(!strcmp((char*)key->data.scalar.value, "proba")) { + SETUP_MASK(PROBA, "super-shape proba"); + res = parse_yaml_double(filename, val, DBL_MIN, DBL_MAX, geom_proba); + + /* Super shape formula0 */ + } else if(!strcmp((char*)key->data.scalar.value, "formula0")) { + SETUP_MASK(FORMULA0, "super-shape formula0"); + res = parse_yaml_super_shape_formula + (filename, doc, val, geom->data.super_shape.formulas[0]); + + /* Super shape formula1 */ + } else if(!strcmp((char*)key->data.scalar.value, "formula1")) { + SETUP_MASK(FORMULA1, "super-shape formula1"); + res = parse_yaml_super_shape_formula + (filename, doc, val, geom->data.super_shape.formulas[1]); + + /* # slices used to discretized the super shape */ + } else if(!strcmp((char*)key->data.scalar.value, "slices")) { + SETUP_MASK(SLICES, "super-shape number of slices"); + res = parse_yaml_uint + (filename, val, 4, 32768, &geom->data.super_shape.nslices); + + /* Error */ + } else { + log_err(filename, key, "unknown super-shape attribute `%s'.\n", + key->data.scalar.value); + res = RES_BAD_ARG; + } + if(res != RES_OK) return res; + + #undef SETUP_MASK + } + + /* Ensure the completness of the cylinder distribution */ + if(!(mask & FORMULA0)) { + log_err(filename, node, "missing the formula0 attribute.\n"); + return RES_BAD_ARG; + } else if(!(mask & FORMULA1)) { + log_err(filename, node, "missing the formula1 attribute.\n"); + return RES_BAD_ARG; + } + + if(!(mask & PROBA)) { /* Default proba */ + *geom_proba = 1.0; + } + if(!(mask & SLICES)) { /* Default number of slices */ + geom->data.super_shape.nslices = SCHIFF_SUPER_SHAPE_DEFAULT.nslices; + } + geom->type = SCHIFF_SUPER_SHAPE; + return RES_OK; +} + +static res_T parse_yaml_geom_distrib (const char* filename, yaml_document_t* doc, @@ -899,6 +1070,8 @@ parse_yaml_geom_distrib 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); + } else if(!strcmp((char*)key->data.scalar.value, "super_shape")) { + res = parse_yaml_super_shape(filename, doc, val, geom, proba); } else { log_err(filename, key, "unknown distribution `%s'.\n", key->data.scalar.value);