Some 3D lattice functionality, little refactoring.
Former-commit-id: 8e6572c7352e3b9a75bc13585d688f1c72d378e1
This commit is contained in:
parent
c632ee36c5
commit
658c564a0c
|
@ -439,7 +439,7 @@ typedef struct PGen_xyWeb_StateData {
|
||||||
cart2_t b1, b2; // lattice vectors
|
cart2_t b1, b2; // lattice vectors
|
||||||
cart2_t offset; // offset of the zeroth lattice point from origin (TODO will be normalised to the WS cell)
|
cart2_t offset; // offset of the zeroth lattice point from origin (TODO will be normalised to the WS cell)
|
||||||
// TODO type rectangular vs. triangular
|
// TODO type rectangular vs. triangular
|
||||||
LatticeType2 lt;
|
LatticeFlags lf;
|
||||||
} PGen_xyWeb_StateData;
|
} PGen_xyWeb_StateData;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -450,7 +450,7 @@ PGen PGen_xyWeb_new(cart2_t b1, cart2_t b2, double rtol, cart2_t offset, double
|
||||||
s->inc_maxR = inc_maxR;
|
s->inc_maxR = inc_maxR;
|
||||||
l2d_reduceBasis(b1, b2, &(s->b1), &(s->b2));
|
l2d_reduceBasis(b1, b2, &(s->b1), &(s->b2));
|
||||||
s->offset = offset; // TODO shorten into the WS cell ?
|
s->offset = offset; // TODO shorten into the WS cell ?
|
||||||
s->lt = l2d_classifyLattice(s->b1, s->b2, rtol);
|
s->lf = l2d_detectRightAngles(s->b1, s->b2, rtol);
|
||||||
s->layer_min_height = l2d_hexWebInCircleRadius(s->b1, s->b2);
|
s->layer_min_height = l2d_hexWebInCircleRadius(s->b1, s->b2);
|
||||||
s->layer = ceil(s->minR/s->layer_min_height);
|
s->layer = ceil(s->minR/s->layer_min_height);
|
||||||
if(!inc_minR && (s->layer * s->layer_min_height) <= minR)
|
if(!inc_minR && (s->layer * s->layer_min_height) <= minR)
|
||||||
|
@ -485,7 +485,7 @@ PGenCart2ReturnData PGen_xyWeb_next_cart2(PGen *g) {
|
||||||
s->i = s->layer;
|
s->i = s->layer;
|
||||||
s->j = 0;
|
s->j = 0;
|
||||||
}
|
}
|
||||||
else if(s->lt & (SQUARE | RECTANGULAR)) {
|
else if(s->lf & ORTHOGONAL_01) {
|
||||||
// rectangular or square lattice, four perimeters
|
// rectangular or square lattice, four perimeters
|
||||||
switch(s->phase) {
|
switch(s->phase) {
|
||||||
case 0: // initial i = l, j = 0
|
case 0: // initial i = l, j = 0
|
||||||
|
|
|
@ -73,6 +73,9 @@ static inline point2d point2d_fromxy(const double x, const double y) {
|
||||||
int qpms_reduce_lattice_basis(double *b, ///< Array of dimension [bsize][ndim].
|
int qpms_reduce_lattice_basis(double *b, ///< Array of dimension [bsize][ndim].
|
||||||
const size_t bsize, ///< Number of the basis vectors (dimensionality of the lattice).
|
const size_t bsize, ///< Number of the basis vectors (dimensionality of the lattice).
|
||||||
const size_t ndim, ///< Dimension of the space into which the lattice is embedded.
|
const size_t ndim, ///< Dimension of the space into which the lattice is embedded.
|
||||||
|
/// Lovász condition parameter \f$ \delta \f$.
|
||||||
|
/** Polynomial time complexity guaranteed for \f$\delta \in (1/4,1)\f$.
|
||||||
|
*/
|
||||||
double delta
|
double delta
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -655,12 +658,25 @@ typedef enum {
|
||||||
} SpaceGroup2;
|
} SpaceGroup2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Just for detecting the right angles (needed for generators).
|
||||||
|
typedef enum {
|
||||||
|
NOT_ORTHOGONAL = 0,
|
||||||
|
ORTHOGONAL_01 = 1,
|
||||||
|
ORTHOGONAL_12 = 2,
|
||||||
|
ORTHOGONAL_02 = 4
|
||||||
|
} LatticeFlags;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lagrange-Gauss reduction of a 2D basis.
|
* Lagrange-Gauss reduction of a 2D basis.
|
||||||
* The output shall satisfy |out1| <= |out2| <= |out2 - out1|
|
* The output shall satisfy |out1| <= |out2| <= |out2 - out1|
|
||||||
*/
|
*/
|
||||||
void l2d_reduceBasis(cart2_t in1, cart2_t in2, cart2_t *out1, cart2_t *out2);
|
void l2d_reduceBasis(cart2_t in1, cart2_t in2, cart2_t *out1, cart2_t *out2);
|
||||||
|
|
||||||
|
// This one uses LLL reduction.
|
||||||
|
void l3d_reduceBasis(const cart3_t in[3], cart3_t out[3]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This gives the "ordered shortest triple" of base vectors (each pair from the triple
|
* This gives the "ordered shortest triple" of base vectors (each pair from the triple
|
||||||
* is a base) and there may not be obtuse angle between o1, o2 and between o2, o3
|
* is a base) and there may not be obtuse angle between o1, o2 and between o2, o3
|
||||||
|
@ -684,6 +700,10 @@ bool l2d_is_obtuse(cart2_t i1, cart2_t i2);
|
||||||
*/
|
*/
|
||||||
LatticeType2 l2d_classifyLattice(cart2_t b1, cart2_t b2, double rtol);
|
LatticeType2 l2d_classifyLattice(cart2_t b1, cart2_t b2, double rtol);
|
||||||
|
|
||||||
|
// Detects right angles.
|
||||||
|
LatticeFlags l2d_detectRightAngles(cart2_t b1, cart2_t b2, double rtol);
|
||||||
|
LatticeFlags l3d_detectRightAngles(const cart3_t basis[3], double rtol);
|
||||||
|
|
||||||
// Other functions in lattices2d.py: TODO?
|
// Other functions in lattices2d.py: TODO?
|
||||||
// range2D()
|
// range2D()
|
||||||
// generateLattice()
|
// generateLattice()
|
||||||
|
|
|
@ -677,6 +677,11 @@ void l2d_reduceBasis(cart2_t b1, cart2_t b2, cart2_t *out1, cart2_t *out2){
|
||||||
*out2 = b2;
|
*out2 = b2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void l3d_reduceBasis(const cart3_t in[3], cart3_t out[3]) {
|
||||||
|
memcpy(out, in, 3*sizeof(cart3_t));
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_reduce_lattice_basis((double *)out, 3, 3, 1.));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This gives the "ordered shortest triple" of base vectors (each pair from the triple
|
* This gives the "ordered shortest triple" of base vectors (each pair from the triple
|
||||||
* is a base) and there may not be obtuse angle between o1, o2 and between o2, o3
|
* is a base) and there may not be obtuse angle between o1, o2 and between o2, o3
|
||||||
|
@ -765,6 +770,33 @@ LatticeType2 l2d_classifyLattice(cart2_t b1, cart2_t b2, double rtol)
|
||||||
return OBLIQUE;
|
return OBLIQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LatticeFlags l2d_detectRightAngles(cart2_t b1, cart2_t b2, double rtol)
|
||||||
|
{
|
||||||
|
l2d_reduceBasis(b1, b2, &b1, &b2);
|
||||||
|
cart2_t ht = cart2_substract(b2, b1);
|
||||||
|
double b1s = cart2_normsq(b1), b2s = cart2_normsq(b2), hts = cart2_normsq(ht);
|
||||||
|
double eps = rtol * (b2s + b1s); //FIXME what should eps be?
|
||||||
|
if (hts - b2s - b1s <= eps)
|
||||||
|
return ORTHOGONAL_01;
|
||||||
|
else
|
||||||
|
return NOT_ORTHOGONAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LatticeFlags l3d_detectRightAngles(const cart3_t basis_nr[3], double rtol)
|
||||||
|
{
|
||||||
|
cart3_t b[3];
|
||||||
|
l3d_reduceBasis(basis_nr, b);
|
||||||
|
LatticeFlags res = NOT_ORTHOGONAL;
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
cart3_t ba = b[i], bb = b[(i+1) % 3];
|
||||||
|
cart3_t ht = cart3_substract(ba, bb);
|
||||||
|
double bas = cart3_normsq(ba), bbs = cart3_normsq(ba), hts = cart3_normsq(ht);
|
||||||
|
double eps = rtol * (bas + bbs);
|
||||||
|
if (hts - bbs - bas <= eps)
|
||||||
|
res |= ((LatticeFlags[]){ORTHOGONAL_01, ORTHOGONAL_12, ORTHOGONAL_02})[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
# if 0
|
# if 0
|
||||||
// variant
|
// variant
|
||||||
|
|
|
@ -99,11 +99,20 @@ static inline cart2_t cart3xy2cart2(const cart3_t a) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 3D vector euclidian norm.
|
/// 3D vector dot product.
|
||||||
static inline double cart3norm(const cart3_t v) {
|
static inline double cart3_dot(const cart3_t a, const cart3_t b) {
|
||||||
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
|
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 3D vector euclidian norm squared.
|
||||||
|
static inline double cart3_normsq(const cart3_t a) {
|
||||||
|
return cart3_dot(a, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 3D vector euclidian norm.
|
||||||
|
static inline double cart3norm(const cart3_t v) {
|
||||||
|
return sqrt(cart3_normsq(v));
|
||||||
|
}
|
||||||
|
|
||||||
/// 3D cartesian to spherical coordinates conversion. See @ref coord_conversions.
|
/// 3D cartesian to spherical coordinates conversion. See @ref coord_conversions.
|
||||||
static inline sph_t cart2sph(const cart3_t cart) {
|
static inline sph_t cart2sph(const cart3_t cart) {
|
||||||
|
@ -224,11 +233,6 @@ static inline complex double csphvec_dotnc(const csphvec_t a, const csphvec_t b)
|
||||||
return a.rc * b.rc + a.thetac * b.thetac + a.phic * b.phic;
|
return a.rc * b.rc + a.thetac * b.thetac + a.phic * b.phic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 3D vector dot product.
|
|
||||||
static inline double cart3_dot(const cart3_t a, const cart3_t b) {
|
|
||||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spherical coordinate system scaling.
|
/// Spherical coordinate system scaling.
|
||||||
static inline sph_t sph_scale(double c, const sph_t s) {
|
static inline sph_t sph_scale(double c, const sph_t s) {
|
||||||
sph_t res = {c * s.r, s.theta, s.phi};
|
sph_t res = {c * s.r, s.theta, s.phi};
|
||||||
|
|
Loading…
Reference in New Issue