00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _LINALG3_H
00014 #define _LINALG3_H
00015
00016 #include <math.h>
00017
00018 class Vector3
00019 {
00020 public:
00021 double x, y, z;
00022 Vector3():x(0),y(0),z(0){};
00023 double operator [] (int i) const { return (&x)[i]; }
00024 double & operator [] (int i) { return (&x)[i]; }
00025 Vector3(double a,double b,double c):x(a),y(b),z(c){};
00026 Vector3(const double a[]){x=a[0];y=a[1];z=a[2];}
00027
00028 Vector3 operator + (const Vector3 &a) const
00029 { Vector3 c; c.x=x+a.x;c.y=y+a.y;c.z=z+a.z; return c; }
00030 Vector3 operator - (Vector3 &a) const
00031 { Vector3 c; c.x=x-a.x;c.y=y-a.y;c.z=z-a.z; return c; }
00032 Vector3 operator * (double b) const
00033 { Vector3 c; c.x=x*b;c.y=y*b;c.z=z*b; return c; }
00034 Vector3 operator / (double b) const
00035 { Vector3 c; c.x=x/b;c.y=y/b;c.z=z/b; return c; }
00036
00037 void add (Vector3 &a, Vector3& b){x=a.x+b.x; y=a.y+b.y; z=a.z+b.z;}
00038 void subtract(Vector3 &a, Vector3& b){x=a.x-b.x; y=a.y-b.y; z=a.z-b.z;}
00039 void addnv(double a,const Vector3& b){x+=a*b.x;y+=a*b.y;z+=a*b.z;}
00040 void invert(){x=1./x;y=1./y;z=1./z;}
00041 void subint() {x=x-rint(x);y=y-rint(y);z=z-rint(z);}
00042 double norm2() const {return x*x+y*y+z*z; }
00043 double norm() const {return sqrt(x*x+y*y+z*z); }
00044 void clear() {x=y=z=0;}
00045
00046 double operator * (const Vector3 &a) const
00047 { return (x*a.x+y*a.y+z*a.z); }
00048
00049 #if 0
00050 Vector3 & operator += (double b) { x+=b;y+=b;z+=b; return (*this); }
00051 Vector3 & operator -= (double b) { x-=b;y-=b;z-=b; return (*this); }
00052 Vector3 & operator *= (double b) { x*=b;y*=b;z*=b; return (*this); }
00053 Vector3 & operator /= (double b) { x/=b;y/=b;z/=b; return (*this); }
00054 Vector3 & operator += (const Vector3 &a) { x+=a.x;y+=a.y;z+=a.z; return (*this); }
00055 Vector3 & operator -= (const Vector3 &a) { x-=a.x;y-=a.y;z-=a.z; return (*this); }
00056 Vector3 & operator *= (const Vector3 &a) { x*=a.x;y*=a.y;z*=a.z; return (*this); }
00057 Vector3 & operator /= (const Vector3 &a) { x/=a.x;y/=a.y;z/=a.z; return (*this); }
00058 #else
00059 void operator += (double b) { x+=b;y+=b;z+=b; }
00060 void operator -= (double b) { x-=b;y-=b;z-=b; }
00061 void operator *= (double b) { x*=b;y*=b;z*=b; }
00062 void operator /= (double b) { x/=b;y/=b;z/=b; }
00063 void operator += (const Vector3 &a) { x+=a.x;y+=a.y;z+=a.z; }
00064 void operator -= (const Vector3 &a) { x-=a.x;y-=a.y;z-=a.z; }
00065 void operator *= (const Vector3 &a) { x*=a.x;y*=a.y;z*=a.z; }
00066 void operator /= (const Vector3 &a) { x/=a.x;y/=a.y;z/=a.z; }
00067 #endif
00068
00069 void set(const double a,const double b,const double c){x=a;y=b;z=c;}
00070 void set(const double a[]){x=a[0];y=a[1];z=a[2];}
00071 void add(const double a,const double b,const double c){x+=a;y+=b;z+=c;}
00072 void copytoarray(double a[]) const {a[0]=x;a[1]=y;a[2]=z;}
00073 Vector3 sq() const { Vector3 c; c.x=x*x;c.y=y*y;c.z=z*z; return c;}
00074 Vector3 sqroot() const { Vector3 c; c.x=(double)sqrt(x);c.y=sqrt(y);c.z=sqrt(z); return c;}
00075
00076 Vector3 & orth(Vector3 &a)
00077 {
00078 double sub,norm2;
00079 norm2=a.norm2();
00080 if(norm2>1e-20)
00081 {
00082 sub=((*this)*a)/norm2;
00083 x-=a.x*sub;y-=a.y*sub;z-=a.z*sub;
00084 }
00085 return (*this);
00086 }
00087 Vector3 & proj(Vector3 &a)
00088 {
00089 double sub,norm2;
00090 norm2=a.norm2();
00091 if(norm2>1e-20)
00092 {
00093 sub=((*this)*a)/norm2;
00094 x=a.x*sub;y=a.y*sub;z=a.z*sub;
00095 }
00096 else clear();
00097 return (*this);
00098 }
00099 friend double dot(Vector3 &a, Vector3 &b)
00100 {
00101 double c;
00102 c=a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
00103 return c;
00104 }
00105 friend Vector3 cross(Vector3 &a, Vector3 &b)
00106 {
00107 Vector3 c;
00108 c[0]=a[1]*b[2]-a[2]*b[1];
00109 c[1]=a[2]*b[0]-a[0]*b[2];
00110 c[2]=a[0]*b[1]-a[1]*b[0];
00111 return c;
00112 }
00113 friend Vector3 schmidt(Vector3 &a, Vector3 &b)
00114 {
00115 #ifndef TINYNORM2
00116 #define TINYNORM2 1e-10
00117 #endif
00118 Vector3 c,a1;
00119 a1=a;
00120 c=a1;c.orth(b);
00121 if(c.norm2()<TINYNORM2) a1[0]+=1;
00122 c=a1;c.orth(b);
00123 if(c.norm2()<TINYNORM2) a1[1]+=1;
00124 c=a1;c.orth(b);
00125 if(c.norm2()<TINYNORM2)
00126 {
00127 FATAL("Schmidt("<<a<<", "<<b<<"): "
00128 <<"too small! c="<<c);
00129 }
00130 #undef TINYNORM
00131 return c/c.norm();
00132 }
00133 friend LOStream & operator <<(LOStream &os, const Vector3 &a)
00134 {
00135 os.Printf("%18.10e %18.10e %18.10e",a.x,a.y,a.z);
00136 return os;
00137 }
00138 friend LIStream & operator >>(LIStream &is, Vector3 &a)
00139 {
00140 is >> a.x >> a.y >> a.z;
00141 return is;
00142 }
00143
00144 };
00145
00146 class Matrix33
00147 {
00148 public:
00149 double element[3][3];
00150 public:
00151 Matrix33(){clear();}
00152 Matrix33(double e1,double e2,double e3,
00153 double e4,double e5,double e6,
00154 double e7,double e8,double e9)
00155 {element[0][0]=e1;element[0][1]=e2;element[0][2]=e3;
00156 element[1][0]=e4;element[1][1]=e5;element[1][2]=e6;
00157 element[2][0]=e7;element[2][1]=e8;element[2][2]=e9;}
00158 Matrix33(double e[9])
00159 {element[0][0]=e[0];element[0][1]=e[1];element[0][2]=e[2];
00160 element[1][0]=e[3];element[1][1]=e[4];element[1][2]=e[5];
00161 element[2][0]=e[6];element[2][1]=e[7];element[2][2]=e[8];}
00162 void set(const double e1,const double e2,const double e3,
00163 const double e4,const double e5,const double e6,
00164 const double e7,const double e8,const double e9)
00165 {element[0][0]=e1;element[0][1]=e2;element[0][2]=e3;
00166 element[1][0]=e4;element[1][1]=e5;element[1][2]=e6;
00167 element[2][0]=e7;element[2][1]=e8;element[2][2]=e9;}
00168 void set(const double e[])
00169 {element[0][0]=e[0];element[0][1]=e[1];element[0][2]=e[2];
00170 element[1][0]=e[3];element[1][1]=e[4];element[1][2]=e[5];
00171 element[2][0]=e[6];element[2][1]=e[7];element[2][2]=e[8];}
00172 void setcol(Vector3 &a,Vector3 &b,Vector3 &c)
00173 {element[0][0]=a[0];element[0][1]=b[0];element[0][2]=c[0];
00174 element[1][0]=a[1];element[1][1]=b[1];element[1][2]=c[1];
00175 element[2][0]=a[2];element[2][1]=b[2];element[2][2]=c[2];}
00176 void setcol(double a[],double b[],double c[])
00177 {element[0][0]=a[0];element[0][1]=b[0];element[0][2]=c[0];
00178 element[1][0]=a[1];element[1][1]=b[1];element[1][2]=c[1];
00179 element[2][0]=a[2];element[2][1]=b[2];element[2][2]=c[2];}
00180 void setcol(Matrix33 ma,Matrix33 mb,Matrix33 mc)
00181 {element[0][0]=ma[0][0];element[0][1]=mb[0][1];element[0][2]=mc[0][2];
00182 element[1][0]=ma[1][0];element[1][1]=mb[1][1];element[1][2]=mc[1][2];
00183 element[2][0]=ma[2][0];element[2][1]=mb[2][1];element[2][2]=mc[2][2];}
00184 void copytoarray(double e[]) const
00185 {e[0]=element[0][0];e[1]=element[0][1];e[2]=element[0][2];
00186 e[3]=element[1][0];e[4]=element[1][1];e[5]=element[1][2];
00187 e[6]=element[2][0];e[7]=element[2][1];e[8]=element[2][2];}
00188 const double * operator [] (int i) const
00189 { if(i>2||i<0) FATAL("wrong index Matrix["<<i<<"]");
00190 return element[i]; }
00191 double * operator [] (int i)
00192 { if(i>2||i<0) FATAL("wrong index Matrix["<<i<<"]");
00193 return element[i]; }
00194
00195 friend LOStream & operator <<(LOStream &os, const Matrix33 &m)
00196 {
00197 os.Printf("%18.10e %18.10e %18.10e\n"
00198 "%18.10e %18.10e %18.10e\n"
00199 "%18.10e %18.10e %18.10e",
00200 m[0][0],m[0][1],m[0][2],
00201 m[1][0],m[1][1],m[1][2],
00202 m[2][0],m[2][1],m[2][2]);
00203 return os;
00204 }
00205 friend LIStream & operator >>(LIStream &is, Matrix33 &m)
00206 {
00207 DUMP("read matrix");
00208 is >> (double &)m[0][0] >> (double &)m[0][1] >> (double &)m[0][2]
00209 >> (double &)m[1][0] >> (double &)m[1][1] >> (double &)m[1][2]
00210 >> (double &)m[2][0] >> (double &)m[2][1] >> (double &)m[2][2];
00211 DUMP("m=[\n"<<m<<"\n");
00212 return is;
00213 }
00214 Matrix33 operator + (double n) const
00215 {
00216 Matrix33 m;
00217 for(int i=0;i<3;i++)
00218 for(int j=0;j<3;j++)
00219 m[i][j]=element[i][j]+n;
00220 return m;
00221 }
00222 Matrix33 operator - (double n) const
00223 {
00224 Matrix33 m;
00225 for(int i=0;i<3;i++)
00226 for(int j=0;j<3;j++)
00227 m[i][j]=element[i][j]-n;
00228 return m;
00229 }
00230 Matrix33 operator - () const
00231 {
00232 Matrix33 m;
00233 for(int i=0;i<3;i++)
00234 for(int j=0;j<3;j++)
00235 m[i][j]=-element[i][j];
00236 return m;
00237 }
00238 Matrix33 operator * (double n) const
00239 {
00240 Matrix33 m;
00241 for(int i=0;i<3;i++)
00242 for(int j=0;j<3;j++)
00243 m[i][j]=element[i][j]*n;
00244 return m;
00245 }
00246 Matrix33 operator / (double n) const
00247 {
00248 Matrix33 m;
00249 for(int i=0;i<3;i++)
00250 for(int j=0;j<3;j++)
00251 m[i][j]=element[i][j]/n;
00252 return m;
00253 }
00254 Matrix33 operator + (Matrix33 h) const
00255 {
00256 Matrix33 m;
00257 for(int i=0;i<3;i++)
00258 for(int j=0;j<3;j++)
00259 m[i][j]=element[i][j]+h[i][j];
00260 return m;
00261 }
00262 Matrix33 operator - (Matrix33 h) const
00263 {
00264 Matrix33 m;
00265 for(int i=0;i<3;i++)
00266 for(int j=0;j<3;j++)
00267 m[i][j]=element[i][j]-h[i][j];
00268 return m;
00269 }
00270 Matrix33 & operator += (const Matrix33 &h)
00271 {
00272 for(int i=0;i<3;i++)
00273 for(int j=0;j<3;j++)
00274 element[i][j]+=h[i][j];
00275 return (*this);
00276 }
00277 double trace() const
00278 {
00279 return (element[0][0]+element[1][1]+element[2][2]);
00280 }
00281 void operator *= (double n)
00282 {
00283 element[0][0]*=n;
00284 element[0][1]*=n;
00285 element[0][2]*=n;
00286 element[1][0]*=n;
00287 element[1][1]*=n;
00288 element[1][2]*=n;
00289 element[2][0]*=n;
00290 element[2][1]*=n;
00291 element[2][2]*=n;
00292 }
00293 void operator /= (double n)
00294 {
00295 element[0][0]/=n;
00296 element[0][1]/=n;
00297 element[0][2]/=n;
00298 element[1][0]/=n;
00299 element[1][1]/=n;
00300 element[1][2]/=n;
00301 element[2][0]/=n;
00302 element[2][1]/=n;
00303 element[2][2]/=n;
00304 }
00305 Vector3 operator * (const Vector3 &a) const
00306 {
00307 Vector3 b;
00308 b.x = element[0][0] * a.x + element[0][1] * a.y + element[0][2] * a.z;
00309 b.y = element[1][0] * a.x + element[1][1] * a.y + element[1][2] * a.z;
00310 b.z = element[2][0] * a.x + element[2][1] * a.y + element[2][2] * a.z;
00311 return b;
00312 }
00313 void multiply (const Vector3 &a, Vector3 &b) const
00314 {
00315 b.x = element[0][0] * a.x + element[0][1] * a.y + element[0][2] * a.z;
00316 b.y = element[1][0] * a.x + element[1][1] * a.y + element[1][2] * a.z;
00317 b.z = element[2][0] * a.x + element[2][1] * a.y + element[2][2] * a.z;
00318 }
00319
00320 Matrix33 operator * (const Matrix33 &m) const
00321 {
00322 Matrix33 n;
00323 n[0][0]=element[0][0]*m[0][0]+element[0][1]*m[1][0]+element[0][2]*m[2][0];
00324 n[0][1]=element[0][0]*m[0][1]+element[0][1]*m[1][1]+element[0][2]*m[2][1];
00325 n[0][2]=element[0][0]*m[0][2]+element[0][1]*m[1][2]+element[0][2]*m[2][2];
00326 n[1][0]=element[1][0]*m[0][0]+element[1][1]*m[1][0]+element[1][2]*m[2][0];
00327 n[1][1]=element[1][0]*m[0][1]+element[1][1]*m[1][1]+element[1][2]*m[2][1];
00328 n[1][2]=element[1][0]*m[0][2]+element[1][1]*m[1][2]+element[1][2]*m[2][2];
00329 n[2][0]=element[2][0]*m[0][0]+element[2][1]*m[1][0]+element[2][2]*m[2][0];
00330 n[2][1]=element[2][0]*m[0][1]+element[2][1]*m[1][1]+element[2][2]*m[2][1];
00331 n[2][2]=element[2][0]*m[0][2]+element[2][1]*m[1][2]+element[2][2]*m[2][2];
00332 return n;
00333 }
00334 Matrix33 & addnvv(double n,Vector3 &a,Vector3 &b)
00335 {
00336 element[0][0]+=n*a.x*b.x;
00337 element[0][1]+=n*a.x*b.y;
00338 element[0][2]+=n*a.x*b.z;
00339 element[1][0]+=n*a.y*b.x;
00340 element[1][1]+=n*a.y*b.y;
00341 element[1][2]+=n*a.y*b.z;
00342 element[2][0]+=n*a.z*b.x;
00343 element[2][1]+=n*a.z*b.y;
00344 element[2][2]+=n*a.z*b.z;
00345 return (*this);
00346 }
00347 Matrix33 adj() const
00348 {
00349 Matrix33 hadj;
00350 hadj[0][0]=element[1][1]*element[2][2]-element[1][2]*element[2][1];
00351 hadj[1][1]=element[2][2]*element[0][0]-element[2][0]*element[0][2];
00352 hadj[2][2]=element[0][0]*element[1][1]-element[0][1]*element[1][0];
00353 hadj[0][1]=element[1][2]*element[2][0]-element[1][0]*element[2][2];
00354 hadj[1][2]=element[2][0]*element[0][1]-element[2][1]*element[0][0];
00355 hadj[2][0]=element[0][1]*element[1][2]-element[0][2]*element[1][1];
00356 hadj[0][2]=element[1][0]*element[2][1]-element[2][0]*element[1][1];
00357 hadj[1][0]=element[2][1]*element[0][2]-element[0][1]*element[2][2];
00358 hadj[2][1]=element[0][2]*element[1][0]-element[1][2]*element[0][0];
00359 return hadj;
00360 }
00361 Matrix33 tran() const
00362 {
00363 Matrix33 htrn;
00364 htrn[0][0]=element[0][0];htrn[1][1]=element[1][1];htrn[2][2]=element[2][2];
00365 htrn[0][1]=element[1][0];htrn[1][2]=element[2][1];htrn[2][0]=element[0][2];
00366 htrn[1][0]=element[0][1];htrn[2][1]=element[1][2];htrn[0][2]=element[2][0];
00367 return htrn;
00368 }
00369 Matrix33 inv() const
00370 {
00371 Matrix33 hinv;double c;
00372 hinv=adj();
00373 c=element[0][0]*hinv[0][0]
00374 +element[0][1]*hinv[0][1]+element[0][2]*hinv[0][2];
00375 hinv=hinv.tran();
00376 hinv[0][0]/=c;hinv[0][1]/=c;hinv[0][2]/=c;
00377 hinv[1][0]/=c;hinv[1][1]/=c;hinv[1][2]/=c;
00378 hinv[2][0]/=c;hinv[2][1]/=c;hinv[2][2]/=c;
00379 return hinv;
00380 }
00381 Matrix33 reorient() const
00382 {
00383 double a, b, c, alpha, beta, gamma;
00384 double b1,b2,c1,c2,c3;
00385 Vector3 va, vb, vc; Matrix33 h0;
00386
00387 va.set(element[0][0],element[1][0],element[2][0]);
00388 vb.set(element[0][1],element[1][1],element[2][1]);
00389 vc.set(element[0][2],element[1][2],element[2][2]);
00390 a=va.norm();
00391 b=vb.norm();
00392 c=vc.norm();
00393 alpha=acos(vb*vc/b/c);
00394 beta=acos(vc*va/c/a);
00395 gamma=acos(va*vb/a/b);
00396 b1=b*cos(gamma);
00397 b2=b*sin(gamma);
00398 c1=c*cos(beta);
00399 c2=c*(cos(alpha)-cos(beta)*cos(gamma))/sin(gamma);
00400 c3=sqrt(c*c-c1*c1-c2*c2);
00401 h0.set(a,b1,c1,
00402 0,b2,c2,
00403 0,0,c3);
00404 for(int i=0;i<3;i++)
00405 for(int j=0;j<3;j++)
00406 if(fabs(h0[i][j])<1e-11) h0[i][j]=0.0;
00407
00408 return h0;
00409
00410 }
00411 double det() const
00412 {
00413 Matrix33 hadj;double c;
00414 hadj=adj();
00415 c=element[0][0]*hadj[0][0]
00416 +element[0][1]*hadj[0][1]+element[0][2]*hadj[0][2];
00417 return c;
00418 }
00419 Vector3 height() const
00420 {
00421 Vector3 h; Vector3 r;
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 Matrix33 hinv;
00436 hinv=inv();
00437
00438 r.set(hinv[0][0],hinv[0][1],hinv[0][2]); h[0]=1/r.norm();
00439 r.set(hinv[1][0],hinv[1][1],hinv[1][2]); h[1]=1/r.norm();
00440 r.set(hinv[2][0],hinv[2][1],hinv[2][2]); h[2]=1/r.norm();
00441
00442
00443 return h;
00444 }
00445 void clear()
00446 {
00447 element[0][0]=element[0][1]=element[0][2]=
00448 element[1][0]=element[1][1]=element[1][2]=
00449 element[2][0]=element[2][1]=element[2][2]=0;
00450 }
00451 void eye()
00452 {
00453 element[0][1]=element[0][2]=
00454 element[1][0]=element[1][2]=
00455 element[2][0]=element[2][1]=0;
00456 element[0][0]=element[1][1]=element[2][2]=1;
00457 }
00458 };
00459
00460
00461 class UnitCell
00462 {
00463
00464 #define MAXBASISNUM 20000
00465
00466 public:
00467 Matrix33 h;
00468 int n;
00469 Vector3 basis[MAXBASISNUM];
00470 int species[MAXBASISNUM];
00471
00472 UnitCell():n(1)
00473 {
00474 h.eye();
00475 basis[0].x=basis[0].y=basis[0].z=0;
00476 species[0]=0;
00477 }
00478 UnitCell(int m,const double *b)
00479 {
00480 h.eye();
00481 n=m;
00482 if(n>=MAXBASISNUM)
00483 FATAL("UnitCell n="<<n<<" exceed limit"<<MAXBASISNUM);
00484 for(int i=0;i<n;i++)
00485 {
00486 basis[i].clear();
00487 basis[i].x=b[3*i];
00488 basis[i].y=b[3*i+1];
00489 basis[i].z=b[3*i+2];
00490 species[i]=0;
00491 }
00492 }
00493 UnitCell(int m,const double *b,const int *s)
00494 {
00495 h.eye();
00496 n=m;
00497 if(n>=MAXBASISNUM)
00498 FATAL("UnitCell n="<<n<<" exceed limit"<<MAXBASISNUM);
00499 for(int i=0;i<n;i++)
00500 {
00501 basis[i].clear();
00502 basis[i].x=b[3*i];
00503 basis[i].y=b[3*i+1];
00504 basis[i].z=b[3*i+2];
00505 species[i]=s[i];
00506 }
00507 }
00508 void set(int m,const double *b)
00509 {
00510 h.eye();
00511 n=m;
00512 if(n>=MAXBASISNUM)
00513 FATAL("UnitCell n="<<n<<" exceed limit"<<MAXBASISNUM);
00514 for(int i=0;i<n;i++)
00515 {
00516 basis[i].clear();
00517 basis[i].x=b[3*i];
00518 basis[i].y=b[3*i+1];
00519 basis[i].z=b[3*i+2];
00520 species[i]=0;
00521 }
00522 }
00523 void set(int m,const double *b,const int *s)
00524 {
00525 h.eye();
00526 n=m;
00527 if(n>=MAXBASISNUM)
00528 FATAL("UnitCell n="<<n<<" exceed limit"<<MAXBASISNUM);
00529 for(int i=0;i<n;i++)
00530 {
00531 basis[i].clear();
00532 basis[i].x=b[3*i];
00533 basis[i].y=b[3*i+1];
00534 basis[i].z=b[3*i+2];
00535 species[i]=s[i];
00536 }
00537 }
00538 UnitCell operator * (const Matrix33 &m) const
00539 {
00540 Vector3 r[8];
00541 Vector3 min,max;
00542 Vector3 s,offset,ns;
00543 Matrix33 hinv;
00544 int i,j,k,p,q;
00545
00546 UnitCell uc;
00547 uc=(*this);
00548 uc.h=h*m;
00549 hinv=m.inv();
00550
00551 r[0].set(0,0,0);
00552 r[1].set(m[0][0],m[1][0],m[2][0]);
00553 r[2].set(m[0][1],m[1][1],m[2][1]);
00554 r[3].set(m[0][2],m[1][2],m[2][2]);
00555 r[4]=r[1]+r[2];
00556 r[5]=r[2]+r[3];
00557 r[6]=r[3]+r[1];
00558 r[7]=r[3]+r[1]+r[2];
00559
00560 min=r[0];max=r[0];
00561 for(i=1;i<8;i++)
00562 {
00563 if(min.x>r[i].x) min.x=r[i].x;
00564 if(min.y>r[i].y) min.y=r[i].y;
00565 if(min.z>r[i].z) min.z=r[i].z;
00566 if(max.x<r[i].x) max.x=r[i].x;
00567 if(max.y<r[i].y) max.y=r[i].y;
00568 if(max.z<r[i].z) max.z=r[i].z;
00569 }
00570
00571 DUMP("min="<<min<<"\nmax="<<max);
00572 q=0;
00573 for(i=(int)floor(min.x);i<=(int)ceil(max.x);i++)
00574 for(j=(int)floor(min.y);j<=(int)ceil(max.y);j++)
00575 for(k=(int)floor(min.z);k<=(int)ceil(max.z);k++)
00576 {
00577 if(n>=MAXBASISNUM)
00578 FATAL("UnitCell n="<<n<<" exceed limit"<<MAXBASISNUM);
00579 for(p=0;p<n;p++)
00580 {
00581 offset.set(i,j,k);
00582 s=basis[p]+offset;
00583 offset.set(0.5,0.5,0.5);
00584 ns=hinv*s;
00585 #define margin 1e-8
00586 #define within01(x) (((x)>-margin)&&((x)<1-margin))
00587 if((within01(ns.x))&&(within01(ns.y))&&(within01(ns.z)))
00588 {
00589 uc.basis[q]=ns;
00590 uc.species[q]=species[p];
00591 if(q>=MAXBASISNUM)
00592 FATAL("UnitCell q="<<q<<" exceed limit"<<MAXBASISNUM);
00593 q++;
00594 DUMP("UnitCell: q="<<q<<"\ns="<<s<<"\nns="<<ns);
00595 }
00596 }
00597 }
00598 uc.n=q;
00599 return uc;
00600 }
00601 friend LOStream & operator <<(LOStream &os, const UnitCell &uc)
00602 {
00603 os.Printf("h=[\n%10g %10g %10g\n"
00604 "%10g %10g %10g\n"
00605 "%10g %10g %10g];\n",
00606 uc.h[0][0],uc.h[0][1],uc.h[0][2],
00607 uc.h[1][0],uc.h[1][1],uc.h[1][2],
00608 uc.h[2][0],uc.h[2][1],uc.h[2][2]);
00609 os<<"basis=[\n";
00610 for(int i=0;i<uc.n;i++)
00611 os.Printf("%10g %10g %10g %2d %6d\n",
00612 uc.basis[i].x,uc.basis[i].y,uc.basis[i].z,uc.species[i],i);
00613 os<<"];";
00614 return os;
00615 }
00616 };
00617
00618 #endif // _LINALG3_H
00619