FOX/ObjCryst++  1.10.X (development)
UnitCell.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /*
20 * source file ObjCryst++ Crystal class
21 *
22 */
23 #include "ObjCryst/ObjCryst/UnitCell.h"
24 #include "ObjCryst/Quirks/VFNStreamFormat.h"
25 
26 namespace ObjCryst
27 {
28 const RefParType *gpRefParTypeUnitCell=0;
29 const RefParType *gpRefParTypeUnitCellLength=0;
30 const RefParType *gpRefParTypeUnitCellAngle=0;
31 long NiftyStaticGlobalObjectsInitializer_UnitCell::mCount=0;
32 
34 mCellDim(6),
35 mBMatrix(3,3),mOrthMatrix(3,3),mOrthMatrixInvert(3,3)
36 {
37  VFN_DEBUG_MESSAGE("UnitCell::UnitCell()",10)
38  this->InitOptions();
39  this->Init(10,11,12,M_PI/2+.1,M_PI/2+.2,M_PI/2+.3,"P1","");
41  mClockMaster.AddChild(this->GetSpaceGroup().GetClockSpaceGroup());
42 }
43 
44 UnitCell::UnitCell(const REAL a, const REAL b, const REAL c, const string &SpaceGroupId):
45 mCellDim(6),
46 mBMatrix(3,3),mOrthMatrix(3,3),mOrthMatrixInvert(3,3)
47 {
48  VFN_DEBUG_MESSAGE("UnitCell::UnitCell(a,b,c,Sg)",10)
49  this->Init(a,b,c,M_PI/2,M_PI/2,M_PI/2,SpaceGroupId,"");
50  this->InitOptions();
52  mClockMaster.AddChild(this->GetSpaceGroup().GetClockSpaceGroup());
53 }
54 
55 UnitCell::UnitCell(const REAL a, const REAL b, const REAL c, const REAL alpha,
56  const REAL beta, const REAL gamma,const string &SpaceGroupId):
57 mCellDim(6),
58 mBMatrix(3,3),mOrthMatrix(3,3),mOrthMatrixInvert(3,3)
59 {
60  VFN_DEBUG_MESSAGE("UnitCell::UnitCell(a,b,c,alpha,beta,gamma,Sg)",10)
61  this->Init(a,b,c,alpha,beta,gamma,SpaceGroupId,"");
62  this->InitOptions();
64  mClockMaster.AddChild(this->GetSpaceGroup().GetClockSpaceGroup());
65 }
66 
68 mCellDim(old.mCellDim),mSpaceGroup(old.GetSpaceGroup()),
69 mBMatrix(3,3),mOrthMatrix(3,3),mOrthMatrixInvert(3,3)
70 {
71  VFN_DEBUG_MESSAGE("UnitCell::UnitCell(&oldUnitCell)",10)
72  this ->InitRefParList();
74  this->InitMatrices();
75  this->UpdateLatticePar();
77  mClockMaster.AddChild(this->GetSpaceGroup().GetClockSpaceGroup());
78 }
79 
81 {
82  VFN_DEBUG_ENTRY("UnitCell::~UnitCell()",5)
83  VFN_DEBUG_EXIT("UnitCell::~UnitCell()",5)
84 }
85 
86 const string& UnitCell::GetClassName() const
87 {
88  const static string className="UnitCell";
89  return className;
90 }
91 
92 CrystVector_REAL UnitCell::GetLatticePar() const
93 {
94  VFN_DEBUG_MESSAGE("UnitCell::GetLatticePar()",0)
95 
97  else
98  {
99  //:NOTE: cannot use this->UpdateLatticePar() because it is not a const member function
100  int num = mSpaceGroup.GetSpaceGroupNumber();
101  CrystVector_REAL cellDim=mCellDim;
102  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0)) return cellDim;
103  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
104  {
105  cellDim(4)=M_PI/2.;
106  cellDim(5)=M_PI/2.;
107  return cellDim;
108  }
109  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
110  {
111  cellDim(3)=M_PI/2.;
112  cellDim(5)=M_PI/2.;
113  return cellDim;
114  }
115  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
116  {
117  cellDim(3)=M_PI/2.;
118  cellDim(4)=M_PI/2.;
119  return cellDim;
120  }
121  if(num <=74)
122  {
123  cellDim(3)=M_PI/2.;
124  cellDim(4)=M_PI/2.;
125  cellDim(5)=M_PI/2.;
126  return cellDim;
127  }
128  if(num <= 142)
129  {
130  cellDim(3)=M_PI/2.;
131  cellDim(4)=M_PI/2.;
132  cellDim(5)=M_PI/2.;
133  cellDim(1) = mCellDim(0) ;
134  return cellDim;
135  }
136  if(mSpaceGroup.GetExtension()=='R')
137  {
138  cellDim(4) = mCellDim(3);
139  cellDim(5) = mCellDim(3);
140  cellDim(1) = mCellDim(0);
141  cellDim(2) = mCellDim(0);
142  return cellDim;
143  }
144  if(num <= 194) // || (mSpaceGroup.GetExtension()=='H') //Hexagonal
145  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
146  cellDim(3) = M_PI/2.;
147  cellDim(4) = M_PI/2.;
148  cellDim(5) = M_PI*2./3.;
149  cellDim(1) = mCellDim(0) ;
150  return cellDim;
151  }
152  cellDim(3)=M_PI/2.;
153  cellDim(4)=M_PI/2.;
154  cellDim(5)=M_PI/2.;
155  cellDim(1) = mCellDim(0) ;
156  cellDim(2) = mCellDim(0) ;
157  return cellDim;
158  }
159 }
160 
161 REAL UnitCell::GetLatticePar(int whichPar)const
162 {
163  VFN_DEBUG_MESSAGE("UnitCell::LatticePar(i)",0)
164  if( (whichPar<0) || (whichPar>5))
165  throw ObjCrystException("UnitCell::LatticePar(int) :trying to access parameter>5!");
166 
167  if(mClockLatticeParUpdate>mClockLatticePar) return mCellDim(whichPar);
168  else
169  {
170  const int num = mSpaceGroup.GetSpaceGroupNumber();
171 
172  static CrystVector_REAL cellDim;
173  cellDim=mCellDim;
174  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0))
175  return cellDim(whichPar);
176  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
177  {
178  cellDim(4)=M_PI/2.;
179  cellDim(5)=M_PI/2.;
180  return cellDim(whichPar);
181  }
182  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
183  {
184  cellDim(3)=M_PI/2.;
185  cellDim(5)=M_PI/2.;
186  return cellDim(whichPar);
187  }
188  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
189  {
190  cellDim(3)=M_PI/2.;
191  cellDim(4)=M_PI/2.;
192  return cellDim(whichPar);
193  }
194 
195  if(num <=74)
196  {
197  cellDim(3)=M_PI/2.;
198  cellDim(4)=M_PI/2.;
199  cellDim(5)=M_PI/2.;
200  return cellDim(whichPar);
201  }
202  if(num <= 142)
203  {
204  cellDim(3)=M_PI/2.;
205  cellDim(4)=M_PI/2.;
206  cellDim(5)=M_PI/2.;
207  cellDim(1) = mCellDim(0) ;
208  return cellDim(whichPar);
209  }
210  if(mSpaceGroup.GetExtension()=='R')
211  {
212  cellDim(4) = mCellDim(3);
213  cellDim(5) = mCellDim(3);
214  cellDim(1) = mCellDim(0);
215  cellDim(2) = mCellDim(0);
216  return cellDim(whichPar);
217  }
218  if(num <= 194) // ||(mSpaceGroup.GetExtension()=='H')
219  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
220  cellDim(3) = M_PI/2.;
221  cellDim(4) = M_PI/2.;
222  cellDim(5) = M_PI*2./3.;
223  cellDim(1) = mCellDim(0) ;
224  return cellDim(whichPar);
225  }
226  cellDim(3)=M_PI/2.;
227  cellDim(4)=M_PI/2.;
228  cellDim(5)=M_PI/2.;
229  cellDim(1) = mCellDim(0) ;
230  cellDim(2) = mCellDim(0) ;
231  return cellDim(whichPar);
232  }
233 }
234 
235 const CrystMatrix_REAL& UnitCell::GetBMatrix()const
236 {
237  VFN_DEBUG_MESSAGE("UnitCell::GetBMatrix()",0)
238  this->InitMatrices();
239  return mBMatrix;
240 }
241 
242 const CrystMatrix_REAL& UnitCell::GetOrthMatrix() const
243 {
244  VFN_DEBUG_MESSAGE("UnitCell::GetOrthMatrix()",0)
245  this->InitMatrices();
246  return mOrthMatrix;
247 }
248 
249 CrystVector_REAL UnitCell::GetOrthonormalCoords(const REAL x,
250  const REAL y,
251  const REAL z) const
252 {
253  this->InitMatrices();
254  CrystVector_REAL coords(3);
255  coords(0)=mOrthMatrix(0,0)*x+mOrthMatrix(0,1)*y+mOrthMatrix(0,2)*z;
256  coords(1)=mOrthMatrix(1,0)*x+mOrthMatrix(1,1)*y+mOrthMatrix(1,2)*z;
257  coords(2)=mOrthMatrix(2,0)*x+mOrthMatrix(2,1)*y+mOrthMatrix(2,2)*z;
258  return coords;
259 }
260 
261 void UnitCell::FractionalToOrthonormalCoords(REAL &x,REAL &y,REAL &z) const
262 {
263  this->InitMatrices();
264  const REAL oldx=x;
265  const REAL oldy=y;
266  x=mOrthMatrix(0,0)*oldx+mOrthMatrix(0,1)*oldy+mOrthMatrix(0,2)*z;
267  y=mOrthMatrix(1,0)*oldx+mOrthMatrix(1,1)*oldy+mOrthMatrix(1,2)*z;
268  z=mOrthMatrix(2,0)*oldx+mOrthMatrix(2,1)*oldy+mOrthMatrix(2,2)*z;
269 }
270 
271 void UnitCell::OrthonormalToFractionalCoords(REAL &x,REAL &y,REAL &z) const
272 {
273  //cout << x << " " << y << " " << z <<endl;
274  //cout << endl << mOrthMatrixInvert <<endl;
275  this->InitMatrices();
276  const REAL oldx=x;
277  const REAL oldy=y;
278  x=mOrthMatrixInvert(0,0)*oldx+mOrthMatrixInvert(0,1)*oldy+mOrthMatrixInvert(0,2)*z;
279  y=mOrthMatrixInvert(1,0)*oldx+mOrthMatrixInvert(1,1)*oldy+mOrthMatrixInvert(1,2)*z;
280  z=mOrthMatrixInvert(2,0)*oldx+mOrthMatrixInvert(2,1)*oldy+mOrthMatrixInvert(2,2)*z;
281  //cout << x << " " << y << " " << z <<endl;
282 }
283 
284 void UnitCell::MillerToOrthonormalCoords(REAL &x,REAL &y,REAL &z) const
285 {
286  this->InitMatrices();
287  const REAL oldx=x;
288  const REAL oldy=y;
289  x=mBMatrix(0,0)*oldx+mBMatrix(0,1)*oldy+mBMatrix(0,2)*z;
290  y=mBMatrix(1,0)*oldx+mBMatrix(1,1)*oldy+mBMatrix(1,2)*z;
291  z=mBMatrix(2,0)*oldx+mBMatrix(2,1)*oldy+mBMatrix(2,2)*z;
292 }
293 
294 void UnitCell::OrthonormalToMillerCoords(REAL &x,REAL &y,REAL &z) const
295 {
296  this->InitMatrices();
297  const REAL oldx=x;
298  const REAL oldy=y;
299  x=mBMatrixInvert(0,0)*oldx+mBMatrixInvert(0,1)*oldy+mBMatrixInvert(0,2)*z;
300  y=mBMatrixInvert(1,0)*oldx+mBMatrixInvert(1,1)*oldy+mBMatrixInvert(1,2)*z;
301  z=mBMatrixInvert(2,0)*oldx+mBMatrixInvert(2,1)*oldy+mBMatrixInvert(2,2)*z;
302 }
303 
304 void UnitCell::Print(ostream &os)const
305 {
306  VFN_DEBUG_MESSAGE("UnitCell::Print()",5)
307  this->InitMatrices();
308  int width =8 ;
309  os << "UnitCell : " << mName <<"("<<this->GetSpaceGroup().GetName()<<")"<< endl;
310  os.width(width);
311  os << " Cell dimensions : "
312  << FormatFloat(this->GetLatticePar(0),8,5) << " "
313  << FormatFloat(this->GetLatticePar(1),8,5) << " "
314  << FormatFloat(this->GetLatticePar(2),8,5) << " "
315  << FormatFloat(this->GetLatticePar(3)*RAD2DEG,8,5) << " "
316  << FormatFloat(this->GetLatticePar(4)*RAD2DEG,8,5) << " "
317  << FormatFloat(this->GetLatticePar(5)*RAD2DEG,8,5) << endl ;
318 }
319 
322 
325 
327 {
328  const REAL a=this->GetLatticePar(0);
329  const REAL b=this->GetLatticePar(1);
330  const REAL c=this->GetLatticePar(2);
331  const REAL alpha=this->GetLatticePar(3);
332  const REAL beta=this->GetLatticePar(4);
333  const REAL gamma=this->GetLatticePar(5);
334 
335  return a*b*c*sqrt(1-cos(alpha)*cos(alpha)-cos(beta)*cos(beta)-cos(gamma)*cos(gamma)
336  +2*cos(alpha)*cos(beta)*cos(gamma));
337 }
338 
339 void UnitCell::Init(const REAL a, const REAL b, const REAL c, const REAL alpha,
340  const REAL beta, const REAL gamma,const string &SpaceGroupId,
341  const string& name)
342 {
343  VFN_DEBUG_ENTRY("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name)",10)
344  //mSpaceGroup.Print();
345  mSpaceGroup.ChangeSpaceGroup(SpaceGroupId);
346  //mSpaceGroup.Print();
347  mCellDim(0)=a;
348  mCellDim(1)=b;
349  mCellDim(2)=c;
350  mCellDim(3)=alpha;
351  mCellDim(4)=beta;
352  mCellDim(5)=gamma;
353 
356 
357  this->InitRefParList();
358  this->InitMatrices();
359  this->UpdateLatticePar();
360  this->SetName(name);
361 
362  VFN_DEBUG_EXIT("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name):End",10)
363 }
364 
366 {
367  VFN_DEBUG_ENTRY("UnitCell::InitOptions",10)
368  static string ConstrainLatticeToSpaceGroupName;
369  static string ConstrainLatticeToSpaceGroupChoices[2];
370 
371  static bool needInitNames=true;
372  if(true==needInitNames)
373  {
374  ConstrainLatticeToSpaceGroupName="Constrain Lattice to SpaceGroup Symmetry";
375  ConstrainLatticeToSpaceGroupChoices[0]="Yes (Default)";
376  ConstrainLatticeToSpaceGroupChoices[1]="No (Allow Crystallographic Pseudo-Symmetry)";
377 
378  needInitNames=false;//Only once for the class
379  }
380  VFN_DEBUG_MESSAGE("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name):Init options",5)
381  mConstrainLatticeToSpaceGroup.Init(2,&ConstrainLatticeToSpaceGroupName,
382  ConstrainLatticeToSpaceGroupChoices);
383  mConstrainLatticeToSpaceGroup.SetChoice(0);
385  VFN_DEBUG_EXIT("UnitCell::InitOptions",10)
386 }
387 
389 {
390  //:NOTE: The Matrices must remain upper triangular, since this is assumed for
391  //optimization purposes in some procedures.
392  if(mClockMetricMatrix>mClockLatticePar) return;//no need to update
393  //this->UpdateLatticePar(); we should be able to do this...
394 
395  VFN_DEBUG_MESSAGE("UnitCell::InitMatrices() for crystal : "+this->GetName(),5)
396  //mClockMetricMatrix.Print();
397  //mClockLatticePar.Print();
398 
399  REAL a,b,c,alpha,beta,gamma;//direct space parameters
400  REAL aa,bb,cc,alphaa,betaa,gammaa;//reciprocal space parameters
401  REAL v;//volume of the unit cell
402  a=this->GetLatticePar(0);
403  b=this->GetLatticePar(1);
404  c=this->GetLatticePar(2);
405  alpha=this->GetLatticePar(3);
406  beta=this->GetLatticePar(4);
407  gamma=this->GetLatticePar(5);
408 
409  //cout <<a<<" "<<b<<" "<<c<<" "<<alpha<<" "<<beta<<" "<<gamma<<endl;
410 
411  v=sqrt(1-cos(alpha)*cos(alpha)-cos(beta)*cos(beta)-cos(gamma)*cos(gamma)
412  +2*cos(alpha)*cos(beta)*cos(gamma));
413 
414  aa=sin(alpha)/a/v;
415  bb=sin(beta )/b/v;
416  cc=sin(gamma)/c/v;
417 
418  alphaa=acos( (cos(beta )*cos(gamma)-cos(alpha))/sin(beta )/sin(gamma) );
419  betaa =acos( (cos(alpha)*cos(gamma)-cos(beta ))/sin(alpha)/sin(gamma) );
420  gammaa=acos( (cos(alpha)*cos(beta )-cos(gamma))/sin(alpha)/sin(beta ) );
421 
422  //cout <<aa<<" "<<bb<<" "<<cc<<" "<<alphaa<<" "<<betaa<<" "<<gammaa<<endl;
423 
424  mBMatrix = aa , bb*cos(gammaa) , cc*cos(betaa) ,
425  0 , bb*sin(gammaa) ,-cc*sin(betaa)*cos(alpha),
426  0 , 0 ,1/c;
427  //cout <<"B Matrix :"<<endl<< mBMatrix <<endl;
428 
429  mOrthMatrix = a , b*cos(gamma) , c*cos(beta) ,
430  0 , b*sin(gamma) ,-c*sin(beta)*cos(alphaa),
431  0 , 0 ,1/cc;
432 
433  mOrthMatrixInvert=InvertMatrix(mOrthMatrix);
434  mBMatrixInvert=InvertMatrix(mBMatrix);
435  //cout << "Orth Matrix :"<<endl<<mOrthMatrix <<endl;
436  //cout << "InvOrth Matrix :"<<endl<<mOrthMatrixInvert <<endl;
437  //cout << "Orth * InvOrth matrix :"<<endl<<product(mOrthMatrix,mOrthMatrixInvert) <<endl;
438  //cout << "InvOrth * Orth Matrix :"<<endl<<product(mOrthMatrixInvert,mOrthMatrix) <<endl;
440  VFN_DEBUG_MESSAGE("UnitCell::InitMatrices():End.",5)
441 }
442 
444 {
447  VFN_DEBUG_ENTRY("UnitCell::UpdateLatticePar().",3)
448 
449  int num = mSpaceGroup.GetSpaceGroupNumber();
450  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0))
451  {
453  return;
454  }
455  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
456  {
457  mCellDim(4)=M_PI/2.;
458  mCellDim(5)=M_PI/2.;
460  return;
461  }
462  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
463  {
464  mCellDim(3)=M_PI/2.;
465  mCellDim(5)=M_PI/2.;
467  return;
468  }
469  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
470  {
471  mCellDim(3)=M_PI/2.;
472  mCellDim(4)=M_PI/2.;
474  return;
475  }
476  if(num <=74)
477  {
478  mCellDim(3)=M_PI/2.;
479  mCellDim(4)=M_PI/2.;
480  mCellDim(5)=M_PI/2.;
482  return;
483  }
484  if(num <= 142)
485  {
486  mCellDim(3)=M_PI/2.;
487  mCellDim(4)=M_PI/2.;
488  mCellDim(5)=M_PI/2.;
489  mCellDim(1) = mCellDim(0) ;
491  return;
492  }
493  if(mSpaceGroup.GetExtension()=='R')
494  {
495  mCellDim(4) = mCellDim(3);
496  mCellDim(5) = mCellDim(3);
497  mCellDim(1) = mCellDim(0);
498  mCellDim(2) = mCellDim(0);
500  return;
501  }
502  if(num <= 194) //||(mSpaceGroup.GetExtension()=='H')
503  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
504  mCellDim(3) = M_PI/2.;
505  mCellDim(4) = M_PI/2.;
506  mCellDim(5) = M_PI*2./3.;
507  mCellDim(1) = mCellDim(0) ;
509  return;
510  }
511  mCellDim(3)=M_PI/2.;
512  mCellDim(4)=M_PI/2.;
513  mCellDim(5)=M_PI/2.;
514  mCellDim(1) = mCellDim(0) ;
515  mCellDim(2) = mCellDim(0) ;
517  VFN_DEBUG_EXIT("UnitCell::UpdateLatticePar().",3)
518  return;
519 }
520 
522 {
523  VFN_DEBUG_ENTRY("UnitCell::InitRefParList()",5)
524  //this->ResetParList();
525  int num = mSpaceGroup.GetSpaceGroupNumber();
526  bool a=true;
527  bool b=true;
528  bool c=true;
529  bool alpha=true;
530  bool beta=true;
531  bool gamma=true;
532  if(mConstrainLatticeToSpaceGroup.GetChoice()==0)
533  {
534  if(num <=2)
535  {
536  }
537  else if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
538  {
539  beta=false;
540  gamma=false;
541  }
542  else if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
543  {
544  alpha=false;
545  gamma=false;
546  }
547  else if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
548  {
549  alpha=false;
550  beta=false;
551  }
552  else if(num <=74)
553  {
554  alpha=false;
555  beta=false;
556  gamma=false;
557  }
558  else if(num <= 142)
559  {
560  b=false;
561  alpha=false;
562  beta=false;
563  gamma=false;
564  }
565  else if(mSpaceGroup.GetExtension()=='R')
566  {//Rhombohedral
567  b=false;
568  c=false;
569  alpha=true;
570  beta=false;
571  gamma=false;
572  }
573  else if(num <= 194)
574  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
575  b=false;
576  alpha=false;
577  beta=false;
578  gamma=false;
579  }
580  else
581  {
582  b=false;
583  c=false;
584  alpha=false;
585  beta=false;
586  gamma=false;
587  }
588  }
589  REAL *pLatPar=mCellDim.data();
590  if(this->GetNbPar()==0)
591  {//:KLUDGE:
592  {
593  RefinablePar tmp("a",pLatPar,1.,100.,
594  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
595  true,true,a,false,1.0);
596  tmp.SetDerivStep(1e-4);
598  this->AddPar(tmp);
599  }
600  {
601  RefinablePar tmp("b",pLatPar+1,1.,100.,
602  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
603  true,true,b,false,1.0);
604  tmp.SetDerivStep(1e-4);
606  this->AddPar(tmp);
607  }
608  {
609  RefinablePar tmp("c",pLatPar+2,1.,100.,
610  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
611  true,true,c,false,1.0);
612  tmp.SetDerivStep(1e-4);
614  this->AddPar(tmp);
615  }
616  {
617  RefinablePar tmp("alpha",pLatPar+3,.5,3.,
618  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
619  true,true,alpha,false,RAD2DEG);
620  tmp.SetDerivStep(1e-4);
622  this->AddPar(tmp);
623  }
624  {
625  RefinablePar tmp("beta",pLatPar+4,.5,3.,
626  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
627  true,true,beta,false,RAD2DEG);
628  tmp.SetDerivStep(1e-4);
630  this->AddPar(tmp);
631  }
632  {
633  RefinablePar tmp("gamma",pLatPar+5,.5,3.,
634  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
635  true,true,gamma,false,RAD2DEG);
636  tmp.SetDerivStep(1e-4);
638  this->AddPar(tmp);
639  }
640  }
641  else
642  {//Just Fix the 'used' status
643  this->GetPar(pLatPar+0).SetIsUsed(a);
644  this->GetPar(pLatPar+1).SetIsUsed(b);
645  this->GetPar(pLatPar+2).SetIsUsed(c);
646  this->GetPar(pLatPar+3).SetIsUsed(alpha);
647  this->GetPar(pLatPar+4).SetIsUsed(beta);
648  this->GetPar(pLatPar+5).SetIsUsed(gamma);
649  }
650 
651  VFN_DEBUG_EXIT("UnitCell::InitRefParList():Finished",5)
652 }
653 
654 }
CrystVector_REAL GetLatticePar() const
Lattice parameters (a,b,c,alpha,beta,gamma) as a 6-element vector in Angstroems and radians...
Definition: UnitCell.cpp:92
void SetDerivStep(const REAL)
Fixed step to use to compute numerical derivative.
void UpdateLatticePar()
Definition: UnitCell.cpp:443
void AddPar(const RefinablePar &newRefPar)
Add a refinable parameter.
virtual void Init(const REAL a, const REAL b, const REAL c, const REAL alpha, const REAL beta, const REAL gamma, const string &SpaceGroupId, const string &name)
Init all UnitCell parameters.
Definition: UnitCell.cpp:339
CrystMatrix_REAL mBMatrixInvert
inverse of B Matrix (i.e. inverse of orthogonalization matrix for direct space)
Definition: UnitCell.h:221
const CrystMatrix_REAL & GetBMatrix() const
Get the 'B' matrix (UnitCell::mBMatrix)for the UnitCell (orthogonalization matrix for the given latti...
Definition: UnitCell.cpp:235
const RefinableObjClock & GetClockLatticePar() const
last time the Lattice parameters were changed
Definition: UnitCell.cpp:323
const RefinableObjClock & GetClockSpaceGroup() const
Get the SpaceGroup Clock (corresponding to the time of the initialization of the SpaceGroup) ...
Definition: SpaceGroup.cpp:467
void OrthonormalToFractionalCoords(REAL &x, REAL &y, REAL &z) const
Get fractional cartesian coordinates for a set of (x,y,z) orthonormal coordinates.
Definition: UnitCell.cpp:271
UnitCell()
Default Constructor.
Definition: UnitCell.cpp:33
We need to record exactly when refinable objects have been modified for the last time (to avoid re-co...
Definition: RefinableObj.h:138
void FractionalToOrthonormalCoords(REAL &x, REAL &y, REAL &z) const
Get orthonormal cartesian coordinates for a set of (x,y,z) fractional coordinates.
Definition: UnitCell.cpp:261
RefinableObjClock mClockLatticePar
Last time lattice parameters were changed.
Definition: UnitCell.h:237
RefObjOpt mConstrainLatticeToSpaceGroup
Option to override lattice parameters constraints from spacegroup choice.
Definition: UnitCell.h:257
void MillerToOrthonormalCoords(REAL &x, REAL &y, REAL &z) const
Get Miller H,K, L indices from orthonormal coordinates in reciprocal space.
Definition: UnitCell.cpp:284
void Click()
Record an event for this clock (generally, the 'time' an object has been modified, or some computation has been made)
long GetNbPar() const
Total number of refinable parameter in the object.
void AddChild(const RefinableObjClock &)
Add a 'child' clock.
unsigned int GetUniqueAxis() const
Which is the unique axis (for monoclinic space groups )
Definition: SpaceGroup.cpp:469
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
Definition: UnitCell.cpp:86
const string & GetName() const
Get the name of this spacegroup (its name, as supplied initially by the calling program or user) ...
Definition: SpaceGroup.cpp:233
void SetIsUsed(const bool)
Is the parameter used (if not, it is simply irrelevant in the model) ?
RefinableObjClock mClockMaster
Master clock, which is changed whenever the object has been altered.
SpaceGroup mSpaceGroup
The space group of the UnitCell.
Definition: UnitCell.h:208
const SpaceGroup & GetSpaceGroup() const
Access to the SpaceGroup object.
Definition: UnitCell.cpp:320
const RefinableObjClock & GetClockMetricMatrix() const
last time the metric matrices were changed
Definition: UnitCell.cpp:324
void OrthonormalToMillerCoords(REAL &x, REAL &y, REAL &z) const
Get orthonormal coordinates given a set of H,K, L indices in reciprocal space.
Definition: UnitCell.cpp:294
string mName
Name for this RefinableObject. Should be unique, at least in the same scope.+.
void InitMatrices() const
Definition: UnitCell.cpp:388
The crystallographic space group, and the cell choice.
Definition: SpaceGroup.h:104
void AssignClock(RefinableObjClock &clock)
RefinableObjClock mClockMetricMatrix
Definition: UnitCell.h:239
REAL GetVolume() const
Volume of Unit Cell (in Angstroems)
Definition: UnitCell.cpp:326
CrystVector_REAL mCellDim
a,b and c in Angstroems, angles (stored) in radians For cubic, rhomboedric UnitCells, only the 'a' parameter is relevant.
Definition: UnitCell.h:206
output a number as a formatted float:
RefinableObjClock mClockLatticeParUpdate
Definition: UnitCell.h:241
void Reset()
Reset a Clock to 0, to force an update.
Exception class for ObjCryst++ library.
Definition: General.h:119
CrystMatrix_REAL mOrthMatrixInvert
inverse of Eucl Matrix (i.e. inverse of de-orthogonalization matrix for direct space) ...
Definition: UnitCell.h:234
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
Unit Cell class: Unit cell with spacegroup information.
Definition: UnitCell.h:71
Generic class for parameters of refinable objects.
Definition: RefinableObj.h:223
const CrystMatrix_REAL & GetOrthMatrix() const
Get the orthogonalization matrix (UnitCell::mOrthMatrix)for the UnitCell in real space.
Definition: UnitCell.cpp:242
void ChangeSpaceGroup(const string &spgId)
Change the Spacegroup.
Definition: SpaceGroup.cpp:227
CrystVector_REAL GetOrthonormalCoords(const REAL x, const REAL y, const REAL z) const
Get orthonormal cartesian coordinates for a set of (x,y,z) fractional coordinates.
Definition: UnitCell.cpp:249
virtual const string & GetName() const
Name of the object.
int GetSpaceGroupNumber() const
Id number of the spacegroup.
Definition: SpaceGroup.cpp:249
CrystMatrix_REAL mOrthMatrix
Eucl Matrix (Orthogonalization matrix for direct space) .
Definition: UnitCell.h:232
~UnitCell()
Destructor.
Definition: UnitCell.cpp:80
CrystMatrix_REAL mBMatrix
B Matrix (Orthogonalization matrix for reciprocal space) .
Definition: UnitCell.h:219
char GetExtension() const
Extension to space group symbol ('1','2':origin choice ; 'R','H'=rhomboedral/hexagonal) ...
Definition: SpaceGroup.cpp:471
virtual void InitOptions()
Init options.
Definition: UnitCell.cpp:365
void AddOption(RefObjOpt *opt)
virtual void SetName(const string &name)
Name of the object.
void InitRefParList()
Prepare the refinable parameters list.
Definition: UnitCell.cpp:521