00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef CLIPPER_COORDS
00046 #define CLIPPER_COORDS
00047
00048
00049 #include "cell.h"
00050 #include "spacegroup.h"
00051 #include "clipper_stats.h"
00052
00053
00054 namespace clipper
00055 {
00056
00057 class Grid; class Grid_sampling; class Grid_range;
00058 class Coord_grid; class Coord_map;
00059 class Coord_reci_frac; class Coord_reci_orth;
00060 class Coord_frac; class Coord_orth;
00061 class U_aniso_frac; class U_aniso_orth;
00062
00063
00065
00068 class Resolution
00069 {
00070 public:
00071 inline Resolution() : resol(0.0) {}
00072 explicit Resolution( const ftype& resol_ );
00073 void init( const ftype& resol_ );
00074 const ftype& limit() const;
00075 ftype invresolsq_limit() const;
00076 bool is_null() const;
00077 private:
00078 ftype resol;
00079 };
00080
00081
00083
00086 class HKL_class
00087 {
00088 public:
00090 inline HKL_class() { epsilon_ = 0; allowed_ = 255; }
00092 HKL_class( const Spacegroup& spgr, const HKL& hkl );
00094 inline ftype epsilon() const { return ftype(epsilon_); }
00096 inline ftype epsilonc() const
00097 { if ( centric() ) return 2.0*ftype(epsilon_);
00098 else return ftype(epsilon_); }
00100 inline ftype allowed() const { return ftype(allowed_) * (Util::pi()/12.0); }
00101 inline bool centric() const { return allowed_ != 255; }
00102 inline bool sys_abs() const { return epsilon_ == 0; }
00103 private:
00104 unsigned char epsilon_, allowed_;
00105 };
00106
00107
00109
00112 class RTop_orth : public RTop<>
00113 {
00114 public:
00116 inline RTop_orth() {}
00118 inline explicit RTop_orth( const RTop<>& o ) : RTop<>( o ) {}
00120 inline explicit RTop_orth( const Mat33<>& r ) : RTop<>( r ) {}
00122 inline RTop_orth( const Mat33<>& r, const Vec3<>& t ) : RTop<>( r, t ) {}
00124 RTop_orth( const std::vector<Coord_orth>& src, const std::vector<Coord_orth>& tgt );
00126 template<class T> RTop_orth( const T& src, const T& tgt );
00128 RTop_frac rtop_frac( const Cell& cell ) const;
00130 RTop_orth inverse() const;
00132 static RTop_orth identity();
00134 static RTop_orth null();
00135 };
00136
00137
00139 class HKL : public Vec3<int>
00140 {
00141 public:
00142 inline HKL() {}
00143 inline explicit HKL( const Vec3<int>& v ) :
00144 Vec3<int>( v ) {}
00145 inline HKL( const int& h, const int& k, const int& l ) :
00146 Vec3<int>( h, k, l ) {}
00147 inline const int& h() const { return (*this)[0]; }
00148 inline const int& k() const { return (*this)[1]; }
00149 inline const int& l() const { return (*this)[2]; }
00150 inline int& h() { return (*this)[0]; }
00151 inline int& k() { return (*this)[1]; }
00152 inline int& l() { return (*this)[2]; }
00153
00154 inline ftype invresolsq( const Cell& cell ) const;
00156 inline Coord_reci_frac coord_reci_frac() const;
00158 inline Coord_reci_orth coord_reci_orth( const Cell& cell ) const;
00160 inline HKL transform( const Symop& op ) const;
00162 inline HKL transform( const Isymop& op ) const;
00164 inline ftype sym_phase_shift( const Symop& op ) const;
00165 String format() const;
00166 friend inline HKL operator -(const HKL& h1)
00167 { return HKL( -h1.h(), -h1.k(), -h1.l() ); }
00168 friend inline HKL operator +(const HKL& h1, const HKL& h2)
00169 { return HKL( h1.h()+h2.h(), h1.k()+h2.k(), h1.l()+h2.l() ); }
00170 friend inline HKL operator -(const HKL& h1, const HKL& h2)
00171 { return HKL( h1.h()-h2.h(), h1.k()-h2.k(), h1.l()-h2.l() ); }
00172 friend inline HKL operator *(const int& s, const HKL& h1)
00173 { return HKL( s*h1.h(), s*h1.k(), s*h1.l() ); }
00174 friend inline HKL operator *(const Isymop& op, const HKL& h1)
00175 { return HKL( h1 * op.rot() ); }
00176 };
00177
00178
00180 class Coord_reci_orth : public Vec3<>
00181 {
00182 public:
00183 inline Coord_reci_orth() {}
00184 inline explicit Coord_reci_orth( const Vec3<>& v ) :
00185 Vec3<>( v ) {}
00186 inline Coord_reci_orth( const ftype& xs, const ftype& ys, const ftype& zs ) : Vec3<>( xs, ys, zs ) {}
00187 inline const ftype& xs() const { return (*this)[0]; }
00188 inline const ftype& ys() const { return (*this)[1]; }
00189 inline const ftype& zs() const { return (*this)[2]; }
00190
00191 inline ftype invresolsq() const;
00193 inline Coord_reci_frac coord_reci_frac( const Cell& cell ) const;
00195 inline Coord_reci_orth transform( const RTop_orth& op ) const
00196 { return Coord_reci_orth( (*this) * op.rot() ); }
00197 String format() const;
00198 };
00199
00200
00202 class Coord_reci_frac : public Vec3<>
00203 {
00204 public:
00205 inline Coord_reci_frac() {}
00206 inline explicit Coord_reci_frac( const Vec3<>& v ) :
00207 Vec3<>( v ) {}
00208 inline Coord_reci_frac( const ftype& us, const ftype& vs, const ftype& ws ) : Vec3<>( us, vs, ws ) {}
00209
00210 inline Coord_reci_frac( const HKL& hkl ) :
00211 Vec3<>( ftype(hkl[0]), ftype(hkl[1]), ftype(hkl[2]) ) {}
00213 inline HKL hkl() const
00214 { return HKL( Util::intr(us()), Util::intr(vs()), Util::intr(ws()) ); }
00216 inline ftype invresolsq( const Cell& cell ) const;
00217 inline const ftype& us() const { return (*this)[0]; }
00218 inline const ftype& vs() const { return (*this)[1]; }
00219 inline const ftype& ws() const { return (*this)[2]; }
00220
00221 inline Coord_reci_orth coord_reci_orth( const Cell& cell ) const;
00223 inline Coord_reci_frac transform( const RTop_frac& op ) const
00224 { return Coord_reci_frac( (*this) * op.rot() ); }
00225 String format() const;
00226 };
00227
00228
00230 class Coord_grid : public Vec3<int>
00231 {
00232 public:
00233 inline Coord_grid() {}
00234
00235 inline explicit Coord_grid( const Vec3<int> v ) : Vec3<int>( v ) {}
00237 inline Coord_grid( const int& u, const int& v, const int& w ) :
00238 Vec3<int>(u,v,w) {}
00240 inline Coord_grid( const Grid& g, const int& index )
00241 { deindex( g, index ); }
00242 inline const int& u() const { return (*this)[0]; }
00243 inline const int& v() const { return (*this)[1]; }
00244 inline const int& w() const { return (*this)[2]; }
00245 inline int& u() { return (*this)[0]; }
00246 inline int& v() { return (*this)[1]; }
00247 inline int& w() { return (*this)[2]; }
00248
00250 inline Coord_map coord_map() const;
00252 inline Coord_frac coord_frac( const Grid_sampling& g ) const;
00254 inline Coord_grid transform( const Isymop& op ) const
00255 { return op * (*this); }
00256
00258 inline Coord_grid unit( const Grid_sampling& g ) const;
00259
00261
00262 inline const Coord_grid& next( const Grid& g );
00264
00265 inline const Coord_grid& next( const Grid_range& g );
00267 inline bool last( const Grid& g ) const;
00269 inline bool last( const Grid_range& g ) const;
00271 inline int index( const Grid& g ) const;
00273 inline void deindex( const Grid& g, const int& index );
00274
00275
00276
00277
00278
00279 String format() const;
00280 friend inline Coord_grid operator -(const Coord_grid& r1)
00281 { return ( Coord_grid( -r1.u(), -r1.v(), -r1.w() ) ); }
00282 friend inline Coord_grid operator +(const Coord_grid& r1, const Coord_grid& r2) { return ( Coord_grid( r1.u()+r2.u(), r1.v()+r2.v(), r1.w()+r2.w() ) ); }
00283 friend inline Coord_grid operator -(const Coord_grid& r1, const Coord_grid& r2) { return ( Coord_grid( r1.u()-r2.u(), r1.v()-r2.v(), r1.w()-r2.w() ) ); }
00284 friend inline Coord_grid operator *(const int& s, const Coord_grid& r1)
00285 { return ( Coord_grid( s*r1.u(), s*r1.v(), s*r1.w() ) ); }
00286 friend inline int operator == (const Coord_grid& r1, const Coord_grid& r2)
00287 { return (r1.u()==r2.u() && r1.v()==r2.v() && r1.w()==r2.w()); }
00288 friend inline int operator != (const Coord_grid& r1, const Coord_grid& r2)
00289 { return (r1.u()!=r2.u() || r1.v()!=r2.v() || r1.w()!=r2.w()); }
00290 friend inline Coord_grid operator *(const Isymop& op, const Coord_grid& r1)
00291 { return Coord_grid( op.rot() * r1 + op.trn() ); }
00292 };
00293
00294
00296 class Coord_orth : public Vec3<>
00297 {
00298 public:
00299 inline Coord_orth() {}
00300 inline explicit Coord_orth( const Vec3<>& v ) :
00301 Vec3<>( v ) {}
00302 inline Coord_orth( const ftype& x, const ftype& y, const ftype& z ) :
00303 Vec3<>( x, y, z ) {}
00304
00305 Coord_orth( const Coord_orth& x1, const Coord_orth& x2, const Coord_orth& x3, const ftype& length, const ftype& angle, const ftype& torsion );
00306 inline const ftype& x() const { return (*this)[0]; }
00307 inline const ftype& y() const { return (*this)[1]; }
00308 inline const ftype& z() const { return (*this)[2]; }
00309
00310 inline ftype lengthsq() const;
00312 inline Coord_frac coord_frac( const Cell& cell ) const;
00314 inline Coord_orth transform( const RTop_orth& op ) const
00315 { return op*(*this); }
00316 String format() const;
00317
00318 static ftype length( const Coord_orth& x1, const Coord_orth& x2);
00320 static ftype angle( const Coord_orth& x1, const Coord_orth& x2,
00321 const Coord_orth& x3);
00323 static ftype torsion( const Coord_orth& x1, const Coord_orth& x2,
00324 const Coord_orth& x3, const Coord_orth& x4);
00325 friend inline Coord_orth operator -(const Coord_orth& x1)
00326 { return Coord_orth( -x1.x(), -x1.y(), -x1.z() ); }
00327 friend inline Coord_orth operator +(const Coord_orth& x1, const Coord_orth& x2) { return Coord_orth( x1.x()+x2.x(), x1.y()+x2.y(), x1.z()+x2.z() ); }
00328 friend inline Coord_orth operator -(const Coord_orth& x1, const Coord_orth& x2) { return Coord_orth( x1.x()-x2.x(), x1.y()-x2.y(), x1.z()-x2.z() ); }
00329 friend inline Coord_orth operator *(const ftype& s, const Coord_orth& x1)
00330 { return Coord_orth( s*x1.x(), s*x1.y(), s*x1.z() ); }
00331 friend inline Coord_orth operator *(const RTop_orth& op, const Coord_orth& x1) { return Coord_orth( op.rot() * x1 + op.trn() ); }
00332 };
00333
00334
00336 class Coord_frac : public Vec3<>
00337 {
00338 public:
00339 inline Coord_frac() {}
00340 inline explicit Coord_frac( const Vec3<>& v ) :
00341 Vec3<>( v ) {}
00342 inline Coord_frac( const ftype& u, const ftype& v, const ftype& w ) :
00343 Vec3<>( u, v, w ) {}
00344 inline const ftype& u() const { return (*this)[0]; }
00345 inline const ftype& v() const { return (*this)[1]; }
00346 inline const ftype& w() const { return (*this)[2]; }
00347
00348 inline ftype lengthsq( const Cell& cell ) const;
00350 inline Coord_orth coord_orth( const Cell& cell ) const;
00352 inline Coord_map coord_map( const Grid& g ) const;
00354 inline Coord_grid coord_grid( const Grid& g ) const;
00356 inline Coord_frac transform( const RTop_frac& op ) const
00357 { return op*(*this); }
00359 inline Coord_frac lattice_copy_zero() const
00360 { return Coord_frac(u()-rint(u()),v()-rint(v()),w()-rint(w())); }
00362 inline Coord_frac lattice_copy_unit() const
00363 { return Coord_frac(u()-floor(u()),v()-floor(v()),w()-floor(w())); }
00365 inline Coord_frac lattice_copy_near(const Coord_frac& n) const
00366 { return (*this-n).lattice_copy_zero()+n; }
00368 Coord_frac symmetry_copy_near(const Spacegroup& spgr, const Cell& cell, const Coord_frac& n) const;
00369 String format() const;
00370 friend inline Coord_frac operator -(const Coord_frac& u1)
00371 { return Coord_frac( -u1.u(), -u1.v(), -u1.w() ); }
00372 friend inline Coord_frac operator +(const Coord_frac& u1, const Coord_frac& u2) { return Coord_frac( u1.u()+u2.u(), u1.v()+u2.v(), u1.w()+u2.w() ); }
00373 friend inline Coord_frac operator -(const Coord_frac& u1, const Coord_frac& u2) { return Coord_frac( u1.u()-u2.u(), u1.v()-u2.v(), u1.w()-u2.w() ); }
00374 friend inline Coord_frac operator *(const ftype& s, const Coord_frac& u1)
00375 { return Coord_frac( s*u1.u(), s*u1.v(), s*u1.w() ); }
00376 friend inline Coord_frac operator *(const RTop_frac& op, const Coord_frac& x1) { return Coord_frac( op.rot() * x1 + op.trn() ); }
00377 };
00378
00379
00381 class Coord_map : public Vec3<>
00382 {
00383 public:
00384 inline Coord_map() {}
00385
00386 inline explicit Coord_map( const Vec3<>& v ) :
00387 Vec3<>( v ) {}
00389 inline explicit Coord_map( const Coord_grid& c ) :
00390 Vec3<>( ftype(c[0]), ftype(c[1]), ftype(c[2]) ) {}
00392 inline Coord_map( const ftype& u, const ftype& v, const ftype& w ) :
00393 Vec3<>( u, v, w ) {}
00395 inline Coord_frac coord_frac( const Grid& g ) const;
00397 inline Coord_grid coord_grid() const { return Coord_grid( Util::intr((*this)[0]), Util::intr((*this)[1]), Util::intr((*this)[2]) ); }
00399 inline Coord_grid floor() const { return Coord_grid( Util::intf((*this)[0]), Util::intf((*this)[1]), Util::intf((*this)[2]) ); }
00401 inline Coord_grid ceil() const { return Coord_grid( Util::intc((*this)[0]), Util::intc((*this)[1]), Util::intc((*this)[2]) ); }
00402 inline const ftype& u() const { return (*this)[0]; }
00403 inline const ftype& v() const { return (*this)[1]; }
00404 inline const ftype& w() const { return (*this)[2]; }
00405 String format() const;
00406 friend inline Coord_map operator -(const Coord_map& u1)
00407 { return Coord_map( -u1.u(), -u1.v(), -u1.w() ); }
00408 friend inline Coord_map operator +(const Coord_map& u1, const Coord_map& u2)
00409 { return Coord_map( u1.u()+u2.u(), u1.v()+u2.v(), u1.w()+u2.w() ); }
00410 friend inline Coord_map operator -(const Coord_map& u1, const Coord_map& u2)
00411 { return Coord_map( u1.u()-u2.u(), u1.v()-u2.v(), u1.w()-u2.w() ); }
00412 friend inline Coord_map operator *(const ftype& s, const Coord_map& u1)
00413 { return Coord_map( s*u1.u(), s*u1.v(), s*u1.w() ); }
00414 };
00415
00416
00418
00420 class U_aniso_orth : public Mat33sym<>
00421 {
00422 public:
00424 inline U_aniso_orth() {};
00426 inline explicit U_aniso_orth( const Mat33sym<>& m ) : Mat33sym<>(m) {}
00428 inline explicit U_aniso_orth( const ftype& u ) :
00429 Mat33sym<>( u, u, u, 0.0, 0.0, 0.0 ) {}
00431 U_aniso_orth( const ftype& u11, const ftype& u22, const ftype& u33,
00432 const ftype& u12, const ftype& u13, const ftype& u23 ) :
00433 Mat33sym<>( u11, u22, u33, u12, u13, u23 ) {}
00435 ftype u_iso() const;
00437 U_aniso_frac u_aniso_frac( const Cell& cell ) const;
00439 U_aniso_orth transform( const RTop_orth& op ) const;
00440 friend U_aniso_orth operator +(const U_aniso_orth& u1, const U_aniso_orth& u2) { return U_aniso_orth( u1.mat00()+u2.mat00(), u1.mat11()+u2.mat11(), u1.mat22()+u2.mat22(), u1.mat01()+u2.mat01(), u1.mat02()+u2.mat02(), u1.mat12()+u2.mat12() ); }
00441 };
00442
00443
00445
00447 class U_aniso_frac : public Mat33sym<>
00448 {
00449 public:
00451 inline U_aniso_frac() {};
00453 inline explicit U_aniso_frac( const Mat33sym<>& m ) : Mat33sym<>(m) {}
00455 U_aniso_frac( const ftype& u11, const ftype& u22, const ftype& u33,
00456 const ftype& u12, const ftype& u13, const ftype& u23 ) :
00457 Mat33sym<>( u11, u22, u33, u12, u13, u23 ) {}
00459 U_aniso_orth u_aniso_orth( const Cell& cell ) const;
00461 U_aniso_frac transform( const RTop_frac& op ) const;
00462 friend U_aniso_frac operator +(const U_aniso_frac& u1, const U_aniso_frac& u2) { return U_aniso_frac( u1.mat00()+u2.mat00(), u1.mat11()+u2.mat11(), u1.mat22()+u2.mat22(), u1.mat01()+u2.mat01(), u1.mat02()+u2.mat02(), u1.mat12()+u2.mat12() ); }
00463 };
00464
00465
00467
00469 class Grid : public Vec3<int>
00470 {
00471 public:
00472 inline Grid() {}
00473 inline Grid( const int& nu, const int& nv, const int& nw ) :
00474 Vec3<int>( nu, nv, nw ) {}
00475 inline const int& nu() const { return (*this)[0]; }
00476 inline const int& nv() const { return (*this)[1]; }
00477 inline const int& nw() const { return (*this)[2]; }
00478
00479 inline int size() const { return nu()*nv()*nw(); }
00481 inline bool in_grid( Coord_grid g ) const { return (g.u() >= 0 && g.u() < nu() && g.v() >= 0 && g.v() < nv() && g.w() >= 0 && g.w() < nw()); }
00482
00484 inline int index( const Coord_grid& c ) const { return c.index(*this); }
00486 inline Coord_grid deindex( const int& index ) const { return Coord_grid( *this, index ); }
00487 String format() const;
00488 void debug() const;
00489 };
00490
00491
00493
00505 class Grid_sampling : public Grid
00506 {
00507 public:
00509 inline Grid_sampling() : Grid(Grid(0,0,0)) {}
00511 inline Grid_sampling( const int& nu, const int& nv, const int& nw ) :
00512 Grid( nu, nv, nw ) {}
00514 Grid_sampling( const Spacegroup& spacegroup, const Cell& cell, const Resolution& resol, const ftype rate = 1.5 );
00516 void init( const Spacegroup& spacegroup, const Cell& cell, const Resolution& resol, const ftype rate = 1.5 );
00517
00519 Mat33<> matrix_grid_frac() const;
00521 Mat33<> matrix_frac_grid() const;
00522
00524 bool is_null() const;
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 };
00535
00536
00538
00542 class HKL_sampling
00543 {
00544 public:
00546 HKL_sampling();
00547
00548 HKL_sampling( const Cell& cell, const Resolution& resolution );
00550 HKL hkl_limit() const;
00552 Resolution resolution( const Cell& cell ) const;
00554 inline bool in_resolution( const HKL& h ) const
00555 { return ( m00*itype64(h.h()*h.h()) + m11*itype64(h.k()*h.k()) +
00556 m22*itype64(h.l()*h.l()) + m01*itype64(h.h()*h.k()) +
00557 m02*itype64(h.h()*h.l()) + m12*itype64(h.k()*h.l()) )
00558 <= ( sqrt_limit_value*sqrt_limit_value ); }
00560 bool is_null() const;
00561 String format() const;
00562 friend inline int operator == (const HKL_sampling& h1, const HKL_sampling& h2)
00563 { return ( h1.m00==h2.m00 && h1.m11==h2.m11 && h1.m22==h2.m22 &&
00564 h1.m01==h2.m01 && h1.m02==h2.m02 && h1.m12==h2.m12 ); }
00565 private:
00566 static itype64 sqrt_limit_value;
00567 itype64 m00, m11, m22, m01, m02, m12;
00568 };
00569
00570
00572
00574 class Grid_range : public Grid
00575 {
00576 public:
00578 inline Grid_range() {}
00580 Grid_range( const Coord_grid& min, const Coord_grid& max );
00582 Grid_range( const Grid& grid, const Coord_frac& min, const Coord_frac& max );
00584 Grid_range( const Cell& cell, const Grid& grid, const ftype& radius );
00586 const Coord_grid& min() const { return min_; }
00588 const Coord_grid& max() const { return max_; }
00590 void add_border( const int b );
00592 bool in_grid( Coord_grid g ) const { return (g.u() >= min_.u() && g.u() <= max_.u() && g.v() >= min_.v() && g.v() <= max_.v() && g.w() >= min_.w() && g.w() <= max_.w()); }
00593
00595 int index( const Coord_grid& c ) const { return (c - min_).index(*this); }
00597 Coord_grid deindex( const int& index ) const { return Coord_grid( *this, index ) + min_; }
00598 private:
00599 Coord_grid min_, max_;
00600 };
00602 typedef Grid_range Grid_map;
00603
00604
00606
00610 class Atom
00611 {
00612 public:
00614 Atom() {}
00616 template<class T> Atom( const T& atom ) : element_(atom.element()), coord_orth_(atom.coord_orth()), u_aniso_orth_(atom.u_aniso_orth()) , occupancy_(atom.occupancy()), u_iso_(atom.u_iso()){}
00618 const String& element() const { return element_; }
00620 const Coord_orth& coord_orth() const { return coord_orth_; }
00622 const ftype& occupancy() const { return occupancy_; }
00624 const ftype& u_iso() const { return u_iso_; }
00626 const U_aniso_orth& u_aniso_orth() const { return u_aniso_orth_; }
00627 void set_element( const String& s );
00628 void set_coord_orth( const Coord_orth& s );
00629 void set_occupancy( const ftype& s );
00630 void set_u_iso( const ftype& s );
00631 void set_u_aniso_orth( const U_aniso_orth& s );
00632
00633 void transform( const RTop_orth rt );
00635 bool is_null() const { return coord_orth_.is_null(); }
00637 static Atom null();
00638 private:
00639 String element_;
00640 Coord_orth coord_orth_;
00641 U_aniso_orth u_aniso_orth_;
00642 ftype occupancy_, u_iso_;
00643 };
00644
00645
00647
00652 class Atom_list : public std::vector<Atom>
00653 {
00654 public:
00656 Atom_list() {}
00658 Atom_list( const std::vector<Atom>& list ) : std::vector<Atom>( list ) {}
00660 template<class T> Atom_list( const T& list ) { for ( int i = 0; i < list.size(); i++ ) push_back( Atom( list[i] ) ); }
00661 };
00662
00663
00664
00665
00673 template<class T> RTop_orth::RTop_orth( const T& src, const T& tgt )
00674 {
00675 std::vector<Coord_orth> vsrc( src.size() );
00676 std::vector<Coord_orth> vtgt( tgt.size() );
00677 for ( int i = 0; i < src.size(); i++ ) vsrc[i] = src[i].coord_orth();
00678 for ( int i = 0; i < tgt.size(); i++ ) vtgt[i] = tgt[i].coord_orth();
00679 (*this) = RTop_orth( vsrc, vtgt );
00680 }
00681
00682
00686 HKL HKL::transform( const Symop& op ) const
00687 { return Coord_reci_frac(*this).transform(op).hkl(); }
00691 HKL HKL::transform( const Isymop& op ) const
00692 { return op*(*this); }
00697 ftype HKL::sym_phase_shift( const Symop& op ) const
00698 { return -Util::twopi()*( Coord_reci_frac(*this) * op.trn() ); }
00699
00703 const Coord_grid& Coord_grid::next( const Grid& g )
00704 { w()++; if ( w() >= g.nw() ) { w() = 0; v()++; if ( v() >= g.nv() ) { v() = 0; u()++; } } return *this; }
00708 const Coord_grid& Coord_grid::next( const Grid_range& g )
00709 { w()++; if ( w() > g.max().w() ) { w() = g.min().w(); v()++; if ( v() > g.max().v() ) { v() = g.min().v(); u()++; } } return *this; }
00713 bool Coord_grid::last( const Grid& g ) const
00714 { return ( u() >= g.nu() ); }
00718 bool Coord_grid::last( const Grid_range& g ) const
00719 { return ( u() > g.max().u() ); }
00724 int Coord_grid::index( const Grid& g ) const
00725 { return ( u()*g.nv() + v() )*g.nw() + w(); }
00730 void Coord_grid::deindex( const Grid& g, const int& index )
00731 { u() = index/(g.nv()*g.nw()); v() = (index/g.nw()) % g.nv(); w() = (index) % g.nw(); }
00732
00734 Coord_grid Coord_grid::unit( const Grid_sampling& g ) const
00735 { return Coord_grid( Util::mod(u(), g.nu()), Util::mod(v(), g.nv()), Util::mod(w(), g.nw()) ); }
00737 Coord_map Coord_grid::coord_map() const
00738 { return Coord_map( *this ); }
00742 Coord_frac Coord_grid::coord_frac( const Grid_sampling& g ) const
00743 { return Coord_frac( ftype(u())/ftype(g.nu()), ftype(v())/ftype(g.nv()), ftype(w())/ftype(g.nw()) ); }
00744
00747 ftype HKL::invresolsq( const Cell& cell ) const
00748 { return cell.metric_reci().lengthsq( Coord_reci_frac( *this ) ); }
00750 Coord_reci_frac HKL::coord_reci_frac() const
00751 { return Coord_reci_frac( *this ); }
00753 Coord_reci_orth HKL::coord_reci_orth( const Cell& cell ) const
00754 { return coord_reci_frac().coord_reci_orth( cell ); }
00756 ftype Coord_reci_orth::invresolsq() const
00757 { return xs()*xs() + ys()*ys() + zs()*zs(); }
00759 Coord_reci_frac Coord_reci_orth::coord_reci_frac( const Cell& cell ) const
00760 { return Coord_reci_frac( (*this) * cell.matrix_orth() ); }
00762 ftype Coord_reci_frac::invresolsq( const Cell& cell ) const
00763 { return cell.metric_reci().lengthsq( *this ); }
00765 Coord_reci_orth Coord_reci_frac::coord_reci_orth( const Cell& cell ) const
00766 { return Coord_reci_orth( (*this) * cell.matrix_frac() ); }
00767
00769 ftype Coord_orth::lengthsq() const
00770 { return x()*x()+y()*y()+z()*z(); }
00772 Coord_frac Coord_orth::coord_frac( const Cell& cell ) const
00773 { return Coord_frac( cell.matrix_frac() * (*this) ); }
00775 ftype Coord_frac::lengthsq( const Cell& cell ) const
00776 { return cell.metric_real().lengthsq( *this ); }
00778 Coord_orth Coord_frac::coord_orth( const Cell& cell ) const
00779 { return Coord_orth( cell.matrix_orth() * (*this) ); }
00781 Coord_map Coord_frac::coord_map( const Grid& g ) const
00782 { return Coord_map( u()*ftype(g.nu()), v()*ftype(g.nv()), w()*ftype(g.nw()) ); }
00784 Coord_grid Coord_frac::coord_grid( const Grid& g ) const
00785 { return Coord_grid( Util::intr(u()*ftype(g.nu())), Util::intr(v()*ftype(g.nv())), Util::intr(w()*ftype(g.nw())) ); }
00787 Coord_frac Coord_map::coord_frac( const Grid& g ) const
00788 { return Coord_frac( u()/ftype(g.nu()), v()/ftype(g.nv()), w()/ftype(g.nw()) ); }
00789
00790 }
00791
00792 #endif