-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathSpaceGroupIrep.wl
6207 lines (5740 loc) · 358 KB
/
SpaceGroupIrep.wl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(* ::Package:: *)
(* A package for irreducible representations of space group using the conventions in the book of
C.J. Bradley and A.P. Cracknell, "The Mathematical Theory of Symmetry in Solids",
called "the BC book" afterwards. *)
(* Package Name: SpaceGroupIrep *)
(* Author: Gui-Bin Liu *)
(* Package verseion: See the following SpaceGroupIrep`Private`Version *)
(* Mathematica version: >=11.2 *)
(* License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.txt *)
SpaceGroupIrep`Private`Version={1,2,7}; (*Specify version here.*)
With[{p=DirectoryName[$InputFileName]}, If[!MemberQ[$Path,p],AppendTo[$Path, p]]];
BeginPackage["SpaceGroupIrep`", {"AbstractGroupData`", "LittleGroupIrepData`"}]
Unprotect@@Names["SpaceGroupIrep`*"];
ClearAll@@Names["SpaceGroupIrep`*"];
Protect[u,v,w,a,b,c,\[Alpha],\[Beta],\[Gamma],t\:2081,t\:2082,t\:2083];
(* ::Section:: *)
(*Usages of most functions and variables. Another part is in the end of the file.*)
SGSymText::usage="A list of text-version international symbols of space groups.";
SGSymTextBC::usage="A list of text-version space-group international symbols which are consistent "<>
"with the orientations used in the BC book.";
SGSymStd::usage="SGSymStd[sgno] returns the international symbol of the space group with No. sgno. "<>
"If option \"TeX\"->True is used, then the output is in LaTeX format.";
SGSymBC::usage="SGSymBC[sgno] returns the international symbol of the space group with No. sgno "<>
"which is consistent with the orientation in the BC book.";
BCOrientation::usage="Orientation[sgno] returns the orientation used in the BC book for the space group No. sgno.";
SGSymScho::usage="SGSymScho[sgno] returns the Schoenflies symbol of the space group with No. sgno. "<>
"Option \"TeX\"->True will output LaTeX format, and option \"full\"->True will output the full symbol "<>
"with the type of Bravais lattice, such as \!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(o\), \(v\)]\)\!\(\*TemplateBox[{\"D\",\"2\",\"8\"},\n\"Subsuperscript\"]\) for SG 23.";
showSGSym::usage="showSGSym[listOrSpan] returns a table of space group symbols and numbers specified "<>
"by listOrSpan. If listOrSpan is omitted, all 230 space groups are output. An option \"ncol\" can be "<>
"used to specify the number of columns in a row. For example: showSGSym[11;;34,\"ncol\"->8]";
PGinfo::usage="PGinfo stores the information of the 32 point groups.";
showPGinfo::usage="showPGinfo[] shows the information of the 32 point groups. Default options are "<>
"\"long\"->True, \"color\"->True, and \"double\"->False.";
JonesSymbol::usage="A list for Jones symbol, including rotation names, Jones symbols and rotation matrices.";
getJones::usage="Two usages, e.g:\n getJones[rotName,\"type\"->type] returns Jones symbol when type"<>
"=\"xyz\" and rotation matrix when type=\"mat\".\n getJones[xyzOrRotMat, p2] return the rotation "<>
"name of given Jones symbol or rotation matrix xyzOrRotMat and p2 is either \"c\" for cubic or "<>
"\"h\" for hexagonal or the space group number.";
BravLatt::usage="An association from 1-14 to corresponding Bravais lattices.";
iBravLatt::usage="An association from Bravais lattices to their indices 1-14.";
BravLattSymb::usage="An association from 1-14 to corresponding symbols of Bravais lattices.";
BasicVectors::usage="An association from Bravais lattices to their basic vectors defined in Tab 3.1 of the BC book.";
JonesTM::usage="An association from each Bravais lattice to a transformation matirx which transforms "<>
"the lattice basic vectors defining Jones' symbol to the ones defined in Tab 3.1 of the BC book.";
getSGLatt::usage="getSGLatt[sgno] returns the Bravais lattice of space group No. sgno.";
checkBasVec::usage="checkBasVec[brav,basvec] checks whether basvec is the basic vectors of the form in "<>
"BC Tab.3.1. It also calculates the BZ type. The return value is a list of the form {True,\"a\",{a->2,c->3}}";
RotMat::usage="RotMat[[1]] associates Bravais lattice to their available rotation names.\n"<>
"RotMat[[2]] associates Bravais lattice to their available rotation matrices.";
checkRotMat::usage="checkRotMat[brav] shows the result of RotMat applied on basic vectors (t1,t2,t3) "<>
"in table form like BC Tab. 3.2.";
getRotMat::usage="getRotMat[brav,rotname] returns the rotation matirx of rotname for Bravais lattice brav.";
getRotName::usage="getRotName[brav,rotmat] returns the rotation name of the matrix rotmat for Bravais lattice brav.";
getRotMatOfK::usage="getRotMatOfK[brav,rotname] returns the rotation matirx in reciprocal space "<>
"(for wave vector k) of rotname for Bravais lattice brav.";
RotMatCart::usage="RotMatCart[rotname] returns the rotation matrix of rotname in cartesian coordinate system.";
checkRotMatOfK::usage="checkRotMatOfK[brav] shows the result of rotation matrix in reciprocal space "<>
"applied on reciprocal basic vectors (g1,g2,g3) in table form like BC Tab. 3.4.";
TMspglibToBC::usage="TMspglibToBC[brav] gives transformation matrix and rotation matrix "<>
"{Q,S1} which transforms the idealized standard basic "<>
"vectors (as',bs',cs') from spglib to the ones (t1_BC2', t2_BC2', t3_BC2') of the second line "<>
"in BC Tab. 3.7. Note that the vectors here are COLUMN vectors. "<>
"The relation is:\n (t1_BC2', t2_BC2', t3_BC2')=S1.(as',bs',cs').Q";
getQandS::usage="getQandS[SGNo] gives {Q,S} where Q is just TMspglibToBC[SGNo][[1]] and S=S2.S1. "<>
"Here S2 is a rotation matrix which together with transformation matirx U converts the "<>
"basic vectors of the second line to the ones of the first line in BC Tab 3.7 and U is "<>
"given by SGGenElem. The relation is:\n(t1_BC1', t2_BC1', t3_BC1')=S2.(t1_BC2', t2_BC2', t3_BC2').U";
SGGenElem::usage="SGGenElem[SGNo] gives information of the space group SGNo given in the BC Tab. 3.7 "<>
"including generating elements of the two lines (if the second line exists) and the orgion shift "<>
"and transformation matrix U between the two lines. Note that some informations of several space groups"<>
" are revised which are different from BC Tab. 3.7.";
BCHighSymKpt::usage="BCHighSymKpt is an association. \nKeys are full BZ types such as \"OrthPrim\", \"OrthBase(a)\", .... "<>
"\nAnd values are informations of the high-symmetry k points given in BC Tab. 3.6.";
showBCHSKpt::usage="showBCHSKpt[fullBZtype] shows the informations of BCHighSymKpt[fullBZtype] in table form.";
checkBCHSKpt::usage="checkBCHSKpt[fullBZtype] checks whether informations of BCHighSymKpt satisfy necessary condition.";
kBCcoord::usage="kBCcoord[bravORsgno, kname] gives the k-point coordinates and corresponding BZs according to kname. "<>
"bravORsgno can be either the Bravais lattice or the SG number.";
WSCell3DMesh::usage="WSCell3DMesh[recilatt] returns a BoundaryMeshRegion object whichs is the Wigner-Seitz "<>
"cell of the reciprocal lattice recilatt. ";
findURange::usage="findURange[fullBZtype, basVec, kname] retruns the range of u of a high-symmetry k line named "<>
"kname for fullBZtype with basic vectors basVec.";
showBZDemo::usage="showBZDemo[fullBZtype] or showBZDemo[fullBZtype, basVec]\nshows the Brillouin zone of fullBZtype. "<>
"Basic vectors basVec is optional.";
keqmod::usage="keqmod[k1,k2,prec] judges whether two wave vectors k1 and k2 are equivalent. The precision prec "<>
"is optional, which is 1*^-5 by default. The two k points are of fractional coordinations.";
identifyBCHSKpt::usage="identifyBCHSKpt[fullBZtype, kOrKlist] identifies the k-point name of fullBZtype from its "<>
"coordinates according to informations of BCHighSymKpt. Note that kOrKlist is numerical and can be coordinates "<>
"of either a k point or a list of k points. And for k points on some k lines, two entries with different knames "<>
"may be retruned.";
doubleKuMax::usage="doubleKuMax[fullBZtype] gives {umax, the lower limit of umax, the upper limit of umax} "<>
"in which umax is the max u values which make the k points lie within or on the "<>
"boundary of the BZ for the k points which can be identified as two knames.";
identifyBCHSKptBySG::usage="identifyBCHSKptBySG[sgno, BZtypeOrBasVec, kOrKlist] identifies the kname of kOrKlist "<>
"for certain space group sgno. BZtypeOrBasVec is either the type of BZ (\"a\",\"b\",\"c\",\"d\",or just \"\") "<>
"or the basic vectors for determining the BZtype. kOrKlist is numerical and can be coordinates of either a k "<>
"point or a list of k points. Note that if only BZtype is given, the range of u, i.e. (0,umax), may "<>
"be incorrect for some k lines because in these cases umax depends on lattice constants without which umax can "<>
"not be determined and is assigned a makeshift value 1/4. But if basic vectors are given then the range of u can "<>
"be determined correctly. With default option, this function returns one entry of information with only one kname. "<>
"But if the option \"allowtwok\"->True is used, when only BZtype is given, this function will return two entries of "<>
"information with different knames in the cases with umax depneding on lattice constants.";
SeitzTimes::usage="Usages:\nSeitzTimes[{R1,v1}, {R2,v2}] OR\nSeitzTimes[{R1,v1}, ..., {Rn,vn}] OR\n"<>
"SeitzTimes[brav][{Rname1,v1}, {Rname2,v2}] OR\nSeitzTimes[brav][{Rname1,v1}, ..., {Rnamen,vn}]\n"<>
"Multiplication of two or more space group operations. R1, R2, and Rn are rotation matrices, while Rname1, Rname2, and "<>
"Rnamen are the names of the rotations. For the last two usages, the Bravais lattice brav has to be given.";
invSeitz::usage="Two usages: invSeitz[{R,v}] or invSeitz[brav][{Rname,v}] gives the inverse of the space "<>
"group operation {R,v} or {Rname,v}.";
powerSeitz::usage="Two usages: powerSeitz[{R,v},n] or powerSeitz[brav][{Rname,v},n] gives {R,v}^n or {Rname,v}^n";
RotTimes::usage=""; (*This usage definition is postponed. But the symbol RotTimes also have to be declared to make it public.*)
powerRot::usage="powerRot[Rname,n] returns the n-th power of a rotation by its name string.";
invRot::usage="invRot[Rname] returns the inverse of a rotation by its name string.";
DRotTimes::usage=""; (*Real usage definition is moved to the end.*)
powerDRot::usage="powerDRot[Rname,n] returns the n-th power of a double-point-group rotation by its name string.";
invDRot::usage="invDRot[Rname] returns the inverse of a double-point-group rotation by its name string.";
CentExtTimes::usage="CentExtTimes[brav,adict][{R1,alpha},{R2,beta}] multiplies two elements {R1,alpha} and "<>
"{R2,beta} of a central extension of little cogroup according to adict which is given by aCentExt. R1 and R2 "<>
"are either rotation matrices or rotation names.";
CentExtPower::usage="CentExtPower[brav,adict][{R,alpha},n] gives {R,alpha}^n for a central extension of "<>
"little cogroup, where R is either a rotation matrix a rotation name.";
getSpinRotOp::usage="getSpinRotOp[Rname] gives the rotation operation {srot,o3det} of Rname in double space group "<>
"where srot is the SU(2) matrix and o3det is the determinant of corresponding O(3) matrix of Rname. In fact, "<>
"getSpinRotOp is an association.";
getSpinRotName::usage="getSpinRotName[brav,{srot, o3det}] gives the double space group rotation name of {srot, o3det} "<>
"for Bravais lattice brav. In fact brav here is only used to distinguish hexagonal or trigonal lattices from other "<>
"lattices. Here srot is SU(2) matrix and o3det is the determinant of corresponding O(3) matrix.";
SpinRotTimes::usage="Two usages:\nSpinRotTimes[{srot1,o3det1},{srot2,o3det2}] or SpinRotTimes[brav][rotname1, rotname2]\n"<>
"Multiplication between two double space group rotations.";
DSGSeitzTimes::usage="DSGSeitzTimes[brav][{Rname1,v1}, {Rname2,v2}] OR\n"<>
"DSGSeitzTimes[brav][{Rname1,v1}, ..., {Rnamen,vn}]\n"<>
"calculates the multiplication of two or more elements of double space group.";
DSGpowerSeitz::usage="DSGpowerSeitz[brav][{Rname,v},n] gives {Rname,v}^n for double space group.";
DSGinvSeitz::usage="DSGinvSeitz[brav][{Rname,v}] gives the inversion of double space group operation {Rname,v}.";
DSGCentExtTimes::usage="DSGCentExtTimes[brav,adict][{Rname1,alpha},{Rname2,beta}] multiplies two elements {Rname1,alpha} and "<>
"{Rname2,beta} of a central extension of little cogroup of double space group according to adict which is given by aCentExt "<>
"with option \"DSG\"->True. ";
DSGCentExtPower::usage="DSGCentExtPower[brav,adict][{Rname,alpha},n] gives {Rname,alpha}^n for a central extension of "<>
"little cogroup for double space group.";
rotAxisAngle::usage="rotAxisAngle[O3RotMat] gives the rotation axis and angle of an O(3) rotation matrix O3RotMat.";
getKStar::usage="getKStar[sgno,kin] gives the star of kin for space group sgno. kin can be the coordinates or name of the "<>
"k-point. Option \"cosets\"->True (default: False) will also gives the cosets.";
generateGroup::usage="generateGroup[gens,identityElement,multiply] gives all the elements of a group according to its "<>
"generators, identity element, and multiplication. If the option \"generationProcess\"->True is used, the process of "<>
"generating each element is given in the form of multiplication sequence of generators.";
modone::usage="modone[x] is my version of Mod[x,1] in which x can be anything. For non-numeric quantity nothing is done.";
seteq::usage="seteq[s1,s2] judges whether sets s1 is equal to s2.";
getHLGElem::usage="Two usages: getHLGElem[brav,{m,n},gens] or getHLGElem[sgno,kname]\nThe first one gives the Herring "<>
"little group according to the abstract group G_m^n and generators given in BC Tab. 5.7 or 6.13. Bravais lattice is needed. "<>
"The second one gives the Herring little group according to sgno and kname directly. "<>
"For double space group the option \"DSG\"->True is needed.";
getLGElem::usage="getLGElem[sgno,k] gives the little group of k for space gorup sgno. In fact this is only the coset "<>
"representatives with respect to the translation group. k can be either its name or coordinates. For double space group the "<>
"option \"DSG\"->True is needed."
getSGElem::usage="getSGElem[sgno] gives the elements of space group sgno. This is equivalent to getLGElem[sgno,\"\[CapitalGamma]\"]. "<>
"In fact, it gives the coset representatives with respect to the translation group. For double space group, the option "<>
"\"DSG\"->True is needed.";
aCentExt::usage="Three usages:\naCentExt[sgno,kname,BZtype] or aCentExt[sgno,kname] or aCentExt[brav,Gk,k]\n"<>
"This function gives the a(Hj,Hk) in the BC eq.(3.7.27) for central extension of little cogroup. kname is a string "<>
"and k is coordinates. Gk is little group. If BZtype is not given, it is \"a\" by default. For double space group the "<>
"option \"DSG\"->True is needed."
getCentExt::usage="getCentExt[sgno,kname] returns the central extension of little cogroup of kname for space group sgno. "<>
"For double space group the option \"DSG\"->True is needed.";
getSGElemAndSQ::usage="getSGElemAndSQ[sgno] returns three sets {G,S,Q} in which G is all coset representatives of the "<>
"space group G with respect to its translation subgroup, S consists of g elements which satisfy g.G.g^-1==G, and Q "<>
"is used for debug.";
detPointGroup::usage="detPointGroup[rots] determinates the name of a point group according to the set of rotations rots "<>
"which can be either set of rotation matrices and rotation names.";
reduceRep::usage="reduceRep[{m,n},chars] gives the number of times of each irreducible representation occuring in the "<>
"characters chars of the abstract group G_m^n. chars is a list of characters for each class of G_m^n in the same order "<>
"of the character table in the BC Tab. 5.1.";
calcRep::usage="calcRep[sgno,kinfo] is used to get the irep infos for \"GP\" and \"UN\" kpoints which are not given in the "<>
"BC book. For the kpoints whose irep infos are given in the BC book (i.e. BC Tab. 5.7 and 6.13), this function is only "<>
"used for checking purpose.";
str2Mulliken::usage=""; (*Real usage definition is moved to the end.*)
Mulliken2str::usage=""; (*Real usage definition is moved to the end.*)
str2GammaLabel::usage=""; (*Real usage definition is moved to the end.*)
GammaLabel2str::usage=""; (*Real usage definition is moved to the end.*)
LGIrepLabel::usage="LGIrepLabel[{m,n}] gives the informations of BC Tab. 5.8.";
DLGIrepLabel::usage="DLGIrepLabel[{m,n}] gives the informations of BC Tab. 6.14.";
showRepLabel::usage="showRepLabel[{m,n},dsgtag] gives the table like BC Tab. 5.8 (for dsgtag=\"s\" which is default) or Tab. 6.14 "<>
"(for dsgtag=\"d\" or \"D\") for checking purpose.";
showLGIrepLabel::usage="showLGIrepLabel[{m,n}] gives the table like BC Tab. 5.8, which is equivalent to showRepLabel[{m,n},\"s\"]";
showDLGIrepLabel::usage="showDLGIrepLabel[{m,n}] gives the table like BC Tab. 6.14, which is equivalent to showRepLabel[{m,n},\"d\"]";
formatRepMat::usage="formatRepMat[mat] is used to format the matrix elements of mat.";
mapLGIrepLabel::usage="mapLGIrepLabel[sgno,kname] gives the correspondence/mapping between the abstract-group irep label, "<>
"the extended Mulliken label, and the Gamma label for the LG ireps of kname. If kname is not designated, all k-points of the "<>
"space group sgno are used. Option \"DSG\"->True can be used for double-valued ireps.";
getPGElem::usage="getPGElem[pg] gives the elements of the point group pg. Default option is \"double\"->False.";
getPGCharTab::usage="getPGCharTab[pg] gives the character table of point group pg. pg can be the sequence number or the name string "<>
"of a point group, e.g. 14, or \"D2d\", or \"-42m\". Full list can be obtained by showPGinfo[], or by triggering a tip via a wrong "<>
"input such as getPGCharTab[0]. When the option \"double\"->True is used, the character table of the corresponding double "<>
"point group is given. For single-valued ireps, both the Mulliken labels and Gamma labels are consitent with the ones "<>
"in the Table 2.2 in the BC book, while the double-valued irep labels are consistent with those in the table 6.5 in the BC book.";
showPGCharTab::usage="showPGCharTab[pg] shows the character table of point group pg in a user-friendly table form. Default "<>
"options are \"double\"->False, \"mode\"->4, \"class\"->Automatic, \"elem\"->All, \"irep\"->All, and \"linewidth\"->2. "<>
"For available values of the input argument pg and the options \"mode\", \"class\", \"elem\", and \"irep\", tips will be "<>
"triggered by a wrong input, e.g. \"class\"->0.";
getPGIrepTab::usage="getPGIrepTab[pg] gives the table of irep matrices for point group pg. Default options "<>
"are \"double\"->False and \"trace\"->False. For available values of the input argument pg and the option \"double\" "<>
"tips will be triggered by a wrong input, e.g. \"double\"->0. In this function, \"double\" can be True, False, and Full.";
showPGIrepTab::usage="showPGIrepTab[pg] shows the table of irep matrices for point group pg in a user-friendly table form. "<>
"Default options are \"double\"->True, \"rotmat\"->True, \"elem\"->All, \"irep\"->All, \"trace\"->False, \"spin\"->"<>
"\"downup\", \"cartesian\"->False, and \"linewidth\"->2. For available values of the input argument pg and the options "<>
"\"double\", \"elem\", and \"irep\", tips will be triggered by a wrong input, e.g. \"double\"->0. In this function, "<>
"\"double\" can be True, False, and Full.";
PGIrepDirectProduct::usage="PGIrepDirectProduct[pg, ireps1, ireps2] gives the direct products between ireps1 and "<>
"ireps2 for point group pg. ireps1 and ireps2 are both optional. If ireps2 is omitted, it takes the same value "<>
"as ireps1, and if both of them are omitted, they both take the vaule All. The output styles 1-4 can be controlled "<>
"by the option \"output\" with default value 1. For available values of the input arguments pg, ireps1, and ireps2, "<>
"and the option \"output\", tips will be triggered by a wrong input, e.g. \"output\"->0. Note that both single-valued "<>
"and double-valued ireps are calculated.";
showPGIrepDirectProduct::usage="showPGIrepDirectProduct[pg, ireps1, ireps2] shows the direct products between ireps1 and "<>
"ireps2 for point group pg in a user-friendly table form. ireps1 and ireps2 are both optional. If ireps2 is omitted, "<>
"it takes the same value as ireps1, and if both of them are omitted, they both take the vaule All. Default options "<>
"are \"label\"->1 (1 for Mulliken labels and 2 for Gamma labels), \"double\"->True, \"linewidth\"->2, and \"emph\"->None. "<>
"For available values of the input arguments pg, ireps1, and ireps2, and the option \"emph\", tips will be triggered "<>
"by a wrong input, e.g. \"emph\"->0. Note that both single-valued and double-valued ireps are shown by default, and "<>
"only single-valued ireps are shown when \"double\"->False is used.";
getLGIrepTab::usage="getLGIrepTab[sgno, k] gives the data for showing the irep table of the little group of k for "<>
"space group sgno. k can be either its name or coordinates. Option \"abcOrBasVec\"->None is default, and if "<>
"None is replaced by the basic vectors, specific BZ type is selected.";
getLGCharTab::usage="getLGCharTab[sgno, k] gives the character table of the k little group of space group sgno, "<>
"other infomation is the same as getLGIrepTab[sgno, k].";
LGIRtwokRelation::usage="LGIRtwokRelation[repinfos] or LGIRtwokRelation[sgno,k] gives the correspondence of "<>
"the LGIR labels between two knames if repinfos=getLGCharTab[sgno,k] has two items. The returned value is an "<>
"association.";
checkLGIrep::usage="checkLGIrep[repinfo] checks whether the representation matrices in the result of getLGIrepTab "<>
"satisfy correct multiplications for LG IR. repinfo is the returned value of getLGIrepTab. Things are all right "<>
"if all the returned numbers are zero."
getRepMat::usage="getRepMat[k,Gk,rep][RvOrRvList] get the representation matrix(es) (or character(s)) of the "<>
"element or list of elements RvOrRvList. k is the k-point coordinates. Gk is the list of LG elements. rep is "<>
"the representation matrices (or characters) of Gk. rep can be for one representation or a list of representations.";
getLGIrepMat::usage="getLGIrepMat[repinfo,IRids][RvOrRvList] get the representation matrix(es) (or character(s)) "<>
"of the element or list of elements RvOrRvList "<>
"according to repinfo which returned by getLGIrepTab (or getLGCharTab). repinfo can be the List of Association "<>
"returned by getLGIrepTab (or getLGCharTab) (in this case the first Association is used) or one Association in "<>
"the List. IRids indicates the index(es) of the requested representations, such as 2 or {2,3,4}. IRids is optional, "<>
"and if it is omitted all representations are processed. An option \"uNumeric\" is available which is False by default.";
showRot::usage="shotRot[rotName] shows the symbol of the rotName string. Similar to showSeitz but only for the rotation part.";
showSeitz::usage="showSeitz[{Rname,v}] shows the Seitz symbol of {Rname,v}. Options: \"format\" can be \"std\""<>
"(default), \"simple\", or \"TeX\"; \"fullbar\" is True by default.";
showLGIrepTab::usage="showLGIrepTab[sgno, k] shows the table of ireps of k little group of space group sgno in "<>
"table form. Default options of this function are \"uNumeric\"->False, \"irep\"->All, \"elem\"->All, "<>
"\"rotmat\"->True, \"trace\"->False, \"spin\"->\"downup\", \"abcOrBasVec\"->None, and \"linewidth\"->2.";
showLGCharTab::usage="showLGCharTab[sgno, k] shows the character table of k little group of space group sgno in "<>
"table form. Default options of this function are \"uNumeric\"->False, \"irep\"->All, \"elem\"->All, "<>
"\"rotmat\"->True, \"spin\"->\"downup\", \"abcOrBasVec\"->None, and \"linewidth\"->2.";
getSGIrepTab::usage="getSGIrepTab[sgno, k] gives the space group ireps of k star for space group sgno. "<>
"k can be either its name or coordinates. Option \"abcOrBasVec\"->None is default, and if "<>
"None is replaced by the basic vectors, specific BZ type is selected.";
showSGIrepTab::usage="showSGIrepTab[sgno, k] shows the space group ireps of k star for space group sgno in "<>
"table form. Default options of this function are \"uNumeric\"->False, \"irep\"->All, \"elem\"->All, "<>
"\"rotmat\"->True, \"maxDim\"->4, \"trace\"->False, \"spin\"->\"downup\", \"abcOrBasVec\"->None, and \"linewidth\"->2.";
getFullRepMat::usage="getFullRepMat[G,rep][RvOrRvList] get the SG IR matrix(es) (or character(s), if "<>
"option \"trace\"->True is used) of the element or list of elements RvOrRvList. G is the list of SG elements. rep is "<>
"the representation matrices of G. rep can be for one representation or a list of representations. This function also "<>
"works for magnetic space group and corepresentations.";
getSGIrepMat::usage="getSGIrepMat[repinfo,IRids][RvOrRvList] get the representation matrix(es) (or character(s)) "<>
"of the element or list of elements RvOrRvList according to repinfo which returned by getSGIrepTab. repinfo can be "<>
"the List of Association returned by getSGIrepTab (in this case the first Association is used) or one Association in "<>
"the List. IRids indicates the index(es) of the requested representations, such as 2 or {2,3,4}. IRids is optional, "<>
"and if it is omitted all representations are processed. Options \"uNumeric\" and \"trace\" are available which "<>
"are both False by default.";
checkSGIrep::usage="checkSGIrep[repinfo] checks whether the representation matrices in the result of getSGIrepTab "<>
"satisfy correct multiplications for SG IR. repinfo is the returned value of getSGIrepTab. Things are all right "<>
"if all the returned numbers are zero.";
generateLibLGIrep::usage="generateLibLGIrep[filename] is used to generate a MX file which stores LG IRs "<>
"for all named k's. The argument filename is optional and is \"libLGIrep.mx\" (under Directory[]) by default.";
SGIrepDirectProduct::usage="SGIrepDirectProduct[sgno, kin1, kin2] calculates the decomposition of the "<>
"direct product of the SG ireps of kin1 star and SG ireps of kin2 star. The input k-point (kin1 or kin2) can "<>
"be either its name (only for high-symmetry k-points not k-lines) or its numeric coordinates. Option \"abcOrBasVec\"->None "<>
"is default, and if None is replaced by the basic vectors, specific BZ type is selected.";
showSGIrepDirectProduct::usage="showSGIrepDirectProduct[sgno, kin1, kin2] shows the decomposition of the "<>
"direct product of the SG ireps of kin1 star and SG ireps of kin2 star. The input k-point (kin1 or kin2) can "<>
"be either its name (only for high-symmetry k-points not k-lines) or its numeric coordinates. Default options are "<>
"\"label\"->1, \"abcOrBasVec\"->None, \"linewidth\"->2.";
readVasp2trace::usage="readVasp2trace[filename] reads the trace.txt file generated by vasp2trace. filename is "<>
"the path to trace.txt file.";
getBandRep::usage="Three usages:\ngetBandRep[sgno, BZtypeOrBasVec, traceData, ikOrListOrSpan, ibOrListOrSpan]\n"<>
"getBandRep[sgno, BZtypeOrBasVec, traceData, ikOrListOrSpan]\ngetBandRep[sgno, BZtypeOrBasVec, traceData]\n"<>
"This function gives the little-group ireps of the Bloch states for the k points specified by ikOrListOrSpan "<>
"and bands specified by ibOrListOrSpan. If ikOrListOrSpan and ibOrListOrSpan are not specified, ireps of "<>
"all k points and all bands are given. traceData is the result of readVasp2trace. Note that if the trace.txt "<>
"file is generated using a BC standard cell the traceData can be directly used by getBandRep; but if the cell "<>
"is not of BC standard then the traceData has to be converted to BC standard by convTraceToBC before being "<>
"used by getBandRep. BZtypeOrBasVec can be BZtype (\"a\", \"b\", \"c\", \"d\", \"\") or basic vectors and if "<>
"it is basic vectors then the names of some high-symmetry k lines can be identified correctly.";
showBandRep::usage="showBandRep[rep, ik, ibOrListOrSpan] shows the small reps (LG IRs) at the ik-th k-point for the bands "<>
"specified by ibOrListOrSpan. If ibOrListOrSpan is omitted, all bands at the k-point are shown. rep is the returned "<>
"value of getBandRep[sgno, BZtypeOrBasVec, tr]. Default option is \"bottomUp\"->True which means that the band energy "<>
"increases from the bottom up in the table shown."
convTraceToBC::usage="convTraceToBC[sgno,traceData,P,p0,stdR] converts traceData from non-BC standard to BC "<>
"standard for getBandRep to determinate little group ireps. P, p0, and stdR are respectively "<>
"dataset['transformation_matrix'], dataset['origin_shift'] and dataset['std_rotation_matrix'] "<>
"from spglib acting on the initial cell. For non-SOC case stdR is not needed but for SOC case "<>
"stdR has to be given.";
readPOSCAR::usage="readPOSCAR[filename] reads the VASP structure file POSCAR.";
spglibGetSym::usage="spglibGetSym[{basVec,pos,atnum}] calls external python package spglib to "<>
"give symmetry data for cell {basVec,pos,atnum}, including P, p0, and stdR used by convTraceToBC. "<>
"basVec is basic vectors of the cell, pos is a list of fractional coordinates of all atoms "<>
"in the cell, and atnum is a list of atomic numbers for all atoms.";
autoConvTraceToBC::usage="autoConvTraceToBC[poscarFile,traceData,prec] converts trace data to "<>
"BC standard automatically according to POSCAR file and corresponding traceData. prec is optional "<>
"and is 1*^-5 by default. This function calls spglibGetSym and hence needs external python package spglib. "<>
"Note that the output is different if the option \"cellData\"->True is used, and in this case it is output[\"trace\"] "<>
"that has the same data structure with traceData and should be used in getBandRep function.";
allBCSkLGdat::usage="allBCSkLGdat contains all little-groups ireps data of all space groups under BCS convention.";
kptBCStoBC::usage="kptBCStoBC[sgno, BZtype] gives correspondence between k points of BCS convention "<>
"and BC convention. BZtype is optional and is \"a\" by default.";
showKptBCStoBC::usage="showKptBCStoBC[sgno, BZtype] shows correspondence between k points of BCS convention "<>
"and BC convention in talbe form. BZtype is optional and is \"a\" by default.";
buildTr4BCSrep::usage="buildTr4BCSrep[sgno, BZtype] builds traceData from BCS ireps data and converts them "<>
"to BC convention which can be used by getBandRep. For double space group the option \"DSG\"->True is needed.";
krepBCStoBC::usage="krepBCStoBC[sgno, BZtype] gives correspondence between little-gorup ireps of BCS convention "<>
"and BC convention. BZtype is optional and is \"a\" by default. For double space group the option \"DSG\"->True is needed.";
showKrepBCStoBC::usage="showKrepBCStoBC[sgno, BZtype] shows correspondence between little-gorup ireps of BCS convention "<>
"and BC convention in talbe form. BZtype is optional and is \"a\" by default. For double space group the option \"DSG\"->True is needed."
Begin["`Private`"]
(* ::Section:: *)
(*Space group symbols*)
SGSymText={"P1", "P-1", "P2", "P21", "C2", "Pm", "Pc", "Cm", "Cc", "P2/m",
"P21/m", "C2/m", "P2/c", "P21/c", "C2/c", "P222", "P2221", "P21212", "P212121", "C2221",
"C222", "F222", "I222", "I212121", "Pmm2", "Pmc21", "Pcc2", "Pma2", "Pca21", "Pnc2",
"Pmn21", "Pba2", "Pna21", "Pnn2", "Cmm2", "Cmc21", "Ccc2", "Amm2", "Aem2", "Ama2",
"Aea2", "Fmm2", "Fdd2", "Imm2", "Iba2", "Ima2", "Pmmm", "Pnnn", "Pccm", "Pban",
"Pmma", "Pnna", "Pmna", "Pcca", "Pbam", "Pccn", "Pbcm", "Pnnm", "Pmmn", "Pbcn",
"Pbca", "Pnma", "Cmcm", "Cmce", "Cmmm", "Cccm", "Cmme", "Ccce", "Fmmm", "Fddd",
"Immm", "Ibam", "Ibca", "Imma", "P4", "P41", "P42", "P43", "I4", "I41",
"P-4", "I-4", "P4/m", "P42/m", "P4/n", "P42/n", "I4/m", "I41/a", "P422", "P4212",
"P4122", "P41212", "P4222", "P42212", "P4322", "P43212", "I422", "I4122", "P4mm", "P4bm",
"P42cm", "P42nm", "P4cc", "P4nc", "P42mc", "P42bc", "I4mm", "I4cm", "I41md", "I41cd",
"P-42m", "P-42c", "P-421m", "P-421c", "P-4m2", "P-4c2", "P-4b2", "P-4n2", "I-4m2", "I-4c2",
"I-42m", "I-42d", "P4/mmm", "P4/mcc", "P4/nbm", "P4/nnc", "P4/mbm", "P4/mnc", "P4/nmm", "P4/ncc",
"P42/mmc", "P42/mcm", "P42/nbc", "P42/nnm", "P42/mbc", "P42/mnm", "P42/nmc", "P42/ncm", "I4/mmm", "I4/mcm",
"I41/amd", "I41/acd", "P3", "P31", "P32", "R3", "P-3", "R-3", "P312", "P321",
"P3112", "P3121", "P3212", "P3221", "R32", "P3m1", "P31m", "P3c1", "P31c", "R3m",
"R3c", "P-31m", "P-31c", "P-3m1", "P-3c1", "R-3m", "R-3c", "P6", "P61", "P65",
"P62", "P64", "P63", "P-6", "P6/m", "P63/m", "P622", "P6122", "P6522", "P6222",
"P6422", "P6322", "P6mm", "P6cc", "P63cm", "P63mc", "P-6m2", "P-6c2", "P-62m", "P-62c",
"P6/mmm", "P6/mcc", "P63/mcm", "P63/mmc", "P23", "F23", "I23", "P213", "I213", "Pm-3",
"Pn-3", "Fm-3", "Fd-3", "Im-3", "Pa-3", "Ia-3", "P432", "P4232", "F432", "F4132",
"I432", "P4332", "P4132", "I4132", "P-43m", "F-43m", "I-43m", "P-43n", "F-43c", "I-43d",
"Pm-3m", "Pn-3n", "Pm-3n", "Pn-3m", "Fm-3m", "Fm-3c", "Fd-3m", "Fd-3c", "Im-3m", "Ia-3d"};
SGSymTextBC=SGSymText;
SGSymTextBC[[{5,7,8,9,12,13,14,15}]]={"B2","Pb","Bm","Bb","B2/m","P2/b","P21/b","B2/b"};
SGSymTextBC[[{17,19,28,29,31,33,36,38,39,40,41,46,51,52,53,54,57,60,61,70,122}]]={
"P2221", "P212121", "Pbm2", "Pbc21", "Pnm21", "Pbn21", "Ccm21", "Cm2m", "Cm2e", "Cc2m",
"Cc2e", "Ibm2", "Pcmm", "Pnan", "Pnmb", "Pcaa", "Pbma", "Pcnb", "Pcab", "Fddd", "I-42d"};
(* Note that for 17,19,70,122, the SG symbols do not change. In fact, these is no need to
change the orientation and only change of origin is needed for these four SGs. *)
Options[SGSymStd]={"TeX"->False, "BC"->False};
SGSymStd[sgno_Integer, OptionsPattern[]]/;1<=sgno<=230:=
Module[{symtext,chs,c,L,s1,s2,s3,j,tmp,bar,sub,tex},
tex=(OptionValue["TeX"]===True);
sub[s1_,s2_]:=If[tex, s1<>"_"<>s2, Subscript[s1,s2]];
bar[s1_]:=If[tex, "\\bar{"<>s1<>"}", OverBar[s1]];
symtext=If[OptionValue["BC"], SGSymTextBC[[sgno]], SGSymText[[sgno]]];
chs=Characters[symtext]; L=chs[[1]]; chs=chs[[2;;]];
c=If[chs[[1]]!="-",chs[[1]],chs[[2]]];
tmp=Position[chs,"/"]; If[tmp!={},tmp=tmp[[1,1]]];
If[tmp=!={},
If[tmp==2,s1=StringJoin@@chs[[;;tmp+1]],
s1=If[tex,StringJoin,Row][{sub[chs[[1]],chs[[2]]],"/",chs[[4]]}]
];
If[Length[chs]>tmp+1, {s2,s3}=chs[[tmp+2;;]], s2=s3=""],
(*--------else, no / ---------*)
If[chs[[1]]=="-",
s1=bar[chs[[2]]];
Switch[Length[chs[[3;;]]], 0, s2=s3="", 1, s2=chs[[3]];s3="",
2, s2=chs[[3]];s3=chs[[4]], 3, s2=sub[chs[[3]],chs[[4]]];s3=chs[[5]]],
(*------else, chs[[1]]\[NotEqual]"-" --------*)
Switch[Length[chs],
1, s1=chs[[1]]; s2=s3="",
2, If[L=="R"||chs=={"2","3"}, s1=chs[[1]];s2=chs[[2]];s3="",
s1=sub[chs[[1]],chs[[2]]];s2=s3="" ],
3, If[chs=={"2","1","3"}, s1=sub[chs[[1]],chs[[2]]]; s2=chs[[3]]; s3="",
If[chs[[2]]!="-", {s1,s2,s3}=chs,
s1=chs[[1]]; s2=bar[chs[[3]]]; s3=""]],
4, If[chs[[1]]=="3"||chs[[1]]=="6", s1=sub[chs[[1]],chs[[2]]]; {s2,s3}=chs[[3;;]],
If[chs[[2]]=="-", s1=chs[[1]]; s2=bar[chs[[3]]]; s3=chs[[4]],
tmp=Position[chs,"1"];
If[tmp=={}, s1=sub[chs[[1]],chs[[2]]]; {s2,s3}=chs[[3;;]],
Switch[tmp[[1,1]],
2, s1=sub[chs[[1]],chs[[2]]]; {s2,s3}=chs[[3;;]],
3, s1=chs[[1]]; s2=sub[chs[[2]],chs[[3]]]; s3=chs[[4]],
4, s1=chs[[1]]; s2=chs[[2]]; s3=sub[chs[[3]],chs[[4]]]
];
]
]],
5, s1=sub[chs[[1]],chs[[2]]]; s2=sub[chs[[3]],chs[[4]]]; s3=chs[[5]],
6, s1=sub[chs[[1]],chs[[2]]]; s2=sub[chs[[3]],chs[[4]]]; s3=sub[chs[[5]],chs[[6]]]
]
]
];
If[tex, StringJoin[{"$",L,s1,s2,s3,"$"}], Row[{L,s1,s2,s3}]]
]
Options[SGSymBC]={"TeX"->False};
SGSymBC[sgno_Integer, OptionsPattern[]]:=SGSymStd[sgno,"TeX"->OptionValue["TeX"],"BC"->True]
(*Note that in the BC book, t1=-b and t2=a for MonoPrim and OrthPrim.
But here the a,b,c represent the conventional basic vectors in ITA. *)
BCOrientation[sgno_Integer]/;1<=sgno<=230:=Which[
MemberQ[{17,19,28,29,31,33,53,61,36,46,70,122},sgno], {"b\!\(\*OverscriptBox[\(a\), \(_\)]\)c",{b,-a,c}},
MemberQ[{38,39,40,41,57},sgno], {"bca",{b,c,a}},
MemberQ[{51,54},sgno], {"\!\(\*OverscriptBox[\(c\), \(_\)]\)ba",{-c,b,a}},
MemberQ[{52,60},sgno]||3<=sgno<=15, {"a\!\(\*OverscriptBox[\(c\), \(_\)]\)b",{a,-c,b}},
True, {"abc",{a,b,c}}
]
SGSymSchoData=<|1->{"C1",1},2->{"Ci",1},3->{"C2",1},4->{"C2",2},5->{"C2",3},6->{"Cs",1},7->{"Cs",2},
8->{"Cs",3},9->{"Cs",4},10->{"C2h",1},11->{"C2h",2},12->{"C2h",3},13->{"C2h",4},14->{"C2h",5},15->{"C2h",6},
16->{"D2",1},17->{"D2",2},18->{"D2",3},19->{"D2",4},20->{"D2",5},21->{"D2",6},22->{"D2",7},23->{"D2",8},
24->{"D2",9},25->{"C2v",1},26->{"C2v",2},27->{"C2v",3},28->{"C2v",4},29->{"C2v",5},30->{"C2v",6},
31->{"C2v",7},32->{"C2v",8},33->{"C2v",9},34->{"C2v",10},35->{"C2v",11},36->{"C2v",12},37->{"C2v",13},
38->{"C2v",14},39->{"C2v",15},40->{"C2v",16},41->{"C2v",17},42->{"C2v",18},43->{"C2v",19},44->{"C2v",20},
45->{"C2v",21},46->{"C2v",22},47->{"D2h",1},48->{"D2h",2},49->{"D2h",3},50->{"D2h",4},51->{"D2h",5},
52->{"D2h",6},53->{"D2h",7},54->{"D2h",8},55->{"D2h",9},56->{"D2h",10},57->{"D2h",11},58->{"D2h",12},
59->{"D2h",13},60->{"D2h",14},61->{"D2h",15},62->{"D2h",16},63->{"D2h",17},64->{"D2h",18},65->{"D2h",19},
66->{"D2h",20},67->{"D2h",21},68->{"D2h",22},69->{"D2h",23},70->{"D2h",24},71->{"D2h",25},72->{"D2h",26},
73->{"D2h",27},74->{"D2h",28},75->{"C4",1},76->{"C4",2},77->{"C4",3},78->{"C4",4},79->{"C4",5},80->{"C4",6},
81->{"S4",1},82->{"S4",2},83->{"C4h",1},84->{"C4h",2},85->{"C4h",3},86->{"C4h",4},87->{"C4h",5},88->{"C4h",6},
89->{"D4",1},90->{"D4",2},91->{"D4",3},92->{"D4",4},93->{"D4",5},94->{"D4",6},95->{"D4",7},96->{"D4",8},
97->{"D4",9},98->{"D4",10},99->{"C4v",1},100->{"C4v",2},101->{"C4v",3},102->{"C4v",4},103->{"C4v",5},
104->{"C4v",6},105->{"C4v",7},106->{"C4v",8},107->{"C4v",9},108->{"C4v",10},109->{"C4v",11},110->{"C4v",12},
111->{"D2d",1},112->{"D2d",2},113->{"D2d",3},114->{"D2d",4},115->{"D2d",5},116->{"D2d",6},117->{"D2d",7},
118->{"D2d",8},119->{"D2d",9},120->{"D2d",10},121->{"D2d",11},122->{"D2d",12},123->{"D4h",1},124->{"D4h",2},
125->{"D4h",3},126->{"D4h",4},127->{"D4h",5},128->{"D4h",6},129->{"D4h",7},130->{"D4h",8},131->{"D4h",9},
132->{"D4h",10},133->{"D4h",11},134->{"D4h",12},135->{"D4h",13},136->{"D4h",14},137->{"D4h",15},138->{"D4h",16},
139->{"D4h",17},140->{"D4h",18},141->{"D4h",19},142->{"D4h",20},143->{"C3",1},144->{"C3",2},145->{"C3",3},
146->{"C3",4},147->{"S6",1},148->{"S6",2},149->{"D3",1},150->{"D3",2},151->{"D3",3},152->{"D3",4},153->{"D3",5},
154->{"D3",6},155->{"D3",7},156->{"C3v",1},157->{"C3v",2},158->{"C3v",3},159->{"C3v",4},160->{"C3v",5},
161->{"C3v",6},162->{"D3d",1},163->{"D3d",2},164->{"D3d",3},165->{"D3d",4},166->{"D3d",5},167->{"D3d",6},
168->{"C6",1},169->{"C6",2},170->{"C6",3},171->{"C6",4},172->{"C6",5},173->{"C6",6},174->{"C3h",1},175->{"C6h",1},
176->{"C6h",2},177->{"D6",1},178->{"D6",2},179->{"D6",3},180->{"D6",4},181->{"D6",5},182->{"D6",6},183->{"C6v",1},
184->{"C6v",2},185->{"C6v",3},186->{"C6v",4},187->{"D3h",1},188->{"D3h",2},189->{"D3h",3},190->{"D3h",4},
191->{"D6h",1},192->{"D6h",2},193->{"D6h",3},194->{"D6h",4},195->{"T",1},196->{"T",2},197->{"T",3},198->{"T",4},
199->{"T",5},200->{"Th",1},201->{"Th",2},202->{"Th",3},203->{"Th",4},204->{"Th",5},205->{"Th",6},206->{"Th",7},
207->{"O",1},208->{"O",2},209->{"O",3},210->{"O",4},211->{"O",5},212->{"O",6},213->{"O",7},214->{"O",8},215->{"Td",1},
216->{"Td",2},217->{"Td",3},218->{"Td",4},219->{"Td",5},220->{"Td",6},221->{"Oh",1},222->{"Oh",2},223->{"Oh",3},
224->{"Oh",4},225->{"Oh",5},226->{"Oh",6},227->{"Oh",7},228->{"Oh",8},229->{"Oh",9},230->{"Oh",10}|>;
(* Give the Schoenflies symbol of the space group with number sgno *)
Options[SGSymScho]={"TeX"->False, "full"->False};
SGSymScho[sgno_Integer, OptionsPattern[]]:=Module[{dat,s1,s2,full,re,slat,brav},
dat=SGSymSchoData[sgno]; full=OptionValue["full"]===True;
s1=StringTake[dat[[1]],1]; s2=StringTake[dat[[1]],{2,-1}];
If[OptionValue["TeX"]===True,
re=s1<>If[s2!="","_{"<>s2<>"}",""]<>"^{"<>ToString[dat[[2]]]<>"}";
If[full, brav=getSGLatt[sgno];
slat=ToString@TeXForm@BravLattSymb@iBravLatt@brav;
If[brav!="TrigPrim",slat=StringReplace[slat,{"_"->"_\\text{","^"->"}^\\text{"}]<>"}"];
re=StringReplace[slat," "->""]<>re
];
re="$"<>re<>"$",
(*----else-----*)
re=Subsuperscript[s1,s2,dat[[2]]];
If[full, re=Row[{BravLattSymb@iBravLatt@getSGLatt[sgno],re}]]
];
re
]
Options[showSGSym]={"ncol"->10};
showSGSym[OptionsPattern[]]:=showSGSym[All,"ncol"->OptionValue["ncol"]];
showSGSym[listOrSpan_, OptionsPattern[]]:=Module[{bgc,i,j,lt=0.96,s1,s2,tab,bgs,h,g,ncol,nrow,
cls,sglist,nsg},
sglist=If[IntegerQ[listOrSpan], {listOrSpan}, Range[230][[listOrSpan]]];
nsg=Length[sglist]; ncol=OptionValue["ncol"]; nrow=Ceiling[nsg/ncol];
tab={#,s1=SGSymStd[#],s2=SGSymBC[#]; If[s2===s1,s2,Style[s2,Red]], SGSymScho[#]}&/@sglist//Partition[#,UpTo[ncol]]&;
tab=Map[Column[#,ItemSize->{Full,1.2}]&,tab,{2}];
bgc[n1_,n2_,color_]:=#->color&/@Range[n1,n2];
cls=Join[bgc[1,2,Lighter[Red,lt]], bgc[3,15,Lighter[Blue,lt]], bgc[16,74,Lighter[Orange,lt]],
bgc[75,142,Lighter[Cyan,lt]], bgc[143,167,Lighter[Yellow,lt]],
bgc[168,194,Lighter[Green,lt]],bgc[195,230,Lighter[Purple,lt]]]//Association;
bgs=(#1->#2)&@@@Transpose@{Flatten[Table[{i,j},{i,nrow},{j,ncol}],1][[1;;nsg]],cls/@sglist};
g=Grid[tab, Alignment->Left, Dividers->{{True,{},True},{True,{Thin},True}}, Spacings->{1, 1},
Background->{None,None,bgs}, ItemSize->Full];
h="Row 1: The SG number.\nRow 2: The standard SG international symbol.\n"<>
"Row 3: The SG international symbol conforming to the BC orientation.\n"<>
"Row 4: The Schoenflies symbol of SG.";
Column[{h,g}]
]
PGinfo={ (*Point group information*)
{1,"C1","1",{1, 1},1,{1, 1},{"E"},2,{2, 1},{"barE"}},
{2,"Ci","-1",{2, 2},2,{2, 1},{"I"},4,{4, 2},{"I", "barE"}},
{3,"C2","2",{3, 5},2,{2, 1},{"C2z"},4,{4, 1},{"C2z"}},
{4,"Cs","m",{6, 9},2,{2, 1},{"\[Sigma]z"},4,{4, 1},{"\[Sigma]z"}},
{5,"C2h","2/m",{10, 15},4,{4, 2},{"C2z", "I"},8,{8, 2},{"C2z", "I"}},
{6,"D2","222",{16, 24},4,{4, 2},{"C2z", "C2y"},5,{8, 5},{"C2z", "C2y"}},
{7,"C2v","mm2",{25, 46},4,{4, 2},{"C2z", "\[Sigma]y"},5,{8, 5},{"C2z", "\[Sigma]y"}},
{8,"D2h","mmm",{47, 74},8,{8, 3},{"C2z", "C2y", "I"},10,{16, 11},{"C2z", "C2y", "I"}},
{9,"C4","4",{75, 80},4,{4, 1},{"C4z+"},8,{8, 1},{"C4z+"}},
{10,"S4","-4",{81, 82},4,{4, 1},{"S4z+"},8,{8, 1},{"S4z+"}},
{11,"C4h","4/m",{83, 88},8,{8, 2},{"C4z+", "I"},16,{16, 2},{"C4z+", "I"}},
{12,"D4","422",{89, 98},5,{8, 4},{"C4z+", "C2x"},7,{16, 14},{"C4z+", "C2x"}},
{13,"C4v","4mm",{99, 110},5,{8, 4},{"C4z+", "\[Sigma]y"},7,{16, 14},{"C4z+", "\[Sigma]y"}},
{14,"D2d","-42m",{111, 122},5,{8, 4},{"S4z+", "C2x"},7,{16, 14},{"S4z+", "C2x"}},
{15,"D4h","4/mmm",{123, 142},10,{16, 9},{"C4z+", "C2x", "I"},14,{32, 9},{"C4z+", "C2x", "I"}},
{16,"C3","3",{143, 146},3,{3, 1},{"C3+"},6,{6, 1},{"C3+"}},
{17,"S6","-3",{147, 148},6,{6, 1},{"S6+"},12,{12, 6},{"S6+", "I"}},
{18,"D3","32",{149, 155},3,{6, 2},{"C3+", "C21p"},6,{12, 4},{"C3+", "C21p"}},
{19,"C3v","3m",{156, 161},3,{6, 2},{"C3+", "\[Sigma]v1"},6,{12, 4},{"C3+", "\[Sigma]v1"}},
{20,"D3d","-3m",{162, 167},6,{12, 3},{"S6+", "C21p"},12,{24, 3},{"C3+", "C21p", "I"}},
{21,"C6","6",{168, 173},6,{6, 1},{"C6+"},12,{12, 1},{"C6+"}},
{22,"C3h","-6",{174, 174},6,{6, 1},{"S3+"},12,{12, 1},{"S3+"}},
{23,"C6h","6/m",{175, 176},12,{12, 2},{"C3+", "C2", "I"},24,{24, 12},{"C6+", "I"}},
{24,"D6","622",{177, 182},6,{12, 3},{"C6+", "C21p"},9,{24, 11},{"C6+", "C21p"}},
{25,"C6v","6mm",{183, 186},6,{12, 3},{"C6+", "\[Sigma]v1"},9,{24, 11},{"C6+", "\[Sigma]d1"}},
{26,"D3h","-6m2",{187, 190},6,{12, 3},{"S3+", "C21p"},9,{24, 11},{"S3+", "C21p"}},
{27,"D6h","6/mmm",{191, 194},12,{24, 5},{"C3+", "C21p", "C2", "I"},18,{48, 15},{"C6+", "C21p", "I"}},
{28,"T","23",{195, 199},4,{12, 5},{"C31+", "C2z", "C2y"},7,{24, 9},{"C31-", "C2x", "barC2y"}},
{29,"Th","m-3",{200, 206},8,{24, 10},{"S61+", "C2z", "C2y"},14,{48, 4},{"C31-", "C2x", "barC2y", "I"}},
{30,"O","432",{207, 214},5,{24, 7},{"C31-", "C2z", "C2x", "C2a"},8,{48, 10},{"C4x+", "barC31-", "C2b"}},
{31,"Td","-43m",{215, 220},5,{24, 7},{"C31-", "C2z", "C2x", "\[Sigma]da"},8,{48, 10},{"S4x-", "barC31-", "\[Sigma]db"}},
{32,"Oh","m-3m",{221, 230},10,{48, 7},{"S61-", "\[Sigma]x", "\[Sigma]z", "C2c"},16,{96, 8},{"C4x+", "barC31-", "C2b", "I"}}
};
showPGSch[s_String]:=If[StringLength[s]==1,s,Subscript[StringTake[s,1],StringTake[s,{2,-1}]]]
showPGInt[s_String]:=Module[{c=Characters[s], p}, p=Position[c, "-"];
If[p=={}, s, p = p[[1, 1]]; Row@Flatten@{c[[;;p-1]], OverBar[c[[p+1]]], c[[p+2;;]]}] ]
Options[showPGinfo]={"long"->True, "color"->True, "double"->False}
showPGinfo[OptionsPattern[]]:=Module[{stab,lt=0.90,bgc,bgs,cls,ncol,ltab,note,dtag,dt},
bgc[n1_,n2_,color_]:=#->color&/@Range[n1,n2];
dtag=If[OptionValue["double"]===True, dt=3; " (D)", dt=0; ""];
stab={#[[1]],showPGSch[#[[2]]],Row[{"(",showPGInt[#[[3]]],")"}]}&/@PGinfo;
stab[[2,2]]=Row[{stab[[2,2]],Subscript["/S","2"]}];
stab[[4,2]]=Row[{stab[[4,2]],Subscript["/C","1h"]}];
stab=Grid[{#}, ItemSize->{{1.6,Full,Full}}, Alignment->Left, Spacings->0]&/@stab;
cls=Join[bgc[1,2,Lighter[Red,lt]], bgc[3,5,Lighter[Blue,lt]], bgc[6,8,Lighter[Orange,lt]],
bgc[9,15,Lighter[Cyan,lt]], bgc[16,20,Lighter[Yellow,lt]],
bgc[21,27,Lighter[Green,lt]],bgc[28,32,Lighter[Purple,lt]]]//Association;
ncol=8;
bgs=(#1->#2)&@@@Transpose@{Flatten[Table[{i,j},{i,Ceiling[32/ncol]},{j,ncol}],1][[;;32]],cls/@Range[32]};
stab=Partition[stab, UpTo[ncol]]//Grid[#,Alignment->Left, Spacings->{2,0.3},
Background->If[OptionValue["color"],{None,None,bgs},{}]]&;
If[OptionValue["long"]==False, Return[stab]];
ltab={#[[1]], showPGSch[#[[2]]], showPGInt[#[[3]]], Row[{#[[4,1]],"~",#[[4,2]]}],
#[[dt+5]], Subsuperscript["G",#[[dt+6,1]],#[[dt+6,2]]], Row[showRot/@#[[dt+7]],","]}&/@PGinfo;
ltab[[2,2]]=Row[{ltab[[2,2]],Subscript["/S","2"]}];
ltab[[4,2]]=Row[{ltab[[4,2]],Subscript["/C","1h"]}];
ltab=Prepend[ltab, {"No.", Column[{"Schoenflies","symbol"}], Column[{"International","symbol"}],
Column[{"Space","groups "}], Column[{"Number of","classes"<>dtag}],
Column[{"Abstract","group"<>dtag}], "Generators"<>dtag}];
cls=Join[bgc[1,1,Lighter[Gray,lt]], bgc[2,3,Lighter[Red,lt]],
bgc[4,6,Lighter[Blue,lt]], bgc[7,9,Lighter[Orange,lt]],
bgc[10,16,Lighter[Cyan,lt]], bgc[17,21,Lighter[Yellow,lt]],
bgc[22,28,Lighter[Green,lt]],bgc[29,33,Lighter[Purple,lt]]];
ltab=Grid[ltab, Alignment->Left, Spacings->{2,0.3}, Frame->True, Dividers->{{},{2->True}},
Background->If[OptionValue["color"],{{},cls},{}]];
note="Note that the generators are not unique. The generators here are consistent with\n"<>
"the rotation parts of the generators of the Herring little group at \[CapitalGamma] point of the\n"<>
"first space group with this point group, NOT the same with those in BC-Tab. 5.2 or 6.4.";
Column[{ltab,note}]
]
(* ::Section:: *)
(*Jones' faithful representation symbols (Tab. 1.4)*)
(* ::Text:: *)
(*Note that the Jones' symbols are based on certain basic vectors of the lattice.*)
(* JonesSymbol[[1]] for cubic crystal system, also usable for monoclinic, orthorhombic, and tetragonal systems
JonesSymbol[[2]] for hexagonal and trigonal crystal systems. *)
JonesSymbol=Module[{xyzHex,xyzCub,nameHex,nameCub,matHex,matCub},Block[{x,y,z},
nameCub={"E","C2x","C2y","C2z","C31+","C32+","C33+","C34+",
"C31-","C32-","C33-","C34-","C4x+","C4y+","C4z+","C4x-",
"C4y-","C4z-","C2a","C2b","C2c","C2d","C2e","C2f",
"I","\[Sigma]x","\[Sigma]y","\[Sigma]z","S61-","S62-","S63-","S64-",
"S61+","S62+","S63+","S64+","S4x-","S4y-","S4z-","S4x+",
"S4y+","S4z+","\[Sigma]da","\[Sigma]db","\[Sigma]dc","\[Sigma]dd","\[Sigma]de","\[Sigma]df"};
xyzCub={{x,y,z},{x,-y,-z},{-x,y,-z},{-x,-y,z},{z,x,y},{-z,x,-y},{-z,-x,y},{z,-x,-y},
{y,z,x},{y,-z,-x},{-y,z,-x},{-y,-z,x},{x,-z,y},{z,y,-x},{-y,x,z},{x,z,-y},
{-z,y,x},{y,-x,z},{y,x,-z},{-y,-x,-z},{z,-y,x},{-x,z,y},{-z,-y,-x},{-x,-z,-y},
{-x,-y,-z},{-x,y,z},{x,-y,z},{x,y,-z},{-z,-x,-y},{z,-x,y},{z,x,-y},{-z,x,y},
{-y,-z,-x},{-y,z,x},{y,-z,x},{y,z,-x},{-x,z,-y},{-z,-y,x},{y,-x,-z},{-x,-z,y},
{z,-y,-x},{-y,x,-z},{-y,-x,z},{y,x,z},{-z,y,-x},{x,-z,-y},{z,y,x},{x,z,y}};
nameHex={"E","C6+","C3+","C2","C3-","C6-","C21p","C22p",
"C23p","C21pp","C22pp","C23pp","I","S3-","S6-","\[Sigma]h",
"S6+","S3+","\[Sigma]d1","\[Sigma]d2","\[Sigma]d3","\[Sigma]v1","\[Sigma]v2","\[Sigma]v3"};
xyzHex={{x,y,z},{x-y,x,z},{-y,x-y,z},{-x,-y,z},{-x+y,-x,z},{y,-x+y,z},{-x+y,y,-z},{x,x-y,-z},
{-y,-x,-z},{x-y,-y,-z},{-x,-x+y,-z},{y,x,-z},{-x,-y,-z},{-x+y,-x,-z},{y,-x+y,-z},{x,y,-z},
{x-y,x,-z},{-y,x-y,-z},{x-y,-y,z},{-x,-x+y,z},{y,x,z},{-x+y,y,z},{x,x-y,z},{-y,-x,z}};
matCub=Normal@CoefficientArrays[#,{x,y,z}][[2]]&/@xyzCub;
matHex=Normal@CoefficientArrays[#,{x,y,z}][[2]]&/@xyzHex;
{{nameCub,xyzCub,matCub}\[Transpose],
{nameHex,xyzHex,matHex}\[Transpose]}
]];
(* opName is a string for the name of operations defined in JonesSymbol,
by default return the xyz form of the Jones' symbol,
if use option "type"\[Rule]"mat" return the corresponding rotation matrix.*)
Options[getJones]={"type"->"xyz"};
getJones[opName_String,OptionsPattern[]]:=Block[{x,y,z,hex,cub,re},
{cub,hex}=JonesSymbol;
If[OptionValue["type"]=="xyz",
re=Association[Rule@@#&/@Join[cub,hex][[All,{1,2}]]],
re=Association[Rule@@#&/@Join[cub,hex][[All,{1,3}]]]
];
re[opName]
]
(* p1 is either the xyz form of the Jones' symbol or its matrix
p2 can be "c" or "h" to designate cubic or hexagonal, p2 can also be the space group number *)
getJones[p1_,p2_]:=Block[{x,y,z,isCub,i,toname1,toname2},
If[!ListQ[p1],Return[""]];
If[StringQ[p2],
Which[p2=="c",isCub=True,p2=="h",isCub=False],
isCub=!(143<=p2<=194) (* space groups with number in [143,194] are hexagonal or trigonal systems*)
];
i=If[isCub,1,2];
toname1=Association[Rule@@#[[{2,1}]]&/@JonesSymbol[[i]]];
toname2=Association[Rule@@#[[{3,1}]]&/@JonesSymbol[[i]]];
Switch[Dimensions[p1],
{3}, toname1[p1],
{3,3}, toname2[p1]
]
]
(* ::Section:: *)
(*The 14 Bravais lattices (Tab. 3.1)*)
Module[{latt,idx,lattS},
latt={"TricPrim","MonoPrim","MonoBase","OrthPrim","OrthBase",
"OrthBody","OrthFace","TetrPrim","TetrBody","TrigPrim",
"HexaPrim","CubiPrim","CubiFace","CubiBody"};
lattS={"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(t\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(m\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(m\), \(b\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(o\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(o\), \(b\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(o\), \(v\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(o\), \(f\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(q\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(q\), \(v\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(rh\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(h\)]\)",
"\!\(\*SubscriptBox[\(\[CapitalGamma]\), \(c\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(c\), \(f\)]\)",
"\!\(\*SubsuperscriptBox[\(\[CapitalGamma]\), \(c\), \(v\)]\)"};
idx=Range[14];
BravLatt=Association[Rule@@#&/@Transpose[{idx,latt}]];
iBravLatt=Association[Rule@@#&/@Transpose[{latt,idx}]];
BravLattSymb=Association[Rule@@#&/@Transpose[{idx,lattS}]];
]
BasicVectors=Block[{bvec,rules,a,b,c,\[Alpha],\[Beta],\[Gamma]},
rules={
"TricPrim"->{{a,0,0},{b Cos[\[Gamma]],b Sin[\[Gamma]],0},{c Cos[\[Beta]],c(Cos[\[Alpha]]Csc[\[Gamma]]-Cos[\[Beta]]Cot[\[Gamma]]),c Sqrt[Sin[\[Beta]]^2 -(Cos[\[Alpha]]Csc[\[Gamma]]-Cos[\[Beta]]Cot[\[Gamma]])^2 ]}},
"MonoPrim"->{{0,-b,0},{a Sin[\[Gamma]],-a Cos[\[Gamma]],0},{0,0,c}},
"MonoBase"->{{0,-b,0},{a Sin[\[Gamma]],-a Cos[\[Gamma]],-c}/2,{a Sin[\[Gamma]],-a Cos[\[Gamma]],c}/2},
"OrthPrim"->{{0,-b,0},{a,0,0},{0,0,c}},
"OrthBase"->{{a,-b,0}/2,{a,b,0}/2,{0,0,c}},
"OrthBody"->{{a,b,c}/2,{-a,-b,c}/2,{a,-b,-c}/2},
"OrthFace"->{{a,0,c}/2,{0,-b,c}/2,{a,-b,0}/2},
"TetrPrim"->{{a,0,0},{0,a,0},{0,0,c}},
"TetrBody"->{{-a,a,c}/2,{a,-a,c}/2,{a,a,-c}/2},
"TrigPrim"->{{0,-a,c},{a Sqrt[3]/2,a/2,c},{-a Sqrt[3]/2,a/2,c}},
"HexaPrim"->{{0,-a,0},{a Sqrt[3]/2,a/2,0},{0,0,c}},
"CubiPrim"->{{a,0,0},{0,a,0},{0,0,a}},
"CubiFace"->{{0,a,a},{a,0,a},{a,a,0}}/2,
"CubiBody"->{{-a,a,a},{a,-a,a},{a,a,-a}}/2};
bvec=Association[rules];
bvec=Append[bvec,Rule@@#&/@Transpose[{Range[14],Values[rules]}]]
];
(* Transformation matrix from the lattice basic vectors defining Jones' symbol to the ones of each Bravais lattice
Let the Jone's basic vectors are a,b,c (all are column vectors), the Bravais lattice basic vectors
are t1,t2,t3, and the transformation matrix is M, then the equation is: (t1,t2,t3)=(a,b,c)M
Because of column vectors, the code should be {t1,t2,t3}\[Transpose]={a,b,c}\[Transpose].M
Note that the crystal has not been changed/rotated, and only the primitive cell definition changed.
*)
JonesTM=Module[{L0,M,brav}, M=<||>; Block[{a,b,c,\[Gamma]},
M["TricPrim"]=M["MonoPrim"]=M["HexaPrim"]=IdentityMatrix[3];
(* for MonoBase *)
L0=BasicVectors["MonoPrim"];
brav="MonoBase"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
(* for OthPrim, OrthBase, OrthBody, OrthFace *)
L0={{a,0,0},{0,b,0},{0,0,c}};
brav="OrthPrim"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="OrthBase"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="OrthBody"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="OrthFace"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
(* for TrigPrim *)
L0=BasicVectors["HexaPrim"];
brav="TrigPrim"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
(* for TetrPrim, TetrBody, CubiPrim, CubiBadyC, CubiFace *)
L0=BasicVectors["TetrPrim"];
brav="TetrPrim"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="TetrBody"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
L0=BasicVectors["CubiPrim"];
brav="CubiPrim"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="CubiBody"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
brav="CubiFace"; M[brav]=Inverse[L0\[Transpose]].BasicVectors[brav]\[Transpose]//Simplify;
]; M];
(* get the Bravais lattice of the space group with number SGNo *)
getSGLatt[SGNo_Integer]:=Module[{BLNo=<||>, brav,i},
If[Or[SGNo>230,SGNo<1],Print["Warning::getSGLatt: SGNo ",SGNo," out of range."]; Return[]];
BLNo["TricPrim"]={1,2}; (*Subscript[\[CapitalGamma], t]*)
BLNo["MonoPrim"]={3,4,6,7,10,11,13,14}; (* Subscript[\[CapitalGamma], m]*)
BLNo["MonoBase"]={5,8,9,12,15}; (*Subsuperscript[\[CapitalGamma], m, b]*)
BLNo["OrthPrim"]={16,17,18,19,25,26,27,28,29,30,31,32,33,34,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62}; (*Subscript[\[CapitalGamma], o]*)
BLNo["OrthBase"]={20,21,35,36,37,38,39,40,41,63,64,65,66,67,68}; (*Subsuperscript[\[CapitalGamma], o, b]*)
BLNo["OrthBody"]={23,24,44,45,46,71,72,73,74}; (*Subsuperscript[\[CapitalGamma], o, v]*)
BLNo["OrthFace"]={22,42,43,69,70}; (*Subsuperscript[\[CapitalGamma], o, f]*)
BLNo["TetrPrim"]={75,76,77,78,81,83,84,85,86,89,90,91,92,93,94,95,96,99,100,101,102,103,104,105,106,111,112,113,114,115,116,117,118,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138}; (*Subscript[\[CapitalGamma], q]*)
BLNo["TetrBody"]={79,80,82,87,88,97,98,107,108,109,110,119,120,121,122,139,140,141,142}; (*Subsuperscript[\[CapitalGamma], q, v]*)
BLNo["TrigPrim"]={146,148,155,160,161,166,167}; (*Subscript[\[CapitalGamma], rh]*)
BLNo["HexaPrim"]={143,144,145,147,149,150,151,152,153,154,156,157,158,159,162,163,164,165,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194}; (*Subscript[\[CapitalGamma], h]*)
BLNo["CubiPrim"]={195,198,200,201,205,207,208,212,213,215,218,221,222,223,224}; (*Subscript[\[CapitalGamma], c]*)
BLNo["CubiFace"]={196,202,203,209,210,216,219,225,226,227,228}; (*Subsuperscript[\[CapitalGamma], c, f]*)
BLNo["CubiBody"]={197,199,204,206,211,214,217,220,229,230}; (*Subsuperscript[\[CapitalGamma], c, v]*)
For[i=1,i<=14,i++, brav=BravLatt[i]; If[MemberQ[BLNo[brav],SGNo],Return[brav]]]
]
(* Check whether bvec is the basic vectors of the form in BC Tab.3.1. Also calculate the BZ type. *)
checkBasVec[brav_,bvec_]/;MatrixQ[bvec,NumericQ]&&Dimensions[bvec]=={3,3}:=
Block[{a,b,c,\[Alpha],\[Beta],\[Gamma],a1,b1,c1,\[Alpha]1,\[Beta]1,\[Gamma]1,pbv,TM,prec=1*^-5,type},
If[brav=="TricPrim", {a1,b1,c1}=Norm/@bvec;
\[Alpha]1=ArcCos[bvec[[2]].bvec[[3]]/(b1*c1)];
\[Beta]1=ArcCos[bvec[[1]].bvec[[3]]/(a1*c1)];
\[Gamma]1=ArcCos[bvec[[1]].bvec[[2]]/(a1*b1)];
Return[{True,"",{a->a1,b->b1,c->c1,\[Alpha]->\[Alpha]1,\[Beta]->\[Beta]1,\[Gamma]->\[Gamma]1}}]
];
If[MemberQ[{"MonoPrim","MonoBase"},brav],
TM=JonesTM[brav];
pbv=Chop[Transpose[bvec\[Transpose].Inverse[TM]],prec];
If[Flatten[pbv][[{1,3,6,7,8}]]!={0,0,0,0,0},Return[{False}]];
b1=-pbv[[1,2]]; a1=Norm[pbv[[2]]]; c1=pbv[[3,3]];
\[Gamma]1=ArcCos[-pbv[[2,2]]/a1];
If[Abs[pbv[[2,1]]-a1*Sin[\[Gamma]1]]<prec&&b1>0&&c1>0,
Return[{True,"",{a->a1,b->b1,c->c1,\[Gamma]->\[Gamma]1}}], Return[{False}]
]
];
If[MemberQ[{"OrthPrim","OrthBase","OrthBody","OrthFace"},brav],
TM={{0,-1,0},{1,0,0},{0,0,1}}.JonesTM[brav];
pbv=Chop[Transpose[bvec\[Transpose].Inverse[TM]],prec];
If[Flatten[pbv][[{1,3,5,6,7,8}]]!={0,0,0,0,0,0},Return[{False}]];
b1=-pbv[[1,2]]; a1=pbv[[2,1]]; c1=pbv[[3,3]];
If[!(a1>0&&b1>0&&c1>0), Return[{False}]];
type=Switch[brav,
"OrthPrim", "",
"OrthBase", If[a1>b1,"a","b"],
"OrthBody", Switch[Max[a1,b1,c1],a1,"a",b1,"b",c1,"c"],
"OrthFace", Which[1/a1^2<1/b1^2+1/c1^2&&1/b1^2<1/a1^2+1/c1^2&&1/c1^2<1/a1^2+1/b1^2,"a",
1/c1^2>1/a1^2+1/b1^2,"b", 1/b1^2>1/a1^2+1/c1^2,"c",
1/a1^2>1/b1^2+1/c1^2,"d"]
];
Return[{True,type,{a->a1,b->b1,c->c1}}]
];
If[MemberQ[{"TetrPrim","TetrBody"},brav],
TM=JonesTM[brav];
pbv=Chop[Transpose[bvec\[Transpose].Inverse[TM]],prec];
If[Flatten[pbv][[{2,3,4,6,7,8}]]!={0,0,0,0,0,0},Return[{False}]];
a1=pbv[[1,1]]; b1=pbv[[2,2]]; c1=pbv[[3,3]];
If[!(Abs[a1-b1]<prec&&a1>0&&c1>0), Return[{False}]];
a1=(a1+b1)/2;
type=If[brav=="TetrBody",If[a1>c1,"a","b"],""];
Return[{True,type,{a->a1,c->c1}}]
];
If[brav=="TrigPrim",
a1=Mean[Norm/@bvec[[All,{1,2}]]]; c1=Mean[bvec[[All,3]]];
If[Max@Abs[(BasicVectors[brav]/.{a->a1,c->c1})-bvec]>prec, Return[{False}]];
type=If[a1>Sqrt[2]c1,"a","b"];
Return[{True,type,{a->a1,c->c1}}]
];
If[brav=="HexaPrim",
a1=Mean[Norm/@bvec[[{1,2}]]]; c1=bvec[[3,3]];
If[Max@Abs[(BasicVectors[brav]/.{a->a1,c->c1})-bvec]>prec, Return[{False}]];
Return[{True,"",{a->a1,c->c1}}]
];
If[MemberQ[{"CubiPrim","CubiBody","CubiFace"},brav],
TM=JonesTM[brav];
pbv=Chop[Transpose[bvec\[Transpose].Inverse[TM]],prec];
If[Flatten[pbv][[{2,3,4,6,7,8}]]!={0,0,0,0,0,0},Return[{False}]];
a1=pbv[[1,1]]; b1=pbv[[2,2]]; c1=pbv[[3,3]];
If[Abs[a1-b1]>prec||Abs[a1-c1]>prec||Abs[b1-c1]>prec, Return[{False}]];
Return[{True,"",{a->(a1+b1+c1)/3}}]
];
]
(* ::Section:: *)
(*Rotation matrices for each Bravais lattice (Tab. 3.2 and Tab. 3.4)*)
(* RotMat[[1]][brav] contain the names of rotations for lattice type of brav.
RotMat[[2]][brav] contain the rotation matrices for lattice type of brav. *)
RotMat=Module[{opNames,M,tmp,i,brav,opMats},
opNames=<||>; opMats=<||>;
opNames["TricPrim"]={"E","I"};
opNames["MonoPrim"]=opNames["MonoBase"]={"E","C2z","I","\[Sigma]z"};
opNames["OrthPrim"]=opNames["OrthBase"]=opNames["OrthBody"]=opNames["OrthFace"]={"E",
"C2x","C2y","C2z","I","\[Sigma]x","\[Sigma]y","\[Sigma]z"};
tmp={"E","C4z+","C2z","C4z-","C2x","C2y","C2a","C2b"};
tmp=Join[tmp,getJones[-getJones[#,"type"->"mat"],"c"]&/@tmp];
opNames["TetrPrim"]=opNames["TetrBody"]=tmp;
tmp={"E","C3+","C3-","C21p","C22p","C23p"};
opNames["TrigPrim"]=Join[tmp,getJones[-getJones[#,"type"->"mat"],"h"]&/@tmp];
opNames["HexaPrim"]=JonesSymbol[[2,All,1]];
opNames["CubiPrim"]=opNames["CubiBody"]=opNames["CubiFace"]=JonesSymbol[[1,All,1]];
For[i=1,i<=14,i++,
brav=BravLatt[i]; M=JonesTM[brav];
opMats[brav]=Inverse[M].getJones[#,"type"->"mat"].M&/@opNames[brav];
];
{opNames,opMats}
];
(* It's faster that looking up the inverse of a rotation matrix than calculating it directly. *)
invRotMat=Association[#->Inverse[#]&/@(Join@@Values[RotMat[[2]]]//DeleteDuplicates)];
(* Show the result of RotMat applied on basic vectors (t1,t2,t3) in table form like Tab. 3.2 *)
checkRotMat[brav_]:=Module[{names,tt},
names=RotMat[[1]][brav];
tt={"t1","t2","t3"}.#&/@RotMat[[2]][brav]//Simplify;
Column[{brav,TableForm[tt,TableHeadings->{names}]},Center,Dividers-> {{},{2->Black,3->Black}}]
]
(* Initialize three functions: getRotMat getRotMatOfK, getRotName*)
Module[{names,rots,dict1,dict2,brav,opname,mat},
Do[
names=RotMat[[1]][brav]; rots=RotMat[[2]][brav];
dict1=Association@(Rule@@#&/@Transpose[{names,rots}]);
dict2=Association@(Rule@@#&/@Transpose[{rots,names}]);
Do[getRotMat[brav,opname]=dict1[opname],{opname,names}];
Do[getRotMatOfK[brav,opname]=Inverse@Transpose[dict1[opname]],{opname,names}];
Do[getRotName[brav,mat]=dict2[mat],{mat,rots}];
,{brav,Values[BravLatt]}]
];
(*Rotation matrices in cartesian coordinate system.*)
RotMatCart=<||>;
(RotMatCart[#]=getRotMat["CubiPrim",#])&/@RotMat[[1]]["CubiPrim"];
(RotMatCart[#]=With[{bv=Transpose@BasicVectors["HexaPrim"]},bv.getRotMat["HexaPrim",#].Inverse[bv]])&/@
DeleteCases[RotMat[[1]]["HexaPrim"],"E"|"I"];
(* Note that the rotation matrix rotmat has to be basend on the t1,t2,t3 defined in Tab. 3.1.
In fact, if the basic vectors are (t1',t2',t3')=(R.t1,R.t2,R.t3) in which R is a O(3) rotation
matrix, then the rotmat remains unchanged.
\:5728\:8fd9\:4e2a\:610f\:4e49\:4e0b\:ff0c\:6bd4\:5982C2x\:5e76\:975e\:4e00\:5b9a\:662f\:7ed5x\:8f74\:8f6c180\:5ea6\:ff0c\:800c\:662f\:7ed5t1\:8f74\:8f6c180\:5ea6(\:7b80\:5355\:56db\:65b9\:548c\:7b80\:5355\:7acb\:65b9\:6676\:683c)\:ff0c\:6216\:662f\:7ed5
t2\:8f74\:8f6c180\:5ea6\:ff08\:7b80\:5355\:6b63\:4ea4\:6676\:683c\:ff09\:ff0c\:6216\:662f\:7ed5t1+t2\:65b9\:5411\:8f6c180\:5ea6\:ff08\:5e95\:5fc3\:6b63\:4ea4\:6676\:683c\:ff09\:ff0c\:6216\:662f\:7ed5t2+t3\:8f6c180\:5ea6\:ff08\:4f53\:5fc3\:7acb\:65b9\:ff09\:ff0c
\:6216\:662f\:7ed5t2+t3-t1\:8f6c180\:5ea6\:ff08\:9762\:5fc3\:7acb\:65b9\:ff09\:7b49 *)
(* Show the result of RotMat in reciprocal space applied on reciprocal basic vectors (g1,g2,g3)
in table form like Tab. 3.4 *)
checkRotMatOfK[brav_]:=Module[{names,tg},
names=RotMat[[1]][brav];
tg={"g1","g2","g3"}.Inverse[#\[Transpose]]&/@RotMat[[2]][brav]//Simplify;
Column[{brav,TableForm[tg,TableHeadings->{names}]},Center,Dividers-> {{},{2->Black,3->Black}}]
]
(* The lattice basic vectors which can generate the operations defined in the BC (means Bradley
and Cracknell) Tab.3.7 are named (t1_BC1,t2_BC1,t3_BC1) and (t1_BC2,t2_BC2,t3_BC2) which
corresond to the first line and second line in Tab.3.7 respectively. These BC1 and BC2 basic vectors
are compitable with the ones defined in BC Tab.3.1 but additional rotations may be needed to
give the same form in Tab.3.1.
Transformation matrix (Q) transforms the idealized standard lattice (as',bs',cs') from spglib (also the
same with ITA) to BC2 by (t1_BC2,t2_BC2,t3_BC2)=(as',bs',cs').Q. To result in the same form
in Tab.3.1, say (t1'_BC2,t2'_BC2,t3'_BC2), a rotation S1 is needed, that is
(t1_BC2', t2_BC2', t3_BC2')=S1.(t1_BC2,t2_BC2,t3_BC2)=S1.(as',bs',cs').Q
However, Tab.3.7 uses different orientations in the first line (i.e. BC1) for some spacegroups,
a transformation matrix U is needed to convert BC2 to BC1,
(t1_BC1,t2_BC1,t3_BC1)=(t1_BC2,t2_BC2,t3_BC2).U.
The BC1 basic vectors also maybe need a rotation S to convert it to the Tab.3.1 form
(t1_BC1', t2_BC1', t3_BC1')=S.(t1_BC1,t2_BC1,t3_BC1)=S.(as',bs',cs').Q.U.
If we start with BC2', then (t1_BC2', t2_BC2', t3_BC2').U also need a rotation to the BC1' form
(t1_BC1', t2_BC1', t3_BC1')=S2.(t1_BC2', t2_BC2', t3_BC2').U=S2.S1.(as',bs',cs').Q.U
Then we can combine the to rotations S1 and S2 to form S=S2.S1.
Thus, the rotation matrix S has two origins, S1 and S2. S1 originates from the different lattice
directions between the idealized standard lattice in spglib (the same as ITA) and the one in BC Tab.3.1,
and S2 originates from the different orientions used in Tab.3.7 for some space groups.
In fact, it turns out that if S1!=I3 then S2==I3 and if S2!=I3 then S1==I3, which means either
S1 or S2 takes effect.
This function only gives Q and S1. U is given by SGGenElem.
Note that all basic vectors in the above equations are COLUMN vectors.
For as',bs',cs' see https://atztogo.github.io/spglib/definition.html#def-idealize-cell
*)
TMspglibToBC[brav_]:=Module[{spgbvec=<||>,BCbvec,rotBCbvec,Q,S1,BCrotMats=<||>,LS=<||>},
LS=Association[#->StringTake[#,4]&/@{"TricPrim","MonoPrim","MonoBase","OrthPrim",
"OrthBase","OrthBody","OrthFace","TetrPrim","TetrBody","TrigPrim","HexaPrim",
"CubiPrim","CubiFace","CubiBody"}];
Block[{a,b,c,\[Alpha],\[Beta],\[Gamma]},
spgbvec["Tric"]=BasicVectors["TricPrim"];
BCrotMats["Tric"]=IdentityMatrix[3];
spgbvec["Mono"]={{a,0,0},{0,c,0},{b Cos[\[Gamma]],0,b Sin[\[Gamma]]}};
BCrotMats["Mono"]=Inverse[RotationMatrix[4Pi/3,{1,1,1}].RotationMatrix[Pi-\[Gamma],{0,0,1}]]//Simplify;
spgbvec["Orth"]={{a,0,0},{0,b,0},{0,0,c}};
BCrotMats["Orth"]=IdentityMatrix[3];
spgbvec["Tetr"]={{a,0,0},{0,a,0},{0,0,c}};
BCrotMats["Tetr"]=IdentityMatrix[3];
(* \:6ce8\:610f\:ff1a\:5728\:76ee\:524d spglib 1.14.1 \:7248\:672c\:65f6\:ff0c\:7f51\:9875 https://atztogo.github.io/spglib/definition.html#def-idealize-cell
\:4e0a\:8bf4 Rhombohedral(R)\:683c\:5b50\:7406\:60f3\:5316\:7684\:6807\:51c6\:57fa\:77e2\:5e94\:8be5\:662f a,b,c \:7684z\:5206\:91cf\:76f8\:7b49\:ff0c\:5b83\:4eec\:5728 xy \:9762\:5185\:7684\:6295\:5f71\:5927\:5c0f\:4e5f\:76f8\:7b49\:ff0c\:9006\:65f6\:9488\:76f8\:9694
120\:5ea6\:ff0c\:4e14a\:5728xy\:9762\:5185\:7684\:6295\:5f71a_xy\:6307\:5411+x\:65b9\:5411\:3002\:7136\:800c\:7a0b\:5e8f\:7684\:884c\:4e3a\:5e76\:975e\:5982\:6b64\:ff0cget_symmetry_dataset \:4e2d\:7ed9\:51fa\:7684 std_lattice\:ff0c
\:4e5f\:5c31\:662f refine_cell \:7ed9\:51fa\:7684\:57fa\:77e2\:5e76\:975eR\:683c\:5b50\:ff0c\:800c\:662f\:4f20\:7edf\:516d\:89d2\:7684H\:683c\:5b50\:3002\:5373\:4f7f\:7528 find_primitive \:5f97\:5230\:7684R\:683c\:5b50\:57fa\:77e2\:5176\:53d6\:5411
\:4e5f\:5e76\:975e\:5982\:7f51\:9875\:4e0a\:6240\:8bf4a_xy\:6307\:5411+x\:65b9\:5411\:ff0c\:800c\:662f\:6307\:5411\:4e0e+x\:65b9\:5411\:5939\:89d230\:5ea6\:7684\:65b9\:5411\:3002\:6545\:6700\:521d\:6309\:7f51\:9875\:4e0a\:8bf4\:7684\:53d6\:5411\:53bb\:5904\:7406\:5f97\:51fa\:7684\:7ed3\:679c\:4e0d\:5bf9\:3002
\:5173\:4e8e\:6b64\:95ee\:9898\:5df2\:5411 spglib \:63d0\:4ea4 bug\:ff0c\:5f97\:5230\:4e86\:80af\:5b9a\:7684\:56de\:590d\:ff0c\:540e\:7eed\:7248\:672c\:4e2d\:4fee\:6539\:4e86\:7f51\:9875\:63cf\:8ff0\:3002
spgbvec["Trig"]={{a,0,c},{-a/2,a Sqrt[3]/2,c},{-a/2,-a Sqrt[3]/2,c}};
BCrotMats["Trig"]=RotationMatrix[Pi/2,{0,0,1}]//Transpose; *)
(* \:6ce8\:610f\:ff1a BC\:4e66\:4e2dTab.3.1\:4e2dR\:683c\:5b50\:91cc\:7684 a,c \:5e76\:975e\:5bf9\:5e94\:4f20\:7edfH\:6676\:80de\:7684a\:548cc\:ff0c\:540e\:8005\:5206\:522b\:662f\:524d\:8005\:7684Sqrt[3]\:548c3\:500d\:3002 *)
spgbvec["Trig"]={{a,0,0},{-a/2,Sqrt[3]a/2,0},{0,0,c}}/.{a->Sqrt[3]a,c->3c};
BCrotMats["Trig"]=RotationMatrix[2Pi/3,{0,0,1}]//Transpose;
spgbvec["Hexa"]={{a,0,0},{-a/2,Sqrt[3]a/2,0},{0,0,c}};
BCrotMats["Hexa"]=RotationMatrix[Pi/2,{0,0,1}]//Transpose;
spgbvec["Cubi"]={{a,0,0},{0,a,0},{0,0,a}};
BCrotMats["Cubi"]=IdentityMatrix[3];
BCbvec=BasicVectors[brav]; (* (t1,t2,t3)^T *)
S1=BCrotMats[LS[brav]];
rotBCbvec=BCbvec.S1//Simplify; (* (t1',t2',t3')^T *)
Q=Inverse[spgbvec[LS[brav]]\[Transpose]].(rotBCbvec\[Transpose])//Simplify;
];
{Q,S1}
]
getQandS[SGNo_]:=Module[{Q,S,S1,S2,OBC2A},
{Q,S1}=TMspglibToBC[getSGLatt[SGNo]];
Block[{a,b,c,OBvecC,OBvecA},
OBvecC=BasicVectors["OrthBase"];
OBvecA={{0,-b,c}/2,{a,0,0},{0,b,c}/2};
OBC2A=Inverse[OBvecC\[Transpose]].OBvecA\[Transpose];
];
If[38<=SGNo<=41,Q=Q.OBC2A]; (*\:8fd9\:51e0\:4e2a\:7a7a\:95f4\:7fa4\:4f7f\:7528\:4e86A\:7684\:6b63\:4ea4\:5e95\:5fc3\:ff0c\:89c1Tab.3.1\:7684note(v)*)
S2=IdentityMatrix[3];
If[MemberQ[{17,19,28,29,31,33,36,46,53,61,70,122},SGNo],
S2=RotationMatrix[-Pi/2,{0,0,1}]]; (* C4z-, for "b -a c" orientation *)
If[MemberQ[{38,39,40,41,57},SGNo],
S2=RotationMatrix[-2Pi/3,{1,1,1}]]; (* C3(111)-, for "b c a" orientation *)
If[MemberQ[{51,54},SGNo],S2=RotationMatrix[-Pi/2,{0,1,0}]]; (* C4y-, for "-c b a" orientation *)
If[MemberQ[{52,60},SGNo],S2=RotationMatrix[Pi/2,{1,0,0}]]; (* C4x+, for "a -c b" orientation *)
S=S2.S1;
{Q,S}
]
(* ::Section::Closed:: *)
(*Space group generating elements. (Tab. 3.7)*)
Module[{I3,o,t1,t2,t3,h1,h2,h3,h12,h13,h23,h123,q1,q3,r1,r2,s1,s5,
OBvecA,OBvecC,OBA2C,UbAc0,Ubca0,UCba0,UaCb0,UbAcOrthP,UbAcOrthC,UbAcOrthB,
UbAcOrthF,UbAcTetrB,UbcaOrthP,UbcaOrthC,UCbaOrthP,UaCbOrthP,U38to41},
t1={1,0,0}; t2={0,1,0}; t3={0,0,1}; h1=t1/2; h2=t2/2; h3=t3/2;
h23=h2+h3; h13=h1+h3; h12=h1+h2; h123=h1+h2+h3;
q1=t3/4; q3=3t3/4;
r1=t3/3; r2=2t3/3; s1=t3/6; s5=5t3/6;
I3=IdentityMatrix[3]; o={0,0,0};
UbAc0=Block[{a,b,c},Transpose@Normal@CoefficientArrays[{b,-a,c},{a,b,c}][[2]]];
Ubca0=Block[{a,b,c},Transpose@Normal@CoefficientArrays[{b,c,a},{a,b,c}][[2]]];
UCba0=Block[{a,b,c},Transpose@Normal@CoefficientArrays[{-c,b,a},{a,b,c}][[2]]];
UaCb0=Block[{a,b,c},Transpose@Normal@CoefficientArrays[{a,-c,b},{a,b,c}][[2]]];
UbAcOrthP=With[{X=TMspglibToBC["OrthPrim"][[1]]},Inverse[X].UbAc0.X];
UbAcOrthC=With[{X=TMspglibToBC["OrthBase"][[1]]},Inverse[X].UbAc0.X];
UbAcOrthB=With[{X=TMspglibToBC["OrthBody"][[1]]},Inverse[X].UbAc0.X];
UbAcOrthF=With[{X=TMspglibToBC["OrthFace"][[1]]},Inverse[X].UbAc0.X];
UbAcTetrB=With[{X=TMspglibToBC["TetrBody"][[1]]},Inverse[X].UbAc0.X];
UbcaOrthP=With[{X=TMspglibToBC["OrthPrim"][[1]]},Inverse[X].Ubca0.X];
UbcaOrthC=With[{X=TMspglibToBC["OrthBase"][[1]]},Inverse[X].Ubca0.X];
UCbaOrthP=With[{X=TMspglibToBC["OrthPrim"][[1]]},Inverse[X].UCba0.X];
UaCbOrthP=With[{X=TMspglibToBC["OrthPrim"][[1]]},Inverse[X].UaCb0.X];
Block[{a,b,c},
OBvecC=BasicVectors["OrthBase"];
OBvecA={{0,-b,c}/2,{a,0,0},{0,b,c}/2};
OBA2C=Inverse[OBvecA\[Transpose]].OBvecC\[Transpose];
];