From 1b24794baaf519d49f7431e0bc66418a9f437f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Thu, 6 Dec 2018 22:30:34 +0000 Subject: [PATCH] Refactoring lattice generator API (dimensionality generalisation) Former-commit-id: 3eb6623ed298bf1e2a458d15c237e83b3b3cf70d --- qpms/latticegens.c | 304 +++++++++++++++++++++------------------ qpms/lattices.h | 118 +++++++++++---- tests/test_latticegens.c | 26 ++-- 3 files changed, 271 insertions(+), 177 deletions(-) diff --git a/qpms/latticegens.c b/qpms/latticegens.c index bda1136..1e145b1 100644 --- a/qpms/latticegens.c +++ b/qpms/latticegens.c @@ -6,56 +6,80 @@ // const PGenSphReturnData PGenSphDoneVal = {PGEN_DONE, {0,0,0}}; // defined already in lattices.h +// const PGenCart3ReturnData PGenCart3DoneVal = {PGEN_DONE, {0,0,0}}; // defined already in lattices.h // General structure of a generator implementation looks like this: #if 0 -//==== PGenSph_NAME ==== +//==== PGen_NAME ==== -extern const PGenSphClassInfo PGenSph_NAME; // forward declaration needed by constructor (may be placed in header file instead) +extern const PGenClassInfo PGen_NAME; // forward declaration needed by constructor (may be placed in header file instead) // Internal state structure -typedef struct PGenSph_NAME_StateData { +typedef struct PGen_NAME_StateData { ... -} PGenSph_NAME_StateData; +} PGen_NAME_StateData; // Constructor -PGenSph PGenSph_NAME_new(...) { - g->stateData = malloc(sizeof(PGenSph_NAME_StateData)); +PGenSph PGen_NAME_new(...) { + g->stateData = malloc(sizeof(PGen_NAME_StateData)); ... - PGenSph g = {&PGenSph_NAME, (void *) stateData}; + PGenSph g = {&PGen_NAME, (void *) stateData}; return g; } // Dectructor -void PGenSph_NAME_dectructor(PGenSph *g) { +void PGen_NAME_dectructor(PGen *g) { ... free(g->stateData); g->stateData = NULL; } -// Extractor -PGenSphReturnData PGenSph_NAME_next(PGenSph *g) { +// Extractor, spherical coordinate output +PGenSphReturnData PGen_NAME_next_sph(PGen *g) { if (g->stateData == NULL) // already destroyed return PGenSphDoneVal; else { - PGenSph_NAME_StateData *s = (PGenSph_NAME_StateData *) g->stateData; + PGen_NAME_StateData *s = (PGen_NAME_StateData *) g->stateData; if (... /* there are still points to be generated */) { ... PGenSphReturnData retval = {.../*flags*/, .../*thePoint*/}; return retval; } else { - PGenSph_destroy(g); + PGen_destroy(g); return PGenSphDoneVal; } } } +// Extractor, 3D cartesian coordinate output +PGenCart3ReturnData PGen_NAME_next_cart3(PGen *g) { + if (g->stateData == NULL) // already destroyed + return PGenCart3DoneVal; + else { + PGen_NAME_StateData *s = (PGen_NAME_StateData *) g->stateData; + if (... /* there are still points to be generated */) { + ... + PGenCart3ReturnData retval = {.../*flags*/, .../*thePoint*/}; + return retval; + } else { + PGen_destroy(g); + return PGenCart3DoneVal; + } + } +} + // Class metadata structure; TODO maybe this can rather be done by macro. -const PGenSphClassInfo PGenSph_NAME = { - "PGenSph_NAME", - PGenSph_NAME_next, - PGenSph_NAME_destructor +const PGenClassInfo PGen_NAME = { + "PGen_NAME", + ?, //dimensionality + // some of the _next_... fun pointers can be NULL + PGen_NAME_next_z, + PGen_NAME_next_pol, + PGen_NAME_next_sph, + PGen_NAME_next_cart2, + PGen_NAME_next_cart3, + PGen_NAME_destructor }; #endif // 0 @@ -64,79 +88,102 @@ const PGenSphClassInfo PGenSph_NAME = { //==== PGenSph_FromPoint2DArray ==== // Internal state structure -typedef struct PGenSph_FromPoint2DArray_StateData { +typedef struct PGen_FromPoint2DArray_StateData { const point2d *base; size_t len; size_t currentIndex; -}PGenSph_FromPoint2DArray_StateData; +}PGen_FromPoint2DArray_StateData; // Constructor -PGenSph PGenSph_FromPoint2DArray_new(const point2d *points, size_t len) { - PGenSph_FromPoint2DArray_StateData *stateData = malloc(sizeof(PGenSph_FromPoint2DArray_StateData)); +PGen PGen_FromPoint2DArray_new(const point2d *points, size_t len) { + PGen_FromPoint2DArray_StateData *stateData = malloc(sizeof(PGen_FromPoint2DArray_StateData)); stateData->base = points; stateData->len = len; stateData->currentIndex = 0; - PGenSph g = {&PGenSph_FromPoint2DArray, (void *) stateData}; + PGen g = {&PGen_FromPoint2DArray, (void *) stateData}; return g; } // Destructor -void PGenSph_FromPoint2DArray_destructor(PGenSph *g) { +void PGen_FromPoint2DArray_destructor(PGen *g) { free(g->stateData); g->stateData = NULL; } -// Extractor -PGenSphReturnData PGenSph_FromPoint2DArray_next(PGenSph *g) { +// Extractor, 2D cartesian (native) +PGenCart2ReturnData PGen_FromPoint2DArray_next_cart2(PGen *g) { + if (g->stateData == NULL) // already destroyed + return PGenCart2DoneVal; + else { + PGen_FromPoint2DArray_StateData *s = (PGen_FromPoint2DArray_StateData *) g->stateData; + if (s->currentIndex < s->len) { + cart2_t thePoint = s->base[s->currentIndex]; + ++(s->currentIndex); + PGenCart2ReturnData retval = {(PGEN_AT_XY | PGEN_NEWR), thePoint}; + return retval; + } else { + PGen_destroy(g); + return PGenCart2DoneVal; + } + } +} + +// Extractor, spherical +PGenSphReturnData PGen_FromPoint2DArray_next_sph(PGen *g) { if (g->stateData == NULL) // already destroyed return PGenSphDoneVal; else { - PGenSph_FromPoint2DArray_StateData *s = (PGenSph_FromPoint2DArray_StateData *) g->stateData; + PGen_FromPoint2DArray_StateData *s = (PGen_FromPoint2DArray_StateData *) g->stateData; if (s->currentIndex < s->len) { sph_t thePoint = cart22sph(s->base[s->currentIndex]); ++(s->currentIndex); PGenSphReturnData retval = {(PGEN_AT_XY | PGEN_NEWR), thePoint}; return retval; } else { - PGenSph_destroy(g); + PGen_destroy(g); return PGenSphDoneVal; } } } -const PGenSphClassInfo PGenSph_FromPoint2DArray = { - "PGenSph_FromPoint2DArray", - PGenSph_FromPoint2DArray_next, - PGenSph_FromPoint2DArray_destructor, +const PGenClassInfo PGen_FromPoint2DArray = { + "PGen_FromPoint2DArray", + 2, // dimensionality + NULL, + NULL,//PGen_FromPoint2DArray_next_pol, + PGen_FromPoint2DArray_next_sph, + PGen_FromPoint2DArray_next_cart2, + NULL,//PGen_FromPoint2DArray_next_cart3, + PGen_FromPoint2DArray_destructor, }; -//==== PGenSph_zAxis ==== +//==== PGen_1D ==== //equidistant points along the z-axis; -extern const PGenSphClassInfo PGenSph_zAxis; // forward declaration needed by constructor (may be placed in header file instead) +extern const PGenClassInfo PGen_1D; // forward declaration needed by constructor (may be placed in header file instead) /* // This had to go to the header file: -enum PGenSph_zAxis_incrementDirection{ - //PGENSPH_ZAXIS_POSITIVE_INC, // not implemented - //PGENSPH_ZAXIS_NEGATIVE_INC, // not implemented - PGENSPH_ZAXIS_INC_FROM_ORIGIN, - PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN +enum PGen_1D_incrementDirection{ + //PGEN1D_POSITIVE_INC, // not implemented + //PGEN1D_NEGATIVE_INC, // not implemented + PGEN1D_INC_FROM_ORIGIN, + PGEN1D_INC_TOWARDS_ORIGIN }; */ // Internal state structure -typedef struct PGenSph_zAxis_StateData { +typedef struct PGen_1D_StateData { long ptindex; //long stopindex; double minR, maxR; bool inc_minR, inc_maxR; double a; // lattice period double offset; // offset of the zeroth lattice point from origin (will be normalised to interval [-a/2,a/2] - enum PGenSph_zAxis_incrementDirection incdir; + enum PGen_1D_incrementDirection incdir; //bool skip_origin; -} PGenSph_zAxis_StateData; +} PGen_1D_StateData; static inline long ptindex_inc(long i) { if (i > 0) @@ -153,9 +200,9 @@ static inline long ptindex_dec(long i) { } // Constructor, specified by maximum and maximum absolute value -PGenSph PGenSph_zAxis_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, - PGenSph_zAxis_incrementDirection incdir) { - PGenSph_zAxis_StateData *s = malloc(sizeof(PGenSph_zAxis_StateData)); +PGen PGen_1D_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, + PGen_1D_incrementDirection incdir) { + PGen_1D_StateData *s = malloc(sizeof(PGen_1D_StateData)); s->minR = minR; s->maxR = maxR; s->inc_minR = inc_minR; @@ -169,12 +216,12 @@ PGenSph PGenSph_zAxis_new_minMaxR(double period, double offset, double minR, boo period *= -1; switch(s->incdir) { double curR; - case PGENSPH_ZAXIS_INC_FROM_ORIGIN: + case PGEN_1D_INC_FROM_ORIGIN: s->ptindex = floor(minR / fabs(period)); while ( (curR = fabs(s->offset + s->ptindex * period)) < minR || (!inc_minR && curR <= minR)) s->ptindex = ptindex_inc(s->ptindex); break; - case PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN: + case PGEN_1D_INC_TOWARDS_ORIGIN: s->ptindex = - ceil(maxR / fabs(period)); while ( (curR = fabs(s->offset + s->ptindex * period)) > maxR || (!inc_minR && curR >= maxR)) s->ptindex = ptindex_dec(s->ptindex); @@ -184,31 +231,66 @@ PGenSph PGenSph_zAxis_new_minMaxR(double period, double offset, double minR, boo } s->a = period; - PGenSph g = {&PGenSph_zAxis, (void *) s}; + PGen g = {&PGen_1D, (void *) s}; return g; } // Dectructor -void PGenSph_zAxis_destructor(PGenSph *g) { +void PGen_1D_destructor(PGen *g) { free(g->stateData); g->stateData = NULL; } -// Extractor -PGenSphReturnData PGenSph_zAxis_next(PGenSph *g) { +// Extractor 1D number +PGenZReturnData PGen_1D_next_z(PGen *g) { if (g->stateData == NULL) // already destroyed - return PGenSphDoneVal; - PGenSph_zAxis_StateData *s = (PGenSph_zAxis_StateData *) g->stateData; + return PGenZDoneVal; + PGen_1D_StateData *s = (PGen_1D_StateData *) g->stateData; const double zval = s->ptindex * s->a + s->offset; const double r = fabs(zval); bool theEnd = false; switch (s->incdir) { - case PGENSPH_ZAXIS_INC_FROM_ORIGIN: + case PGEN_1D_INC_FROM_ORIGIN: if (r < s->maxR || (s->inc_maxR && r == s->maxR)) s->ptindex = ptindex_inc(s->ptindex); else theEnd = true; break; - case PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN: + case PGEN_1D_INC_TOWARDS_ORIGIN: + if (r > s->minR || (s->inc_minR && r == s->minR)) { + if (s->ptindex == 0) // handle "underflow" + s->minR = INFINITY; + else + s->ptindex = ptindex_dec(s->ptindex); + } else theEnd = true; + break; + default: + abort(); // invalid value + } + if (!theEnd) { + const PGenZReturnData retval = {PGEN_NOTDONE | PGEN_NEWR | PGEN_AT_Z, + zval}; + return retval; + } else { + PGen_destroy(g); + return PGenZDoneVal; + } +} + +// Extractor spherical coordinates // TODO remove/simplify +PGenSphReturnData PGen_1D_next_sph(PGen *g) { + if (g->stateData == NULL) // already destroyed + return PGenSphDoneVal; + PGen_1D_StateData *s = (PGen_1D_StateData *) g->stateData; + const double zval = s->ptindex * s->a + s->offset; + const double r = fabs(zval); + bool theEnd = false; + switch (s->incdir) { + case PGEN_1D_INC_FROM_ORIGIN: + if (r < s->maxR || (s->inc_maxR && r == s->maxR)) + s->ptindex = ptindex_inc(s->ptindex); + else theEnd = true; + break; + case PGEN_1D_INC_TOWARDS_ORIGIN: if (r > s->minR || (s->inc_minR && r == s->minR)) { if (s->ptindex == 0) // handle "underflow" s->minR = INFINITY; @@ -224,133 +306,81 @@ PGenSphReturnData PGenSph_zAxis_next(PGenSph *g) { {r, zval >= 0 ? 0 : M_PI, 0}}; return retval; } else { - PGenSph_destroy(g); + PGen_destroy(g); return PGenSphDoneVal; } } // Class metadata structure; TODO maybe this can rather be done by macro. -const PGenSphClassInfo PGenSph_zAxis = { - "PGenSph_zAxis", - PGenSph_zAxis_next, - PGenSph_zAxis_destructor +const PGenClassInfo PGen_1D = { + "PGen_1D", + 1, // dimensionality + PGen_1D_next_z, + NULL,//PGen_1D_next_pol, + PGen_1D_next_sph, + NULL,//PGen_1D_next_cart2, + NULL,//PGen_1D_next_cart3, + PGen_1D_destructor }; #if 0 -//==== PGenSph_xyWeb ==== +//==== PGen_xyWeb ==== // 2D lattice generator in the "spiderweb" style, generated in the "perimetre" order, // not strictly ordered (or limited) by distance from origin. // The minR and maxR here refer to the TODO WWHAT -extern const PGenSphClassInfo PGenSph_xyWeb; // forward declaration needed by constructor (may be placed in header file instead) +extern const PGenClassInfo PGen_xyWeb; // forward declaration needed by constructor (may be placed in header file instead) // Internal state structure -typedef struct PGenSph_xyWeb_StateData { +typedef struct PGen_xyWeb_StateData { long i, j; - //long stopindex; + unsigned short phase; // 0 to 5 + long layer; + double layer_min_height; // this * layer is what minR and maxR are compared to double minR, maxR; bool inc_minR, inc_maxR; cart2_t b1, b2; // lattice vectors cart2_t offset; // offset of the zeroth lattice point from origin (will be normalised to the WS cell) -} PGenSph_xyWeb_StateData; +} PGen_xyWeb_StateData; // Constructor -PGenSph PGenSph_xyWeb_new(...) { - g->stateData = malloc(sizeof(PGenSph_xyWeb_StateData)); +PGen PGen_xyWeb_new(...) { + g->stateData = malloc(sizeof(PGen_xyWeb_StateData)); ... - PGenSph g = {&PGenSph_xyWeb, (void *) stateData}; + PGen g = {&PGen_xyWeb, (void *) stateData}; return g; } // Dectructor -void PGenSph_xyWeb_dectructor(PGenSph *g) { +void PGen_xyWeb_dectructor(PGen *g) { ... free(g->stateData); g->stateData = NULL; } -// Extractor -PGenSphReturnData PGenSph_xyWeb_next(PGenSph *g) { +// Extractor (2D cartesian, native) +PGenCart2ReturnData PGen_xyWeb_next_cart2(PGen *g) { if (g->stateData == NULL) // already destroyed - return PGenSphDoneVal; + return PGenDoneVal; else { - PGenSph_xyWeb_StateData *s = (PGenSph_xyWeb_StateData *) g->stateData; + PGen_xyWeb_StateData *s = (PGen_xyWeb_StateData *) g->stateData; if (... /* there are still points to be generated */) { ... - PGenSphReturnData retval = {.../*flags*/, .../*thePoint*/}; + PGenReturnData retval = {.../*flags*/, .../*thePoint*/}; return retval; } else { - PGenSph_destroy(g); - return PGenSphDoneVal; + PGen_destroy(g); + return PGenDoneVal; } } } // Class metadata structure; TODO maybe this can rather be done by macro. -const PGenSphClassInfo PGenSph_xyWeb = { - "PGenSph_xyWeb", - PGenSph_xyWeb_next, - PGenSph_xyWeb_destructor +const PGenClassInfo PGen_xyWeb = { + "PGen_xyWeb", + PGen_xyWeb_next, + PGen_xyWeb_destructor }; #endif // 0 - - -#if 0 -//==== PGenSph_xyPlane ==== //TODO - -extern const PGenSphClassInfo PGenSph_xyPlane; // forward declaration needed by constructor (may be placed in header file instead) - -// Internal state structure -typedef struct PGenSph_xyPlane_StateData { - long i, j; - //long stopindex; - double minR, maxR; - bool inc_minR, inc_maxR; - cart2_t b1, b2; // lattice vectors - cart2_t offset; // offset of the zeroth lattice point from origin (will be normalised to the WS cell) -} PGenSph_xyPlane_StateData; - -// Constructor -PGenSph PGenSph_xyPlane_new(...) { - g->stateData = malloc(sizeof(PGenSph_xyPlane_StateData)); - ... - PGenSph g = {&PGenSph_xyPlane, (void *) stateData}; - return g; -} - -// Dectructor -void PGenSph_xyPlane_dectructor(PGenSph *g) { - ... - free(g->stateData); - g->stateData = NULL; -} - -// Extractor -PGenSphReturnData PGenSph_xyPlane_next(PGenSph *g) { - if (g->stateData == NULL) // already destroyed - return PGenSphDoneVal; - else { - PGenSph_xyPlane_StateData *s = (PGenSph_xyPlane_StateData *) g->stateData; - if (... /* there are still points to be generated */) { - ... - PGenSphReturnData retval = {.../*flags*/, .../*thePoint*/}; - return retval; - } else { - PGenSph_destroy(g); - return PGenSphDoneVal; - } - } -} - -// Class metadata structure; TODO maybe this can rather be done by macro. -const PGenSphClassInfo PGenSph_xyPlane = { - "PGenSph_xyPlane", - PGenSph_xyPlane_next, - PGenSph_xyPlane_destructor -}; - -#endif // 0 - - diff --git a/qpms/lattices.h b/qpms/lattices.h index 266ae75..5dfc579 100644 --- a/qpms/lattices.h +++ b/qpms/lattices.h @@ -57,15 +57,15 @@ static inline point2d point2d_fromxy(const double x, const double y) { /* - * GENERIC LATTICE POINT GENERATOR TYPE PGenSph + * GENERIC LATTICE POINT GENERATOR TYPE PGen * ============================================ * * A bit of OOP-in-C brainfuck here. * * The basic principle of operation is following: - * Instead of a list (array) of points, an initialized PGenSph object + * Instead of a list (array) of points, an initialized PGen object * is passed to a function that does something over a set of points. - * Each time PGenSph-type object is "called", it returns PGenSphReturnData, + * Each time PGen-type object is "called", it returns PGenReturnData, * which contains a point in spherical coordinates (sph_t) and some metadata. * * After the last generated point, the generator frees all internal memory @@ -73,15 +73,15 @@ static inline point2d point2d_fromxy(const double x, const double y) { * shall be considered invalid data). * The caller can also decide not to use the rest and end getting the points * even when the PGEN_NOTDONE was set in the last returned data. - * In such case, the caller shall call PGenSph_destroy() manually. + * In such case, the caller shall call PGen_destroy() manually. * * MEMORY MANAGEMENT POLICY * ------------------------ - * The basic PGenSph structure shall be allocated on stack (it's only two pointers), + * The basic PGen structure shall be allocated on stack (it's only two pointers), * everything internal goes on heap. */ -struct PGenSph; // full definition below +struct PGen; // full definition below typedef enum PGenPointFlags { PGEN_NOTDONE = 2, // The most important flag: when this is not set, the interation ended – other data returned should be considered nonsense and at this point, the generator should have de-allocated all internal memory. @@ -91,56 +91,120 @@ typedef enum PGenPointFlags { PGEN_DONE = 0, // convenience value, not an actual flag } PGenPointFlags; +typedef struct PGenZReturnData { + PGenPointFlags flags; // metatada + double point_z; +} PGenZReturnData; + +typedef struct PGenPolReturnData { + PGenPointFlags flags; // metatada + pol_t point_pol; +} PGenPolReturnData; + typedef struct PGenSphReturnData { PGenPointFlags flags; // metatada sph_t point_sph; // the actual point data } PGenSphReturnData; -static const PGenSphReturnData PGenSphDoneVal = {PGEN_DONE, {0,0,0}}; // convenience constant for use in the exctractor implementations +typedef struct PGenCart2ReturnData { + PGenPointFlags flags; // metatada + cart2_t point_cart2; // the actual point data +} PGenCart2ReturnData; + +typedef struct PGenCart3ReturnData { + PGenPointFlags flags; // metatada + cart3_t point_cart3; // the actual point data +} PGenCart3ReturnData; + +// convenience constants for use in the extractor implementations +static const PGenZReturnData PGenZDoneVal = {PGEN_DONE, 0}; +static const PGenPolReturnData PGenPolDoneVal = {PGEN_DONE, {0,0}}; +static const PGenSphReturnData PGenSphDoneVal = {PGEN_DONE, {0,0,0}}; +static const PGenCart2ReturnData PGenCart2DoneVal = {PGEN_DONE, {0,0}}; +static const PGenCart3ReturnData PGenCart3DoneVal = {PGEN_DONE, {0,0,0}}; typedef struct PGenSphClassInfo { // static PGenSph info char * const name; // mainly for debugging purposes - PGenSphReturnData (*next)(struct PGenSph *); // This contains the actual generator procedure (TODO shouldn't I rather point to stateData?) - void (*destructor)(struct PGenSph *); // Destructor to be called by next() at iteration end, or by the caller if ending the generation prematurely -} PGenSphClassInfo; + int dimensionality; // lower-dimensional can be converted to higher-D, not vice versa + // TODO info about native coordinate system + PGenZReturnData (*next_z)(struct PGen *); + PGenPolReturnData (*next_pol)(struct PGen *); // This contains the actual generator procedure (TODO shouldn't I rather point to stateData?) + PGenSphReturnData (*next_sph)(struct PGen *); + PGenCart2ReturnData (*next_cart2)(struct PGen *); + PGenCart3ReturnData (*next_cart3)(struct PGen *); + void (*destructor)(struct PGen *); // Destructor to be called by next() at iteration end, or by the caller if ending the generation prematurely +} PGenClassInfo; // TOP DATA STRUCTURE DEFINITION HERE -typedef struct PGenSph { - const PGenSphClassInfo * /*const*/ c; +typedef struct PGen { + const PGenClassInfo * /*const*/ c; void *stateData; // shall be NULL if invalid (destroyed) -} PGenSph; +} PGen; -static inline void PGenSph_destroy(PGenSph *g) { +static inline void PGen_destroy(PGen *g) { g->c->destructor(g); assert(g->stateData == NULL); // this should be done by the destructor } -static inline PGenSphReturnData PGenSph_next(PGenSph *g) { +static inline PGenSphReturnData PGen_next_sph(PGen *g) { // TODO maybe some asserts around here - return g->c->next(g); + if (g->c->next_sph) + return g->c->next_sph(g); + else abort(); // the current point generator does not support this type of output +} + +static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) { + // TODO maybe some asserts around here + if (g->c->next_cart3) + return g->c->next_cart3(g); + else abort(); // the current point generator does not support this type of output +} + +static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) { + // TODO maybe some asserts around here + if (g->c->next_cart2) + return g->c->next_cart2(g); + else abort(); // the current point generator does not support this type of output } static inline bool PGenSph_notDone(PGenSphReturnData data) { return data.flags & PGEN_NOTDONE ? true : false; } +static inline bool PGenCart3_notDone(PGenCart3ReturnData data) { + return data.flags & PGEN_NOTDONE ? true : false; +} + +static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData sphdata){ + PGenCart3ReturnData c3data; + c3data.flags = sphdata.flags; + c3data.point_cart3 = sph2cart(sphdata.point_sph); + return c3data; +} + +static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData c){ + PGenSphReturnData s; + s.flags = c.flags; + s.point_sph = cart2sph(c.point_cart3); + return s; +} /* * Some basic lattice generators implementing the abstract interface above (implemented in latticegens.c). */ // This one simply iterates over an existing array of Point2d -extern const PGenSphClassInfo PGenSph_FromPoint2DArray; // TODO Do I even need this to be declared here? -PGenSph PGenSph_FromPoints2DArray_new(const point2d *points, size_t len); +extern const PGenClassInfo PGen_FromPoint2DArray; // TODO Do I even need this to be declared here? +PGen PGen_FromPoints2DArray_new(const point2d *points, size_t len); -extern const PGenSphClassInfo PGenSph_zAxis; -typedef enum PGenSph_zAxis_incrementDirection{ - //PGENSPH_ZAXIS_POSITIVE_INC, // not implemented - //PGENSPH_ZAXIS_NEGATIVE_INC, // not implemented - PGENSPH_ZAXIS_INC_FROM_ORIGIN, - PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN -} PGenSph_zAxis_incrementDirection; -PGenSph PGenSph_zAxis_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, - PGenSph_zAxis_incrementDirection incdir); +extern const PGenClassInfo PGen_1D; +typedef enum PGen_1D_incrementDirection{ + //PGEN_1D_POSITIVE_INC, // not implemented + //PGEN_1D_NEGATIVE_INC, // not implemented + PGEN_1D_INC_FROM_ORIGIN, + PGEN_1D_INC_TOWARDS_ORIGIN +} PGen_1D_incrementDirection; +PGen PGen_1D_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, + PGen_1D_incrementDirection incdir); /* diff --git a/tests/test_latticegens.c b/tests/test_latticegens.c index a7d1d82..e550be9 100644 --- a/tests/test_latticegens.c +++ b/tests/test_latticegens.c @@ -10,10 +10,10 @@ void print_PGenSphReturnData(PGenSphReturnData d) { s.r, s.theta / M_PI, s.phi / M_PI, c.x, c.y, c.z, d.flags); } -void dump_PGenSph(PGenSph *g) { +void dump_PGenSph(PGen *g) { PGenSphReturnData d; do { - d = PGenSph_next(g); + d = PGen_next_sph(g); print_PGenSphReturnData(d); } while (d.flags & PGEN_NOTDONE); } @@ -21,26 +21,26 @@ void dump_PGenSph(PGenSph *g) { #define DO_AND_PRINT(label, s) printf(#label ":\n" #s "\n"); s ; int main(int argc, char **argv) { - PGenSph g; - DO_AND_PRINT(test1a, g = PGenSph_zAxis_new_minMaxR(0.2, 0.14, 5, true, 7, true, PGENSPH_ZAXIS_INC_FROM_ORIGIN)) + PGen g; + DO_AND_PRINT(test1a, g = PGen_1D_new_minMaxR(0.2, 0.14, 5, true, 7, true, PGEN_1D_INC_FROM_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test1b, g = PGenSph_zAxis_new_minMaxR(0.2, 0.14, 5, true, 7, true, PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN)) + DO_AND_PRINT(test1b, g = PGen_1D_new_minMaxR(0.2, 0.14, 5, true, 7, true, PGEN_1D_INC_TOWARDS_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test2a, g = PGenSph_zAxis_new_minMaxR(0.2, 0.05, 5.05, true, 7.05, true, PGENSPH_ZAXIS_INC_FROM_ORIGIN)) + DO_AND_PRINT(test2a, g = PGen_1D_new_minMaxR(0.2, 0.05, 5.05, true, 7.05, true, PGEN_1D_INC_FROM_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test2b, g = PGenSph_zAxis_new_minMaxR(0.2, 0.05, 5.05, true, 7.05, true, PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN)) + DO_AND_PRINT(test2b, g = PGen_1D_new_minMaxR(0.2, 0.05, 5.05, true, 7.05, true, PGEN_1D_INC_TOWARDS_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test3a, g = PGenSph_zAxis_new_minMaxR(0.2, 0.05, 5.05, false, 7.05, false, PGENSPH_ZAXIS_INC_FROM_ORIGIN)) + DO_AND_PRINT(test3a, g = PGen_1D_new_minMaxR(0.2, 0.05, 5.05, false, 7.05, false, PGEN_1D_INC_FROM_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test3b, g = PGenSph_zAxis_new_minMaxR(0.2, 0.05, 5.05, false, 7.05, false, PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN)) + DO_AND_PRINT(test3b, g = PGen_1D_new_minMaxR(0.2, 0.05, 5.05, false, 7.05, false, PGEN_1D_INC_TOWARDS_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test4a, g = PGenSph_zAxis_new_minMaxR(0.2, 0.0, 0, false, 1, false, PGENSPH_ZAXIS_INC_FROM_ORIGIN)) + DO_AND_PRINT(test4a, g = PGen_1D_new_minMaxR(0.2, 0.0, 0, false, 1, false, PGEN_1D_INC_FROM_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test4b, g = PGenSph_zAxis_new_minMaxR(0.2, 0.0, 0, false, 1, false, PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN)) + DO_AND_PRINT(test4b, g = PGen_1D_new_minMaxR(0.2, 0.0, 0, false, 1, false, PGEN_1D_INC_TOWARDS_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test5a, g = PGenSph_zAxis_new_minMaxR(0.2, 0.0, 0, true, 1, true, PGENSPH_ZAXIS_INC_FROM_ORIGIN)) + DO_AND_PRINT(test5a, g = PGen_1D_new_minMaxR(0.2, 0.0, 0, true, 1, true, PGEN_1D_INC_FROM_ORIGIN)) dump_PGenSph(&g); - DO_AND_PRINT(test5b, g = PGenSph_zAxis_new_minMaxR(0.2, 0.0, 0, true, 1, true, PGENSPH_ZAXIS_INC_TOWARDS_ORIGIN)) + DO_AND_PRINT(test5b, g = PGen_1D_new_minMaxR(0.2, 0.0, 0, true, 1, true, PGEN_1D_INC_TOWARDS_ORIGIN)) dump_PGenSph(&g);