FOX/ObjCryst++  2022
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,"P 1","");
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 
98  else
99  {
100  //:NOTE: cannot use this->UpdateLatticePar() because it is not a const member function
101  int num = mSpaceGroup.GetSpaceGroupNumber();
102  CrystVector_REAL cellDim=mCellDim;
103  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0)) return cellDim;
104  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
105  {
106  cellDim(4)=M_PI/2.;
107  cellDim(5)=M_PI/2.;
108  return cellDim;
109  }
110  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
111  {
112  cellDim(3)=M_PI/2.;
113  cellDim(5)=M_PI/2.;
114  return cellDim;
115  }
116  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
117  {
118  cellDim(3)=M_PI/2.;
119  cellDim(4)=M_PI/2.;
120  return cellDim;
121  }
122  if(num <=74)
123  {
124  cellDim(3)=M_PI/2.;
125  cellDim(4)=M_PI/2.;
126  cellDim(5)=M_PI/2.;
127  return cellDim;
128  }
129  if(num <= 142)
130  {
131  cellDim(3)=M_PI/2.;
132  cellDim(4)=M_PI/2.;
133  cellDim(5)=M_PI/2.;
134  cellDim(1) = mCellDim(0) ;
135  return cellDim;
136  }
137  if(mSpaceGroup.GetExtension()=='R')
138  {
139  cellDim(4) = mCellDim(3);
140  cellDim(5) = mCellDim(3);
141  cellDim(1) = mCellDim(0);
142  cellDim(2) = mCellDim(0);
143  return cellDim;
144  }
145  if(num <= 194) // || (mSpaceGroup.GetExtension()=='H') //Hexagonal
146  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
147  cellDim(3) = M_PI/2.;
148  cellDim(4) = M_PI/2.;
149  cellDim(5) = M_PI*2./3.;
150  cellDim(1) = mCellDim(0) ;
151  return cellDim;
152  }
153  cellDim(3)=M_PI/2.;
154  cellDim(4)=M_PI/2.;
155  cellDim(5)=M_PI/2.;
156  cellDim(1) = mCellDim(0) ;
157  cellDim(2) = mCellDim(0) ;
158  return cellDim;
159  }
160 }
161 
162 REAL UnitCell::GetLatticePar(int whichPar)const
163 {
164  VFN_DEBUG_MESSAGE("UnitCell::LatticePar(i)",0)
165  if( (whichPar<0) || (whichPar>5))
166  throw ObjCrystException("UnitCell::LatticePar(int) :trying to access parameter>5!");
167 
170  else
171  {
172  const int num = mSpaceGroup.GetSpaceGroupNumber();
173 
174  static CrystVector_REAL cellDim;
175  cellDim=mCellDim;
176  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0))
177  return cellDim(whichPar);
178  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
179  {
180  cellDim(4)=M_PI/2.;
181  cellDim(5)=M_PI/2.;
182  return cellDim(whichPar);
183  }
184  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
185  {
186  cellDim(3)=M_PI/2.;
187  cellDim(5)=M_PI/2.;
188  return cellDim(whichPar);
189  }
190  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
191  {
192  cellDim(3)=M_PI/2.;
193  cellDim(4)=M_PI/2.;
194  return cellDim(whichPar);
195  }
196 
197  if(num <=74)
198  {
199  cellDim(3)=M_PI/2.;
200  cellDim(4)=M_PI/2.;
201  cellDim(5)=M_PI/2.;
202  return cellDim(whichPar);
203  }
204  if(num <= 142)
205  {
206  cellDim(3)=M_PI/2.;
207  cellDim(4)=M_PI/2.;
208  cellDim(5)=M_PI/2.;
209  cellDim(1) = mCellDim(0) ;
210  return cellDim(whichPar);
211  }
212  if(mSpaceGroup.GetExtension()=='R')
213  {
214  cellDim(4) = mCellDim(3);
215  cellDim(5) = mCellDim(3);
216  cellDim(1) = mCellDim(0);
217  cellDim(2) = mCellDim(0);
218  return cellDim(whichPar);
219  }
220  if(num <= 194) // ||(mSpaceGroup.GetExtension()=='H')
221  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
222  cellDim(3) = M_PI/2.;
223  cellDim(4) = M_PI/2.;
224  cellDim(5) = M_PI*2./3.;
225  cellDim(1) = mCellDim(0) ;
226  return cellDim(whichPar);
227  }
228  cellDim(3)=M_PI/2.;
229  cellDim(4)=M_PI/2.;
230  cellDim(5)=M_PI/2.;
231  cellDim(1) = mCellDim(0) ;
232  cellDim(2) = mCellDim(0) ;
233  return cellDim(whichPar);
234  }
235 }
236 
237 const CrystMatrix_REAL& UnitCell::GetBMatrix()const
238 {
239  VFN_DEBUG_MESSAGE("UnitCell::GetBMatrix()",0)
240  this->InitMatrices();
241  return mBMatrix;
242 }
243 
244 const CrystMatrix_REAL& UnitCell::GetOrthMatrix() const
245 {
246  VFN_DEBUG_MESSAGE("UnitCell::GetOrthMatrix()",0)
247  this->InitMatrices();
248  return mOrthMatrix;
249 }
250 
251 CrystVector_REAL UnitCell::GetOrthonormalCoords(const REAL x,
252  const REAL y,
253  const REAL z) const
254 {
255  this->InitMatrices();
256  CrystVector_REAL coords(3);
257  coords(0)=mOrthMatrix(0,0)*x+mOrthMatrix(0,1)*y+mOrthMatrix(0,2)*z;
258  coords(1)=mOrthMatrix(1,0)*x+mOrthMatrix(1,1)*y+mOrthMatrix(1,2)*z;
259  coords(2)=mOrthMatrix(2,0)*x+mOrthMatrix(2,1)*y+mOrthMatrix(2,2)*z;
260  return coords;
261 }
262 
263 void UnitCell::FractionalToOrthonormalCoords(REAL &x,REAL &y,REAL &z) const
264 {
265  this->InitMatrices();
266  const REAL oldx=x;
267  const REAL oldy=y;
268  x=mOrthMatrix(0,0)*oldx+mOrthMatrix(0,1)*oldy+mOrthMatrix(0,2)*z;
269  y=mOrthMatrix(1,0)*oldx+mOrthMatrix(1,1)*oldy+mOrthMatrix(1,2)*z;
270  z=mOrthMatrix(2,0)*oldx+mOrthMatrix(2,1)*oldy+mOrthMatrix(2,2)*z;
271 }
272 
273 void UnitCell::OrthonormalToFractionalCoords(REAL &x,REAL &y,REAL &z) const
274 {
275  //cout << x << " " << y << " " << z <<endl;
276  //cout << endl << mOrthMatrixInvert <<endl;
277  this->InitMatrices();
278  const REAL oldx=x;
279  const REAL oldy=y;
280  x=mOrthMatrixInvert(0,0)*oldx+mOrthMatrixInvert(0,1)*oldy+mOrthMatrixInvert(0,2)*z;
281  y=mOrthMatrixInvert(1,0)*oldx+mOrthMatrixInvert(1,1)*oldy+mOrthMatrixInvert(1,2)*z;
282  z=mOrthMatrixInvert(2,0)*oldx+mOrthMatrixInvert(2,1)*oldy+mOrthMatrixInvert(2,2)*z;
283  //cout << x << " " << y << " " << z <<endl;
284 }
285 
286 void UnitCell::MillerToOrthonormalCoords(REAL &x,REAL &y,REAL &z) const
287 {
288  this->InitMatrices();
289  const REAL oldx=x;
290  const REAL oldy=y;
291  x=mBMatrix(0,0)*oldx+mBMatrix(0,1)*oldy+mBMatrix(0,2)*z;
292  y=mBMatrix(1,0)*oldx+mBMatrix(1,1)*oldy+mBMatrix(1,2)*z;
293  z=mBMatrix(2,0)*oldx+mBMatrix(2,1)*oldy+mBMatrix(2,2)*z;
294 }
295 
296 void UnitCell::OrthonormalToMillerCoords(REAL &x,REAL &y,REAL &z) const
297 {
298  this->InitMatrices();
299  const REAL oldx=x;
300  const REAL oldy=y;
301  x=mBMatrixInvert(0,0)*oldx+mBMatrixInvert(0,1)*oldy+mBMatrixInvert(0,2)*z;
302  y=mBMatrixInvert(1,0)*oldx+mBMatrixInvert(1,1)*oldy+mBMatrixInvert(1,2)*z;
303  z=mBMatrixInvert(2,0)*oldx+mBMatrixInvert(2,1)*oldy+mBMatrixInvert(2,2)*z;
304 }
305 
306 void UnitCell::Print(ostream &os)const
307 {
308  VFN_DEBUG_MESSAGE("UnitCell::Print()",5)
309  this->InitMatrices();
310  int width =8 ;
311  os << "UnitCell : " << mName <<"("<<this->GetSpaceGroup().GetName()<<")"<< endl;
312  os.width(width);
313  os << " Cell dimensions : "
314  << FormatFloat(this->GetLatticePar(0),8,5) << " "
315  << FormatFloat(this->GetLatticePar(1),8,5) << " "
316  << FormatFloat(this->GetLatticePar(2),8,5) << " "
317  << FormatFloat(this->GetLatticePar(3)*RAD2DEG,8,5) << " "
318  << FormatFloat(this->GetLatticePar(4)*RAD2DEG,8,5) << " "
319  << FormatFloat(this->GetLatticePar(5)*RAD2DEG,8,5) << endl ;
320 }
321 
324 
325 void UnitCell::ChangeSpaceGroup(const string &spgId)
326 {
327  this->GetSpaceGroup().ChangeSpaceGroup(spgId);
328  this->InitRefParList();
329  this->UpdateLatticePar();
330 }
331 
332 
335 
337 {
338  const REAL a=this->GetLatticePar(0);
339  const REAL b=this->GetLatticePar(1);
340  const REAL c=this->GetLatticePar(2);
341  const REAL alpha=this->GetLatticePar(3);
342  const REAL beta=this->GetLatticePar(4);
343  const REAL gamma=this->GetLatticePar(5);
344 
345  return a*b*c*sqrt(1-cos(alpha)*cos(alpha)-cos(beta)*cos(beta)-cos(gamma)*cos(gamma)
346  +2*cos(alpha)*cos(beta)*cos(gamma));
347 }
348 
349 void UnitCell::Init(const REAL a, const REAL b, const REAL c, const REAL alpha,
350  const REAL beta, const REAL gamma,const string &SpaceGroupId,
351  const string& name)
352 {
353  VFN_DEBUG_ENTRY("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name)",10)
354  //mSpaceGroup.Print();
355  mSpaceGroup.ChangeSpaceGroup(SpaceGroupId);
356  //mSpaceGroup.Print();
357  mCellDim(0)=a;
358  mCellDim(1)=b;
359  mCellDim(2)=c;
360  mCellDim(3)=alpha;
361  mCellDim(4)=beta;
362  mCellDim(5)=gamma;
364  this->UpdateLatticePar();
365  if((mCellDim(3)<=0)||(mCellDim(3)>=M_PI)) throw ObjCrystException("alpha must be within ]0;pi[");
366  if((mCellDim(4)<=0)||(mCellDim(4)>=M_PI)) throw ObjCrystException("beta must be within ]0;pi[");
367  if((mCellDim(5)<=0)||(mCellDim(5)>=M_PI)) throw ObjCrystException("gamma must be within ]0;pi[");
368 
371 
372  this->InitRefParList();
373  this->InitMatrices();
374  this->SetName(name);
375 
376  VFN_DEBUG_EXIT("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name):End",10)
377 }
378 
380 {
381  VFN_DEBUG_ENTRY("UnitCell::InitOptions",10)
382  static string ConstrainLatticeToSpaceGroupName;
383  static string ConstrainLatticeToSpaceGroupChoices[2];
384 
385  static bool needInitNames=true;
386  if(true==needInitNames)
387  {
388  ConstrainLatticeToSpaceGroupName="Constrain Lattice to SpaceGroup Symmetry";
389  ConstrainLatticeToSpaceGroupChoices[0]="Yes (Default)";
390  ConstrainLatticeToSpaceGroupChoices[1]="No (Allow Crystallographic Pseudo-Symmetry)";
391 
392  needInitNames=false;//Only once for the class
393  }
394  VFN_DEBUG_MESSAGE("UnitCell::Init(a,b,c,alpha,beta,gamma,Sg,name):Init options",5)
395  mConstrainLatticeToSpaceGroup.Init(2,&ConstrainLatticeToSpaceGroupName,
396  ConstrainLatticeToSpaceGroupChoices);
397  mConstrainLatticeToSpaceGroup.SetChoice(0);
399  VFN_DEBUG_EXIT("UnitCell::InitOptions",10)
400 }
401 
403 {
404  //:NOTE: The Matrices must remain upper triangular, since this is assumed for
405  //optimization purposes in some procedures.
407  &&(mClockMetricMatrix>mSpaceGroup.GetClockSpaceGroup())) return;//no need to update
408  //this->UpdateLatticePar(); we should be able to do this...
409 
410  VFN_DEBUG_MESSAGE("UnitCell::InitMatrices() for crystal : "+this->GetName(),5)
411  //mClockMetricMatrix.Print();
412  //mClockLatticePar.Print();
413 
414  REAL a,b,c,alpha,beta,gamma;//direct space parameters
415  REAL aa,bb,cc,alphaa,betaa,gammaa;//reciprocal space parameters
416  REAL v;//volume of the unit cell
417  a=this->GetLatticePar(0);
418  b=this->GetLatticePar(1);
419  c=this->GetLatticePar(2);
420  alpha=this->GetLatticePar(3);
421  beta=this->GetLatticePar(4);
422  gamma=this->GetLatticePar(5);
423 
424  //cout <<a<<" "<<b<<" "<<c<<" "<<alpha<<" "<<beta<<" "<<gamma<<endl;
425 
426  v=sqrt(1-cos(alpha)*cos(alpha)-cos(beta)*cos(beta)-cos(gamma)*cos(gamma)
427  +2*cos(alpha)*cos(beta)*cos(gamma));
428 
429  aa=sin(alpha)/a/v;
430  bb=sin(beta )/b/v;
431  cc=sin(gamma)/c/v;
432 
433  alphaa=acos( (cos(beta )*cos(gamma)-cos(alpha))/sin(beta )/sin(gamma) );
434  betaa =acos( (cos(alpha)*cos(gamma)-cos(beta ))/sin(alpha)/sin(gamma) );
435  gammaa=acos( (cos(alpha)*cos(beta )-cos(gamma))/sin(alpha)/sin(beta ) );
436 
437  //cout <<aa<<" "<<bb<<" "<<cc<<" "<<alphaa<<" "<<betaa<<" "<<gammaa<<endl;
438 
439  mBMatrix = aa , bb*cos(gammaa) , cc*cos(betaa) ,
440  0 , bb*sin(gammaa) ,-cc*sin(betaa)*cos(alpha),
441  0 , 0 ,1/c;
442  //cout <<"B Matrix :"<<endl<< mBMatrix <<endl;
443 
444  mOrthMatrix = a , b*cos(gamma) , c*cos(beta) ,
445  0 , b*sin(gamma) ,-c*sin(beta)*cos(alphaa),
446  0 , 0 ,1/cc;
447 
448  mOrthMatrixInvert=InvertMatrix(mOrthMatrix);
449  mBMatrixInvert=InvertMatrix(mBMatrix);
450  //cout << "Orth Matrix :"<<endl<<mOrthMatrix <<endl;
451  //cout << "InvOrth Matrix :"<<endl<<mOrthMatrixInvert <<endl;
452  //cout << "Orth * InvOrth matrix :"<<endl<<product(mOrthMatrix,mOrthMatrixInvert) <<endl;
453  //cout << "InvOrth * Orth Matrix :"<<endl<<product(mOrthMatrixInvert,mOrthMatrix) <<endl;
455  VFN_DEBUG_MESSAGE("UnitCell::InitMatrices():End.",5)
456 }
457 
459 {
462  VFN_DEBUG_ENTRY("UnitCell::UpdateLatticePar().",3)
463 
464  int num = mSpaceGroup.GetSpaceGroupNumber();
465  if((num <=2)||(mConstrainLatticeToSpaceGroup.GetChoice()!=0))
466  {
468  return;
469  }
470  if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
471  {
472  mCellDim(4)=M_PI/2.;
473  mCellDim(5)=M_PI/2.;
475  return;
476  }
477  if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
478  {
479  mCellDim(3)=M_PI/2.;
480  mCellDim(5)=M_PI/2.;
482  return;
483  }
484  if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
485  {
486  mCellDim(3)=M_PI/2.;
487  mCellDim(4)=M_PI/2.;
489  return;
490  }
491  if(num <=74)
492  {
493  mCellDim(3)=M_PI/2.;
494  mCellDim(4)=M_PI/2.;
495  mCellDim(5)=M_PI/2.;
497  return;
498  }
499  if(num <= 142)
500  {
501  mCellDim(3)=M_PI/2.;
502  mCellDim(4)=M_PI/2.;
503  mCellDim(5)=M_PI/2.;
504  mCellDim(1) = mCellDim(0) ;
506  return;
507  }
508  if(mSpaceGroup.GetExtension()=='R')
509  {
510  mCellDim(4) = mCellDim(3);
511  mCellDim(5) = mCellDim(3);
512  mCellDim(1) = mCellDim(0);
513  mCellDim(2) = mCellDim(0);
515  return;
516  }
517  if(num <= 194) //||(mSpaceGroup.GetExtension()=='H')
518  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
519  mCellDim(3) = M_PI/2.;
520  mCellDim(4) = M_PI/2.;
521  mCellDim(5) = M_PI*2./3.;
522  mCellDim(1) = mCellDim(0) ;
524  return;
525  }
526  mCellDim(3)=M_PI/2.;
527  mCellDim(4)=M_PI/2.;
528  mCellDim(5)=M_PI/2.;
529  mCellDim(1) = mCellDim(0) ;
530  mCellDim(2) = mCellDim(0) ;
532  VFN_DEBUG_EXIT("UnitCell::UpdateLatticePar().",3)
533  return;
534 }
535 
537 {
538  VFN_DEBUG_ENTRY("UnitCell::InitRefParList()",5)
539  //this->ResetParList();
540  int num = mSpaceGroup.GetSpaceGroupNumber();
541  bool a=true;
542  bool b=true;
543  bool c=true;
544  bool alpha=true;
545  bool beta=true;
546  bool gamma=true;
547  if(mConstrainLatticeToSpaceGroup.GetChoice()==0)
548  {
549  if(num <=2)
550  {
551  }
552  else if((num <=15) && (0==mSpaceGroup.GetUniqueAxis()))
553  {
554  beta=false;
555  gamma=false;
556  }
557  else if((num <=15) && (1==mSpaceGroup.GetUniqueAxis()))
558  {
559  alpha=false;
560  gamma=false;
561  }
562  else if((num <=15) && (2==mSpaceGroup.GetUniqueAxis()))
563  {
564  alpha=false;
565  beta=false;
566  }
567  else if(num <=74)
568  {
569  alpha=false;
570  beta=false;
571  gamma=false;
572  }
573  else if(num <= 142)
574  {
575  b=false;
576  alpha=false;
577  beta=false;
578  gamma=false;
579  }
580  else if(mSpaceGroup.GetExtension()=='R')
581  {//Rhombohedral
582  b=false;
583  c=false;
584  alpha=true;
585  beta=false;
586  gamma=false;
587  }
588  else if(num <= 194)
589  {//Hexagonal axes, for hexagonal and non-rhomboedral trigonal cells
590  b=false;
591  alpha=false;
592  beta=false;
593  gamma=false;
594  }
595  else
596  {
597  b=false;
598  c=false;
599  alpha=false;
600  beta=false;
601  gamma=false;
602  }
603  }
604  REAL *pLatPar=mCellDim.data();
605  if(this->GetNbPar()==0)
606  {//:KLUDGE:
607  {
608  RefinablePar tmp("a",pLatPar,1.,100.,
609  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
610  true,true,a,false,1.0);
611  tmp.SetDerivStep(1e-4);
613  this->AddPar(tmp);
614  }
615  {
616  RefinablePar tmp("b",pLatPar+1,1.,100.,
617  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
618  true,true,b,false,1.0);
619  tmp.SetDerivStep(1e-4);
621  this->AddPar(tmp);
622  }
623  {
624  RefinablePar tmp("c",pLatPar+2,1.,100.,
625  gpRefParTypeUnitCellLength,REFPAR_DERIV_STEP_ABSOLUTE,
626  true,true,c,false,1.0);
627  tmp.SetDerivStep(1e-4);
629  this->AddPar(tmp);
630  }
631  {
632  RefinablePar tmp("alpha",pLatPar+3,.5,3.,
633  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
634  true,true,alpha,false,RAD2DEG);
635  tmp.SetDerivStep(1e-4);
637  this->AddPar(tmp);
638  }
639  {
640  RefinablePar tmp("beta",pLatPar+4,.5,3.,
641  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
642  true,true,beta,false,RAD2DEG);
643  tmp.SetDerivStep(1e-4);
645  this->AddPar(tmp);
646  }
647  {
648  RefinablePar tmp("gamma",pLatPar+5,.5,3.,
649  gpRefParTypeUnitCellAngle,REFPAR_DERIV_STEP_ABSOLUTE,
650  true,true,gamma,false,RAD2DEG);
651  tmp.SetDerivStep(1e-4);
653  this->AddPar(tmp);
654  }
655  }
656  else
657  {//Just Fix the 'used' status
658  this->GetPar(pLatPar+0).SetIsUsed(a);
659  this->GetPar(pLatPar+1).SetIsUsed(b);
660  this->GetPar(pLatPar+2).SetIsUsed(c);
661  this->GetPar(pLatPar+3).SetIsUsed(alpha);
662  this->GetPar(pLatPar+4).SetIsUsed(beta);
663  this->GetPar(pLatPar+5).SetIsUsed(gamma);
664  }
665 
666  VFN_DEBUG_EXIT("UnitCell::InitRefParList():Finished",5)
667 }
668 
669 }
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: doc-main.h:25
Exception class for ObjCryst++ library.
Definition: General.h:122
The crystallographic space group, and the cell choice.
Definition: SpaceGroup.h:105
char GetExtension() const
Extension to space group symbol ('1','2':origin choice ; 'R','H'=rhomboedral/hexagonal)
Definition: SpaceGroup.cpp:470
const string & GetName() const
Get the name of this spacegroup (its name, as supplied initially by the calling program or user)
Definition: SpaceGroup.cpp:235
unsigned int GetUniqueAxis() const
Which is the unique axis (for monoclinic space groups )
Definition: SpaceGroup.cpp:468
int GetSpaceGroupNumber() const
Id number of the spacegroup.
Definition: SpaceGroup.cpp:251
const RefinableObjClock & GetClockSpaceGroup() const
Get the SpaceGroup Clock (corresponding to the time of the initialization of the SpaceGroup)
Definition: SpaceGroup.cpp:466
void ChangeSpaceGroup(const string &spgId)
Change the Spacegroup.
Definition: SpaceGroup.cpp:229
Unit Cell class: Unit cell with spacegroup information.
Definition: UnitCell.h:72
CrystMatrix_REAL mBMatrix
B Matrix (Orthogonalization matrix for reciprocal space)
Definition: UnitCell.h:225
CrystVector_REAL mCellDim
a,b and c in Angstroems, angles (stored) in radians For cubic, rhomboedric UnitCells,...
Definition: UnitCell.h:212
CrystMatrix_REAL mOrthMatrixInvert
inverse of Eucl Matrix (i.e. inverse of de-orthogonalization matrix for direct space)
Definition: UnitCell.h:240
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:251
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 ChangeSpaceGroup(const string &spgId)
Change the spacegroup.
Definition: UnitCell.cpp:325
void MillerToOrthonormalCoords(REAL &x, REAL &y, REAL &z) const
Get Miller H,K, L indices from orthonormal coordinates in reciprocal space.
Definition: UnitCell.cpp:286
CrystMatrix_REAL mOrthMatrix
Eucl Matrix (Orthogonalization matrix for direct space)
Definition: UnitCell.h:238
const RefinableObjClock & GetClockMetricMatrix() const
last time the metric matrices were changed
Definition: UnitCell.cpp:334
REAL GetVolume() const
Volume of Unit Cell (in Angstroems)
Definition: UnitCell.cpp:336
void InitRefParList()
Prepare the refinable parameters list.
Definition: UnitCell.cpp:536
UnitCell()
Default Constructor.
Definition: UnitCell.cpp:33
RefinableObjClock mClockMetricMatrix
Definition: UnitCell.h:245
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:349
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:273
SpaceGroup mSpaceGroup
The space group of the UnitCell.
Definition: UnitCell.h:214
RefinableObjClock mClockLatticePar
Last time lattice parameters were changed.
Definition: UnitCell.h:243
void UpdateLatticePar()
Definition: UnitCell.cpp:458
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
Definition: UnitCell.cpp:86
RefinableObjClock mClockLatticeParUpdate
Definition: UnitCell.h:247
void InitMatrices() const
Definition: UnitCell.cpp:402
const SpaceGroup & GetSpaceGroup() const
Access to the SpaceGroup object.
Definition: UnitCell.cpp:322
~UnitCell()
Destructor.
Definition: UnitCell.cpp:80
const CrystMatrix_REAL & GetOrthMatrix() const
Get the orthogonalization matrix (UnitCell::mOrthMatrix)for the UnitCell in real space.
Definition: UnitCell.cpp:244
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:296
RefObjOpt mConstrainLatticeToSpaceGroup
Option to override lattice parameters constraints from spacegroup choice.
Definition: UnitCell.h:263
CrystMatrix_REAL mBMatrixInvert
inverse of B Matrix (i.e. inverse of orthogonalization matrix for direct space)
Definition: UnitCell.h:227
const CrystMatrix_REAL & GetBMatrix() const
Get the 'B' matrix (UnitCell::mBMatrix)for the UnitCell (orthogonalization matrix for the given latti...
Definition: UnitCell.cpp:237
const RefinableObjClock & GetClockLatticePar() const
last time the Lattice parameters were changed
Definition: UnitCell.cpp:333
virtual void InitOptions()
Init options.
Definition: UnitCell.cpp:379
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:263
We need to record exactly when refinable objects have been modified for the last time (to avoid re-co...
Definition: RefinableObj.h:140
void Reset()
Reset a Clock to 0, to force an update.
void AddChild(const RefinableObjClock &)
Add a 'child' clock.
void Click()
Record an event for this clock (generally, the 'time' an object has been modified,...
Generic class for parameters of refinable objects.
Definition: RefinableObj.h:225
void SetDerivStep(const REAL)
Fixed step to use to compute numerical derivative.
void AssignClock(RefinableObjClock &clock)
void SetIsUsed(const bool)
Is the parameter used (if not, it is simply irrelevant in the model) ?
void AddPar(const RefinablePar &newRefPar)
Add a refinable parameter.
virtual void SetName(const string &name)
Name of the object.
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual const string & GetName() const
Name of the object.
long GetNbPar() const
Total number of refinable parameter in the object.
void AddOption(RefObjOpt *opt)
RefinableObjClock mClockMaster
Master clock, which is changed whenever the object has been altered.
string mName
Name for this RefinableObject. Should be unique, at least in the same scope.+.
output a number as a formatted float: