Doxygen docs for the lattice generators.

Former-commit-id: eb3a5149a7f3fac70e5bf882642690ef31e1d6e4
This commit is contained in:
Marek Nečada 2019-06-25 20:05:31 +03:00
parent c214ba809b
commit 5a5f124f6b
2 changed files with 150 additions and 41 deletions

View File

@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation. # included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_STATIC = NO EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO # locally in source files will be included in the documentation. If set to NO

View File

@ -1,3 +1,7 @@
/*! \file lattices.h
* \brief Lattice point generators and lattice vector analysis / transformation.
*
*/
#ifndef LATTICES_H #ifndef LATTICES_H
#define LATTICES_H #define LATTICES_H
@ -53,20 +57,18 @@ static inline point2d point2d_fromxy(const double x, const double y) {
return p; return p;
} }
/// Generic lattice point generator type.
/**
/*
* GENERIC LATTICE POINT GENERATOR TYPE PGen
* ============================================
*
* A bit of OOP-in-C brainfuck here. * A bit of OOP-in-C brainfuck here.
* *
* The basic principle of operation is following: * The basic principle of operation is following:
* Instead of a list (array) of points, an initialized PGen 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. * is passed to a function that does something over a set of points.
* Each time PGen-type object is "called", it returns PGenReturnData, * Each time PGen-type object is "called" (more specifically, one of
* which contains a point in spherical coordinates (sph_t) and some metadata. * the "methods" specified in the PGenClassInfo structure in @ref c,
* it returns PGenReturnData
* which contains a point in given coordinates (depending on the generator
* class) and some metadata.
* *
* After the last generated point, the generator frees all internal memory * After the last generated point, the generator frees all internal memory
* and returns PGenSphReturnData with PGEN_NOTDONE flag unset (the rest * and returns PGenSphReturnData with PGEN_NOTDONE flag unset (the rest
@ -75,20 +77,52 @@ static inline point2d point2d_fromxy(const double x, const double y) {
* even when the PGEN_NOTDONE was set in the last returned data. * even when the PGEN_NOTDONE was set in the last returned data.
* In such case, the caller shall call PGen_destroy() manually. * In such case, the caller shall call PGen_destroy() manually.
* *
* MEMORY MANAGEMENT POLICY * Methods
* -------
*
* The standard wrapper "methods" to generate a single point in a given
* coordinate system are
*
* * PGen_next_z(),
* * PGen_next_cart2(),
* * PGen_next_cart3(),
* * PGen_next_pol(),
* * PGen_next_sph().
*
* Memory management policy
* ------------------------ * ------------------------
*
* The basic PGen 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. * everything internal goes on heap.
*/ */
typedef struct PGen {
struct PGen; // full definition below /// Pointer to the "class" metadata defining the behaviour of the generator.
const struct PGenClassInfo * /*const*/ c;
/// Pointer to internal state data; shall be NULL if invalid (destroyed);
void *stateData;
} PGen;
typedef enum PGenPointFlags { 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. /** The most important flag: when this is not set, the
PGEN_NEWR = 1, // The r-coordinate is different than in the previous generated point (so radial parts of the calculation have to be redone); * interation ended other data returned should be
PGEN_AT_Z = 4, // This is set if we are at the z-axis (theta is either 0 or M_PI) * considered nonsense and at this point, the generator
PGEN_AT_XY = 8, // This is set if we are at the xy-plane (theta is M_PI2) * should have de-allocated all internal memory.
PGEN_DONE = 0, // convenience value, not an actual flag */
PGEN_NOTDONE = 2,
/** Set if the r-coordinate is different than in the
* previous generated point (so radial parts of the
* calculation have to be redone).
*/
PGEN_NEWR = 1,
/** Set if the r-coordinate has changed between the
* first and the last point generated in the current
* call.
* Only for the bulk generator methods.
*/
PGEN_RCHANGED = 16,
PGEN_AT_Z = 4, ///< Set if the point(s) lie(s) at the z-axis (theta is either 0 or M_PI).
PGEN_AT_XY = 8, ///< Set if the point(s) lie(s) in the xy-plane (theta is M_PI2).
PGEN_DONE = 0, ///< Convenience identifier, not an actual flag.
PGEN_COORDS_CART1 = QPMS_COORDS_CART1, PGEN_COORDS_CART1 = QPMS_COORDS_CART1,
PGEN_COORDS_CART2 = QPMS_COORDS_CART2, PGEN_COORDS_CART2 = QPMS_COORDS_CART2,
PGEN_COORDS_CART3 = QPMS_COORDS_CART3, PGEN_COORDS_CART3 = QPMS_COORDS_CART3,
@ -98,34 +132,48 @@ typedef enum PGenPointFlags {
PGEN_COORDS_CART2 | PGEN_COORDS_CART3 | PGEN_COORDS_POL | PGEN_COORDS_SPH PGEN_COORDS_CART2 | PGEN_COORDS_CART3 | PGEN_COORDS_POL | PGEN_COORDS_SPH
} PGenPointFlags; } PGenPointFlags;
typedef struct PGenReturnData { // Generic return type that might contain point represented in any of the supported coordinate systems
PGenPointFlags flags; // metadata; must contain info about the coordinate system /// Metadata generated by the fetch*() methods from PGenClassInfo
anycoord_point_t point; typedef struct PGenReturnDataBulk {
/// Flags describing the returned data.
PGenPointFlags flags;
size_t generated; ///< Number of points really generated
} PGenReturnDataBulk;
/// Generic PGen return type that might contain point represented in any of the supported coordinate systems.
typedef struct PGenReturnData {
PGenPointFlags flags; ///< Metadata, must contain valid coordinate system defining flags.
anycoord_point_t point; ///< Generated point in a coordinate system defined by flags.
} PGenReturnData; } PGenReturnData;
/// PGen single-point return data type (1D).
typedef struct PGenZReturnData { typedef struct PGenZReturnData {
PGenPointFlags flags; // metadata PGenPointFlags flags; ///< Medatata.
double point_z; double point_z; ///< Generated point on a real axis.
} PGenZReturnData; } PGenZReturnData;
/// PGen single-point return data type (2D, polar coordinates).
typedef struct PGenPolReturnData { typedef struct PGenPolReturnData {
PGenPointFlags flags; // metadata PGenPointFlags flags; ///< Metadata.
pol_t point_pol; pol_t point_pol; ///< Generated point in polar coordinates.
} PGenPolReturnData; } PGenPolReturnData;
/// PGen single-point return data type (3D, spherical coordinates).
typedef struct PGenSphReturnData { typedef struct PGenSphReturnData {
PGenPointFlags flags; // metadata PGenPointFlags flags; ///< Metadata.
sph_t point_sph; // the actual point data sph_t point_sph; ///< Generated point in spherical coordinates.
} PGenSphReturnData; } PGenSphReturnData;
/// PGen single-point return data type (2D, cartesian coordinates).
typedef struct PGenCart2ReturnData { typedef struct PGenCart2ReturnData {
PGenPointFlags flags; // metadata PGenPointFlags flags; ///< Metadata.
cart2_t point_cart2; // the actual point data cart2_t point_cart2; ///< Generated point in cartesian coordinates.
} PGenCart2ReturnData; } PGenCart2ReturnData;
/// PGen single-point return data type (3D, cartesian coordinates).
typedef struct PGenCart3ReturnData { typedef struct PGenCart3ReturnData {
PGenPointFlags flags; // metadata PGenPointFlags flags; ///< Metadata.
cart3_t point_cart3; // the actual point data cart3_t point_cart3; ///< Generated point in cartesian coordinates.
} PGenCart3ReturnData; } PGenCart3ReturnData;
// convenience constants for use in the extractor implementations // convenience constants for use in the extractor implementations
@ -135,36 +183,74 @@ static const PGenSphReturnData PGenSphDoneVal = {PGEN_DONE, {0,0,0}};
static const PGenCart2ReturnData PGenCart2DoneVal = {PGEN_DONE, {0,0}}; static const PGenCart2ReturnData PGenCart2DoneVal = {PGEN_DONE, {0,0}};
static const PGenCart3ReturnData PGenCart3DoneVal = {PGEN_DONE, {0,0,0}}; static const PGenCart3ReturnData PGenCart3DoneVal = {PGEN_DONE, {0,0,0}};
/// PGen class metadata.
/**
* This structure determines the behaviour of the PGen
* instance pointing to it.
*
* For generating a single point, use the next() method.
* For generating up to N points in a single call, use the
* fetch() method.
*
* Usually, each generator uses internally one "native" coordinate
* system (in lattice generators, this will typically be nD
* cartesian coordinates) in which the next() method gives its result.
*
* One does not have to explicitly implement every single method.
*
* TODO doc about the default transformations etc.
*/
typedef struct PGenClassInfo { // static PGenSph info typedef struct PGenClassInfo { // static PGenSph info
char * const name; // mainly for debugging purposes char * const name; // mainly for debugging purposes
int dimensionality; // lower-dimensional can be converted to higher-D, not vice versa; bit redundant with the following, whatever. int dimensionality; // lower-dimensional can be converted to higher-D, not vice versa; bit redundant with the following, whatever.
PGenPointFlags native_point_flags; // info about native coordinate system /// Info about the generator native coordinate system.
PGenPointFlags native_point_flags;
/// Generate a single point in the native coordinates.
PGenReturnData (*next)(struct PGen *); PGenReturnData (*next)(struct PGen *);
/// Generate a single 1D point.
PGenZReturnData (*next_z)(struct PGen *); PGenZReturnData (*next_z)(struct PGen *);
PGenPolReturnData (*next_pol)(struct PGen *); // This contains the actual generator procedure (TODO shouldn't I rather point to stateData?) /// Generate a single 2D point in polar coordinates.
PGenPolReturnData (*next_pol)(struct PGen *);
/// Generate a single 3D point in spherical coordinates.
PGenSphReturnData (*next_sph)(struct PGen *); PGenSphReturnData (*next_sph)(struct PGen *);
/// Generate a single 2D point in cartesian coordinates.
PGenCart2ReturnData (*next_cart2)(struct PGen *); PGenCart2ReturnData (*next_cart2)(struct PGen *);
/// Generate a single 3D point in cartesian coordinates.
PGenCart3ReturnData (*next_cart3)(struct PGen *); PGenCart3ReturnData (*next_cart3)(struct PGen *);
#if 0 // must be implemented first.
/// Generate up to \a n points in the native coordinates.
PGenReturnDataBulk (*fetch)(struct PGen *, size_t, anycoord_point_t *);
/// Generate up to \a n 1D points.
PGenReturnDataBulk (*fetch_z)(struct PGen *, size_t, double *);
/// Generate up to \a n 2D points in polar coordinates.
PGenReturnDataBulk (*fetch_pol)(struct PGen *, size_t, pol_t *);
/// Generate up to \a n 3D points in spherical coordinates.
PGenReturnDataBulk (*fetch_sph)(struct PGen *, size_t, sph_t *);
/// Generate up to \a n 2D points in cartesian coordinates.
PGenReturnDataBulk (*fetch_cart2)(struct PGen *, size_t, cart2_t);
/// Generate up to \a n 3D points in cartesian coordinates.
PGenReturnDataBulk (*fetch_cart3)(struct PGen *, size_t, cart3_t);
#endif
void (*destructor)(struct PGen *); // Destructor to be called by next() at iteration end, or by the caller if ending the generation prematurely void (*destructor)(struct PGen *); // Destructor to be called by next() at iteration end, or by the caller if ending the generation prematurely
} PGenClassInfo; } PGenClassInfo;
// TOP DATA STRUCTURE DEFINITION HERE
typedef struct PGen {
const PGenClassInfo * /*const*/ c;
void *stateData; // shall be NULL if invalid (destroyed)
} PGen;
/// Deallocate and invalidate a PGen point generator.
static inline void PGen_destroy(PGen *g) { static inline void PGen_destroy(PGen *g) {
g->c->destructor(g); g->c->destructor(g);
assert(g->stateData == NULL); // this should be done by the destructor assert(g->stateData == NULL); // this should be done by the destructor
} }
/// Generate a point in a 1D real space.
static inline PGenZReturnData PGen_next_z(PGen *g) { static inline PGenZReturnData PGen_next_z(PGen *g) {
if (g->c->next_z) if (g->c->next_z)
return g->c->next_z(g); return g->c->next_z(g);
else abort(); else abort();
} }
/// Generate a point in a 3D real space (spherical coordinates).
static inline PGenSphReturnData PGen_next_sph(PGen *g) { static inline PGenSphReturnData PGen_next_sph(PGen *g) {
// TODO maybe some asserts around here // TODO maybe some asserts around here
if (g->c->next_sph) if (g->c->next_sph)
@ -172,6 +258,7 @@ static inline PGenSphReturnData PGen_next_sph(PGen *g) {
else abort(); // the current point generator does not support this type of output else abort(); // the current point generator does not support this type of output
} }
/// Generate a point in a 2D real space (polar coordinates).
static inline PGenPolReturnData PGen_next_pol(PGen *g) { static inline PGenPolReturnData PGen_next_pol(PGen *g) {
// TODO maybe some asserts around here // TODO maybe some asserts around here
if (g->c->next_pol) if (g->c->next_pol)
@ -179,6 +266,7 @@ static inline PGenPolReturnData PGen_next_pol(PGen *g) {
else abort(); // the current point generator does not support this type of output else abort(); // the current point generator does not support this type of output
} }
/// Generate a point in a 3D real space (cartesian coordinates).
static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) { static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) {
// TODO maybe some asserts around here // TODO maybe some asserts around here
if (g->c->next_cart3) if (g->c->next_cart3)
@ -186,6 +274,7 @@ static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) {
else abort(); // the current point generator does not support this type of output else abort(); // the current point generator does not support this type of output
} }
/// Ǧenerate a point in a 2D real space (cartesian coordinates).
static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) { static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) {
// TODO maybe some asserts around here // TODO maybe some asserts around here
if (g->c->next_cart2) if (g->c->next_cart2)
@ -193,6 +282,15 @@ static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) {
else abort(); // the current point generator does not support this type of output else abort(); // the current point generator does not support this type of output
} }
#if 0
/// Generate up to \a n points.
static inline PGenReturnDataBulk PGen_fetch(PGen *g, size_t n, anycoord_point_t *arr){
if (g->c->fetch)
return g->c->fetch(g, n, arr);
else abort();
}
#endif
static inline bool PGenSph_notDone(PGenSphReturnData data) { static inline bool PGenSph_notDone(PGenSphReturnData data) {
return data.flags & PGEN_NOTDONE ? true : false; return data.flags & PGEN_NOTDONE ? true : false;
} }
@ -200,6 +298,7 @@ static inline bool PGenCart3_notDone(PGenCart3ReturnData data) {
return data.flags & PGEN_NOTDONE ? true : false; return data.flags & PGEN_NOTDONE ? true : false;
} }
/// Standard PGen spherical coordinates -> 3d cartesian convertor.
static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData sphdata){ static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData sphdata){
PGenCart3ReturnData c3data; PGenCart3ReturnData c3data;
c3data.flags = sphdata.flags; c3data.flags = sphdata.flags;
@ -207,6 +306,7 @@ static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData
return c3data; return c3data;
} }
/// Standard PGen 3d cartesian -> spherical coordinates convertor.
static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData c){ static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData c){
PGenSphReturnData s; PGenSphReturnData s;
s.flags = c.flags; s.flags = c.flags;
@ -218,10 +318,12 @@ static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData
* Some basic lattice generators implementing the abstract interface above (implemented in latticegens.c). * Some basic lattice generators implementing the abstract interface above (implemented in latticegens.c).
*/ */
// This one simply iterates over an existing array of Point2d /// 2D point generator that simply iterates over an existing array of Point2d.
extern const PGenClassInfo PGen_FromPoint2DArray; // TODO Do I even need this to be declared here? extern const PGenClassInfo PGen_FromPoint2DArray; // TODO Do I even need this to be declared here?
/// PGen_FromPoint2DArray constructor.
PGen PGen_FromPoints2DArray_new(const point2d *points, size_t len); PGen PGen_FromPoints2DArray_new(const point2d *points, size_t len);
/// 1D equidistant point generator.
extern const PGenClassInfo PGen_1D; extern const PGenClassInfo PGen_1D;
typedef enum PGen_1D_incrementDirection{ typedef enum PGen_1D_incrementDirection{
//PGEN_1D_POSITIVE_INC, // not implemented //PGEN_1D_POSITIVE_INC, // not implemented
@ -229,8 +331,15 @@ typedef enum PGen_1D_incrementDirection{
PGEN_1D_INC_FROM_ORIGIN, PGEN_1D_INC_FROM_ORIGIN,
PGEN_1D_INC_TOWARDS_ORIGIN PGEN_1D_INC_TOWARDS_ORIGIN
} PGen_1D_incrementDirection; } PGen_1D_incrementDirection;
PGen PGen_1D_new_minMaxR(double period, double offset, double minR, bool inc_minR, double maxR, bool inc_maxR, /// PGen_1D point generator constructor.
PGen_1D_incrementDirection incdir); PGen PGen_1D_new_minMaxR(double period, ///< Distance between points.
double offset, ///< Lattice offset from zero.
double minR, ///< Lower bound of |z| of the generated points.
bool inc_minR, ///< Include also |z| == minR (if applicable).
double maxR, ///< Upper bound of |z| of the generated points.
bool inc_maxR, ///< Include also |z| == maxR if applicable.
PGen_1D_incrementDirection incdir ///< Order of generated points.
);
extern const PGenClassInfo PGen_xyWeb; extern const PGenClassInfo PGen_xyWeb;