Doxygen docs for the lattice generators.
Former-commit-id: eb3a5149a7f3fac70e5bf882642690ef31e1d6e4
This commit is contained in:
parent
c214ba809b
commit
5a5f124f6b
2
Doxyfile
2
Doxyfile
|
@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO
|
|||
# included in the documentation.
|
||||
# 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
|
||||
# locally in source files will be included in the documentation. If set to NO
|
||||
|
|
189
qpms/lattices.h
189
qpms/lattices.h
|
@ -1,3 +1,7 @@
|
|||
/*! \file lattices.h
|
||||
* \brief Lattice point generators and lattice vector analysis / transformation.
|
||||
*
|
||||
*/
|
||||
#ifndef LATTICES_H
|
||||
#define LATTICES_H
|
||||
|
||||
|
@ -53,20 +57,18 @@ static inline point2d point2d_fromxy(const double x, const double y) {
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GENERIC LATTICE POINT GENERATOR TYPE PGen
|
||||
* ============================================
|
||||
*
|
||||
/// Generic lattice point generator type.
|
||||
/**
|
||||
* A bit of OOP-in-C brainfuck here.
|
||||
*
|
||||
* The basic principle of operation is following:
|
||||
* 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 PGen-type object is "called", it returns PGenReturnData,
|
||||
* which contains a point in spherical coordinates (sph_t) and some metadata.
|
||||
* Each time PGen-type object is "called" (more specifically, one of
|
||||
* 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
|
||||
* 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.
|
||||
* 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),
|
||||
* everything internal goes on heap.
|
||||
*/
|
||||
|
||||
struct PGen; // full definition below
|
||||
typedef struct PGen {
|
||||
/// 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 {
|
||||
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.
|
||||
PGEN_NEWR = 1, // The r-coordinate is different than in the previous generated point (so radial parts of the calculation have to be redone);
|
||||
PGEN_AT_Z = 4, // This is set if we are at the z-axis (theta is either 0 or M_PI)
|
||||
PGEN_AT_XY = 8, // This is set if we are at the xy-plane (theta is M_PI2)
|
||||
PGEN_DONE = 0, // convenience value, not an actual flag
|
||||
/** 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.
|
||||
*/
|
||||
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_CART2 = QPMS_COORDS_CART2,
|
||||
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
|
||||
} 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
|
||||
anycoord_point_t point;
|
||||
|
||||
/// Metadata generated by the fetch*() methods from PGenClassInfo
|
||||
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;
|
||||
|
||||
/// PGen single-point return data type (1D).
|
||||
typedef struct PGenZReturnData {
|
||||
PGenPointFlags flags; // metadata
|
||||
double point_z;
|
||||
PGenPointFlags flags; ///< Medatata.
|
||||
double point_z; ///< Generated point on a real axis.
|
||||
} PGenZReturnData;
|
||||
|
||||
/// PGen single-point return data type (2D, polar coordinates).
|
||||
typedef struct PGenPolReturnData {
|
||||
PGenPointFlags flags; // metadata
|
||||
pol_t point_pol;
|
||||
PGenPointFlags flags; ///< Metadata.
|
||||
pol_t point_pol; ///< Generated point in polar coordinates.
|
||||
} PGenPolReturnData;
|
||||
|
||||
/// PGen single-point return data type (3D, spherical coordinates).
|
||||
typedef struct PGenSphReturnData {
|
||||
PGenPointFlags flags; // metadata
|
||||
sph_t point_sph; // the actual point data
|
||||
PGenPointFlags flags; ///< Metadata.
|
||||
sph_t point_sph; ///< Generated point in spherical coordinates.
|
||||
} PGenSphReturnData;
|
||||
|
||||
/// PGen single-point return data type (2D, cartesian coordinates).
|
||||
typedef struct PGenCart2ReturnData {
|
||||
PGenPointFlags flags; // metadata
|
||||
cart2_t point_cart2; // the actual point data
|
||||
PGenPointFlags flags; ///< Metadata.
|
||||
cart2_t point_cart2; ///< Generated point in cartesian coordinates.
|
||||
} PGenCart2ReturnData;
|
||||
|
||||
/// PGen single-point return data type (3D, cartesian coordinates).
|
||||
typedef struct PGenCart3ReturnData {
|
||||
PGenPointFlags flags; // metadata
|
||||
cart3_t point_cart3; // the actual point data
|
||||
PGenPointFlags flags; ///< Metadata.
|
||||
cart3_t point_cart3; ///< Generated point in cartesian coordinates.
|
||||
} PGenCart3ReturnData;
|
||||
|
||||
// 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 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
|
||||
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.
|
||||
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 *);
|
||||
/// Generate a single 1D point.
|
||||
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 *);
|
||||
/// Generate a single 2D point in cartesian coordinates.
|
||||
PGenCart2ReturnData (*next_cart2)(struct PGen *);
|
||||
/// Generate a single 3D point in cartesian coordinates.
|
||||
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
|
||||
} 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) {
|
||||
g->c->destructor(g);
|
||||
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) {
|
||||
if (g->c->next_z)
|
||||
return g->c->next_z(g);
|
||||
else abort();
|
||||
}
|
||||
|
||||
/// Generate a point in a 3D real space (spherical coordinates).
|
||||
static inline PGenSphReturnData PGen_next_sph(PGen *g) {
|
||||
// TODO maybe some asserts around here
|
||||
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
|
||||
}
|
||||
|
||||
/// Generate a point in a 2D real space (polar coordinates).
|
||||
static inline PGenPolReturnData PGen_next_pol(PGen *g) {
|
||||
// TODO maybe some asserts around here
|
||||
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
|
||||
}
|
||||
|
||||
/// Generate a point in a 3D real space (cartesian coordinates).
|
||||
static inline PGenCart3ReturnData PGen_next_cart3(PGen *g) {
|
||||
// TODO maybe some asserts around here
|
||||
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
|
||||
}
|
||||
|
||||
/// Ǧenerate a point in a 2D real space (cartesian coordinates).
|
||||
static inline PGenCart2ReturnData PGen_next_cart2(PGen *g) {
|
||||
// TODO maybe some asserts around here
|
||||
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
|
||||
}
|
||||
|
||||
#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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/// Standard PGen spherical coordinates -> 3d cartesian convertor.
|
||||
static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData sphdata){
|
||||
PGenCart3ReturnData c3data;
|
||||
c3data.flags = sphdata.flags;
|
||||
|
@ -207,6 +306,7 @@ static inline PGenCart3ReturnData PGenReturnDataConv_sph_cart3(PGenSphReturnData
|
|||
return c3data;
|
||||
}
|
||||
|
||||
/// Standard PGen 3d cartesian -> spherical coordinates convertor.
|
||||
static inline PGenSphReturnData PGenReturnDataConv_cart3_sph(PGenCart3ReturnData c){
|
||||
PGenSphReturnData s;
|
||||
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).
|
||||
*/
|
||||
|
||||
// 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?
|
||||
/// PGen_FromPoint2DArray constructor.
|
||||
PGen PGen_FromPoints2DArray_new(const point2d *points, size_t len);
|
||||
|
||||
/// 1D equidistant point generator.
|
||||
extern const PGenClassInfo PGen_1D;
|
||||
typedef enum PGen_1D_incrementDirection{
|
||||
//PGEN_1D_POSITIVE_INC, // not implemented
|
||||
|
@ -229,8 +331,15 @@ typedef enum PGen_1D_incrementDirection{
|
|||
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);
|
||||
/// PGen_1D point generator constructor.
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue