Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/materials/src/G4CrystalUnitCell.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /materials/src/G4CrystalUnitCell.cc (Version 11.3.0) and /materials/src/G4CrystalUnitCell.cc (Version 11.2.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26                                                    26 
 27 #include "G4CrystalUnitCell.hh"                    27 #include "G4CrystalUnitCell.hh"
 28                                                    28 
 29 #include "G4PhysicalConstants.hh"                  29 #include "G4PhysicalConstants.hh"
 30                                                    30 
 31 #include <cmath>                                   31 #include <cmath>
 32                                                    32 
 33 G4CrystalUnitCell::G4CrystalUnitCell(G4double      33 G4CrystalUnitCell::G4CrystalUnitCell(G4double sizeA, G4double sizeB, G4double sizeC, G4double alpha,
 34   G4double beta, G4double gamma, G4int spacegr     34   G4double beta, G4double gamma, G4int spacegroup)
 35   : theSize(G4ThreeVector(sizeA, sizeB, sizeC)     35   : theSize(G4ThreeVector(sizeA, sizeB, sizeC)),
 36     theAngle(G4ThreeVector(alpha, beta, gamma)     36     theAngle(G4ThreeVector(alpha, beta, gamma)),
 37     theSpaceGroup(spacegroup)                      37     theSpaceGroup(spacegroup)
 38 {                                                  38 {
 39   nullVec = G4ThreeVector(0., 0., 0.);             39   nullVec = G4ThreeVector(0., 0., 0.);
 40   theUnitBasis[0] = CLHEP::HepXHat;                40   theUnitBasis[0] = CLHEP::HepXHat;
 41   theUnitBasis[1] = CLHEP::HepYHat;                41   theUnitBasis[1] = CLHEP::HepYHat;
 42   theUnitBasis[2] = CLHEP::HepZHat;                42   theUnitBasis[2] = CLHEP::HepZHat;
 43                                                    43 
 44   theRecUnitBasis[0] = CLHEP::HepXHat;             44   theRecUnitBasis[0] = CLHEP::HepXHat;
 45   theRecUnitBasis[1] = CLHEP::HepYHat;             45   theRecUnitBasis[1] = CLHEP::HepYHat;
 46   theRecUnitBasis[2] = CLHEP::HepZHat;             46   theRecUnitBasis[2] = CLHEP::HepZHat;
 47                                                    47 
 48   cosa = std::cos(alpha), cosb = std::cos(beta     48   cosa = std::cos(alpha), cosb = std::cos(beta), cosg = std::cos(gamma);
 49   sina = std::sin(alpha), sinb = std::sin(beta     49   sina = std::sin(alpha), sinb = std::sin(beta), sing = std::sin(gamma);
 50                                                    50 
 51   cosar = (cosb * cosg - cosa) / (sinb * sing)     51   cosar = (cosb * cosg - cosa) / (sinb * sing);
 52   cosbr = (cosa * cosg - cosb) / (sina * sing)     52   cosbr = (cosa * cosg - cosb) / (sina * sing);
 53   cosgr = (cosa * cosb - cosg) / (sina * sinb)     53   cosgr = (cosa * cosb - cosg) / (sina * sinb);
 54                                                    54 
 55   theVolume = ComputeCellVolume();                 55   theVolume = ComputeCellVolume();
 56   theRecVolume = 1. / theVolume;                   56   theRecVolume = 1. / theVolume;
 57                                                    57 
 58   theRecSize[0] = sizeB * sizeC * sina / theVo     58   theRecSize[0] = sizeB * sizeC * sina / theVolume;
 59   theRecSize[1] = sizeC * sizeA * sinb / theVo     59   theRecSize[1] = sizeC * sizeA * sinb / theVolume;
 60   theRecSize[2] = sizeA * sizeB * sing / theVo     60   theRecSize[2] = sizeA * sizeB * sing / theVolume;
 61                                                    61 
 62   theRecAngle[0] = std::acos(cosar);               62   theRecAngle[0] = std::acos(cosar);
 63   theRecAngle[1] = std::acos(cosbr);               63   theRecAngle[1] = std::acos(cosbr);
 64   theRecAngle[2] = std::acos(cosgr);               64   theRecAngle[2] = std::acos(cosgr);
 65                                                    65 
 66   G4double x3, y3, z3;                             66   G4double x3, y3, z3;
 67                                                    67 
 68   switch (GetLatticeSystem(theSpaceGroup)) {       68   switch (GetLatticeSystem(theSpaceGroup)) {
 69     case Amorphous:                                69     case Amorphous:
 70       break;                                       70       break;
 71     case Cubic:  // Cubic, C44 set                 71     case Cubic:  // Cubic, C44 set
 72       break;                                       72       break;
 73     case Tetragonal:                               73     case Tetragonal:
 74       break;                                       74       break;
 75     case Orthorhombic:                             75     case Orthorhombic:
 76       break;                                       76       break;
 77     case Rhombohedral:                             77     case Rhombohedral:
 78       theUnitBasis[1].rotateZ(gamma - CLHEP::h     78       theUnitBasis[1].rotateZ(gamma - CLHEP::halfpi);  // X-Y opening angle
 79       // Z' axis computed by hand to get both      79       // Z' axis computed by hand to get both opening angles right
 80       // X'.Z' = cos(alpha), Y'.Z' = cos(beta)     80       // X'.Z' = cos(alpha), Y'.Z' = cos(beta), solve for Z' components
 81       x3 = cosa, y3 = (cosb - cosa * cosg) / s     81       x3 = cosa, y3 = (cosb - cosa * cosg) / sing, z3 = std::sqrt(1. - x3 * x3 - y3 * y3);
 82       theUnitBasis[2] = G4ThreeVector(x3, y3,      82       theUnitBasis[2] = G4ThreeVector(x3, y3, z3).unit();
 83       break;                                       83       break;
 84     case Monoclinic:                               84     case Monoclinic:
 85       theUnitBasis[2].rotateX(beta - CLHEP::ha     85       theUnitBasis[2].rotateX(beta - CLHEP::halfpi);  // Z-Y opening angle
 86       break;                                       86       break;
 87     case Triclinic:                                87     case Triclinic:
 88       theUnitBasis[1].rotateZ(gamma - CLHEP::h     88       theUnitBasis[1].rotateZ(gamma - CLHEP::halfpi);  // X-Y opening angle
 89       // Z' axis computed by hand to get both      89       // Z' axis computed by hand to get both opening angles right
 90       // X'.Z' = cos(alpha), Y'.Z' = cos(beta)     90       // X'.Z' = cos(alpha), Y'.Z' = cos(beta), solve for Z' components
 91       x3 = cosa, y3 = (cosb - cosa * cosg) / s     91       x3 = cosa, y3 = (cosb - cosa * cosg) / sing, z3 = std::sqrt(1. - x3 * x3 - y3 * y3);
 92       theUnitBasis[2] = G4ThreeVector(x3, y3,      92       theUnitBasis[2] = G4ThreeVector(x3, y3, z3).unit();
 93       break;                                       93       break;
 94     case Hexagonal:  // Tetragonal, C16=0          94     case Hexagonal:  // Tetragonal, C16=0
 95       theUnitBasis[1].rotateZ(30. * CLHEP::deg     95       theUnitBasis[1].rotateZ(30. * CLHEP::deg);  // X-Y opening angle
 96       break;                                       96       break;
 97     default:                                       97     default:
 98       break;                                       98       break;
 99   }                                                99   }
100                                                   100 
101   for (auto i : {0, 1, 2}) {                      101   for (auto i : {0, 1, 2}) {
102     theBasis[i] = theUnitBasis[i] * theSize[i]    102     theBasis[i] = theUnitBasis[i] * theSize[i];
103     theRecBasis[i] = theRecUnitBasis[i] * theR    103     theRecBasis[i] = theRecUnitBasis[i] * theRecSize[i];
104   }                                               104   }
105 }                                                 105 }
106                                                   106 
107 //....oooOO0OOooo........oooOO0OOooo........oo    107 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
108                                                   108 
109 theLatticeSystemType G4CrystalUnitCell::GetLat    109 theLatticeSystemType G4CrystalUnitCell::GetLatticeSystem(G4int aGroup)
110 {                                                 110 {
111   if (aGroup >= 1 && aGroup <= 2) {               111   if (aGroup >= 1 && aGroup <= 2) {
112     return Triclinic;                             112     return Triclinic;
113   }                                               113   }
114   if (aGroup >= 3 && aGroup <= 15) {              114   if (aGroup >= 3 && aGroup <= 15) {
115     return Monoclinic;                            115     return Monoclinic;
116   }                                               116   }
117   if (aGroup >= 16 && aGroup <= 74) {             117   if (aGroup >= 16 && aGroup <= 74) {
118     return Orthorhombic;                          118     return Orthorhombic;
119   }                                               119   }
120   if (aGroup >= 75 && aGroup <= 142) {            120   if (aGroup >= 75 && aGroup <= 142) {
121     return Tetragonal;                            121     return Tetragonal;
122   }                                               122   }
123   if (aGroup == 146 || aGroup == 148 || aGroup    123   if (aGroup == 146 || aGroup == 148 || aGroup == 155 || aGroup == 160 || aGroup == 161 ||
124       aGroup == 166 || aGroup == 167)             124       aGroup == 166 || aGroup == 167)
125   {                                               125   {
126     return Rhombohedral;                          126     return Rhombohedral;
127   }                                               127   }
128   if (aGroup >= 143 && aGroup <= 167) {           128   if (aGroup >= 143 && aGroup <= 167) {
129     return Hexagonal;                             129     return Hexagonal;
130   }                                               130   }
131   if (aGroup >= 168 && aGroup <= 194) {           131   if (aGroup >= 168 && aGroup <= 194) {
132     return Hexagonal;                             132     return Hexagonal;
133   }                                               133   }
134   if (aGroup >= 195 && aGroup <= 230) {           134   if (aGroup >= 195 && aGroup <= 230) {
135     return Cubic;                                 135     return Cubic;
136   }                                               136   }
137                                                   137 
138   return Amorphous;                               138   return Amorphous;
139 }                                                 139 }
140                                                   140 
141 //....oooOO0OOooo........oooOO0OOooo........oo    141 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
142                                                   142 
143 const G4ThreeVector& G4CrystalUnitCell::GetUni    143 const G4ThreeVector& G4CrystalUnitCell::GetUnitBasis(G4int idx) const
144 {                                                 144 {
145   return (idx >= 0 && idx < 3 ? theUnitBasis[i    145   return (idx >= 0 && idx < 3 ? theUnitBasis[idx] : nullVec);
146 }                                                 146 }
147                                                   147 
148 //....oooOO0OOooo........oooOO0OOooo........oo    148 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
149                                                   149 
150 const G4ThreeVector& G4CrystalUnitCell::GetBas    150 const G4ThreeVector& G4CrystalUnitCell::GetBasis(G4int idx) const
151 {                                                 151 {
152   return (idx >= 0 && idx < 3 ? theBasis[idx]     152   return (idx >= 0 && idx < 3 ? theBasis[idx] : nullVec);
153 }                                                 153 }
154                                                   154 
155 //....oooOO0OOooo........oooOO0OOooo........oo    155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
156                                                   156 
157 const G4ThreeVector& G4CrystalUnitCell::GetRec    157 const G4ThreeVector& G4CrystalUnitCell::GetRecUnitBasis(G4int idx) const
158 {                                                 158 {
159   return (idx >= 0 && idx < 3 ? theRecUnitBasi    159   return (idx >= 0 && idx < 3 ? theRecUnitBasis[idx] : nullVec);
160 }                                                 160 }
161                                                   161 
162 //....oooOO0OOooo........oooOO0OOooo........oo    162 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
163                                                   163 
164 const G4ThreeVector& G4CrystalUnitCell::GetRec    164 const G4ThreeVector& G4CrystalUnitCell::GetRecBasis(G4int idx) const
165 {                                                 165 {
166   return (idx >= 0 && idx < 3 ? theRecBasis[id    166   return (idx >= 0 && idx < 3 ? theRecBasis[idx] : nullVec);
167 }                                                 167 }
168                                                   168 
169 //....oooOO0OOooo........oooOO0OOooo........oo    169 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
170                                                   170 
171 G4ThreeVector G4CrystalUnitCell::GetUnitBasisT    171 G4ThreeVector G4CrystalUnitCell::GetUnitBasisTrigonal()
172 {                                                 172 {
173   // Z' axis computed by hand to get both open    173   // Z' axis computed by hand to get both opening angles right
174   // X'.Z' = cos(alpha), Y'.Z' = cos(beta), so    174   // X'.Z' = cos(alpha), Y'.Z' = cos(beta), solve for Z' components
175   G4double x3 = cosa, y3 = (cosb - cosa * cosg    175   G4double x3 = cosa, y3 = (cosb - cosa * cosg) / sing, z3 = std::sqrt(1. - x3 * x3 - y3 * y3);
176   return G4ThreeVector(x3, y3, z3).unit();        176   return G4ThreeVector(x3, y3, z3).unit();
177 }                                                 177 }
178                                                   178 
179 //....oooOO0OOooo........oooOO0OOooo........oo    179 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
180                                                   180 
181 G4bool G4CrystalUnitCell::FillAtomicUnitPos(G4    181 G4bool G4CrystalUnitCell::FillAtomicUnitPos(G4ThreeVector& pos, std::vector<G4ThreeVector>& vecout)
182 {                                                 182 {
183   // Just for testing the infrastructure          183   // Just for testing the infrastructure
184   G4ThreeVector aaa = pos;                        184   G4ThreeVector aaa = pos;
185   vecout.push_back(aaa);                          185   vecout.push_back(aaa);
186   vecout.emplace_back(2., 5., 3.);                186   vecout.emplace_back(2., 5., 3.);
187   return true;                                    187   return true;
188 }                                                 188 }
189                                                   189 
190 //....oooOO0OOooo........oooOO0OOooo........oo    190 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
191                                                   191 
192 G4bool G4CrystalUnitCell::FillAtomicPos(G4Thre    192 G4bool G4CrystalUnitCell::FillAtomicPos(G4ThreeVector& posin, std::vector<G4ThreeVector>& vecout)
193 {                                                 193 {
194   FillAtomicUnitPos(posin, vecout);               194   FillAtomicUnitPos(posin, vecout);
195   for (auto& vec : vecout) {                      195   for (auto& vec : vecout) {
196     vec.setX(vec.x() * theSize[0]);               196     vec.setX(vec.x() * theSize[0]);
197     vec.setY(vec.y() * theSize[1]);               197     vec.setY(vec.y() * theSize[1]);
198     vec.setZ(vec.z() * theSize[2]);               198     vec.setZ(vec.z() * theSize[2]);
199   }                                               199   }
200   return true;                                    200   return true;
201 }                                                 201 }
202                                                   202 
203 //....oooOO0OOooo........oooOO0OOooo........oo    203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
204                                                   204 
205 G4bool G4CrystalUnitCell::FillElReduced(G4doub    205 G4bool G4CrystalUnitCell::FillElReduced(G4double Cij[6][6])
206 {                                                 206 {
207   switch (GetLatticeSystem()) {                   207   switch (GetLatticeSystem()) {
208     case Amorphous:                               208     case Amorphous:
209       return FillAmorphous(Cij);                  209       return FillAmorphous(Cij);
210       break;                                      210       break;
211     case Cubic:  // Cubic, C44 set                211     case Cubic:  // Cubic, C44 set
212       return FillCubic(Cij);                      212       return FillCubic(Cij);
213       break;                                      213       break;
214     case Tetragonal:                              214     case Tetragonal:
215       return FillTetragonal(Cij);                 215       return FillTetragonal(Cij);
216       break;                                      216       break;
217     case Orthorhombic:                            217     case Orthorhombic:
218       return FillOrthorhombic(Cij);               218       return FillOrthorhombic(Cij);
219       break;                                      219       break;
220     case Rhombohedral:                            220     case Rhombohedral:
221       return FillRhombohedral(Cij);               221       return FillRhombohedral(Cij);
222       break;                                      222       break;
223     case Monoclinic:                              223     case Monoclinic:
224       return FillMonoclinic(Cij);                 224       return FillMonoclinic(Cij);
225       break;                                      225       break;
226     case Triclinic:                               226     case Triclinic:
227       return FillTriclinic(Cij);                  227       return FillTriclinic(Cij);
228       break;                                      228       break;
229     case Hexagonal:  // Tetragonal, C16=0         229     case Hexagonal:  // Tetragonal, C16=0
230       return FillHexagonal(Cij);                  230       return FillHexagonal(Cij);
231       break;                                      231       break;
232     default:                                      232     default:
233       break;                                      233       break;
234   }                                               234   }
235                                                   235 
236   return false;                                   236   return false;
237 }                                                 237 }
238                                                   238 
239 //....oooOO0OOooo........oooOO0OOooo........oo    239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
240                                                   240 
241 G4bool G4CrystalUnitCell::FillAmorphous(G4doub    241 G4bool G4CrystalUnitCell::FillAmorphous(G4double Cij[6][6]) const
242 {                                                 242 {
243   Cij[3][3] = 0.5 * (Cij[0][0] - Cij[0][1]);      243   Cij[3][3] = 0.5 * (Cij[0][0] - Cij[0][1]);
244   return true;                                    244   return true;
245 }                                                 245 }
246                                                   246 
247 //....oooOO0OOooo........oooOO0OOooo........oo    247 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
248                                                   248 
249 G4bool G4CrystalUnitCell::FillCubic(G4double C    249 G4bool G4CrystalUnitCell::FillCubic(G4double Cij[6][6]) const
250 {                                                 250 {
251   G4double C11 = Cij[0][0], C12 = Cij[0][1], C    251   G4double C11 = Cij[0][0], C12 = Cij[0][1], C44 = Cij[3][3];
252                                                   252 
253   for (size_t i = 0; i < 6; i++) {                253   for (size_t i = 0; i < 6; i++) {
254     for (size_t j = i; j < 6; j++) {              254     for (size_t j = i; j < 6; j++) {
255       if (i < 3 && j < 3) {                       255       if (i < 3 && j < 3) {
256         Cij[i][j] = (i == j) ? C11 : C12;         256         Cij[i][j] = (i == j) ? C11 : C12;
257       }                                           257       }
258       else if (i == j && i >= 3) {                258       else if (i == j && i >= 3) {
259         Cij[i][i] = C44;                          259         Cij[i][i] = C44;
260       }                                           260       }
261       else {                                      261       else {
262         Cij[i][j] = 0.;                           262         Cij[i][j] = 0.;
263       }                                           263       }
264     }                                             264     }
265   }                                               265   }
266                                                   266 
267   ReflectElReduced(Cij);                          267   ReflectElReduced(Cij);
268                                                   268 
269   return (C11 != 0. && C12 != 0. && C44 != 0.)    269   return (C11 != 0. && C12 != 0. && C44 != 0.);
270 }                                                 270 }
271                                                   271 
272 //....oooOO0OOooo........oooOO0OOooo........oo    272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
273                                                   273 
274 G4bool G4CrystalUnitCell::FillTetragonal(G4dou    274 G4bool G4CrystalUnitCell::FillTetragonal(G4double Cij[6][6]) const
275 {                                                 275 {
276   G4double C11 = Cij[0][0], C12 = Cij[0][1], C    276   G4double C11 = Cij[0][0], C12 = Cij[0][1], C13 = Cij[0][2], C16 = Cij[0][5];
277   G4double C33 = Cij[2][2], C44 = Cij[3][3], C    277   G4double C33 = Cij[2][2], C44 = Cij[3][3], C66 = Cij[5][5];
278                                                   278 
279   Cij[1][1] = C11;  // Copy small number of in    279   Cij[1][1] = C11;  // Copy small number of individual elements
280   Cij[1][2] = C13;                                280   Cij[1][2] = C13;
281   Cij[1][5] = -C16;                               281   Cij[1][5] = -C16;
282   Cij[4][4] = C44;                                282   Cij[4][4] = C44;
283                                                   283 
284   ReflectElReduced(Cij);                          284   ReflectElReduced(Cij);
285                                                   285 
286   // NOTE:  Do not test for C16 != 0., to allo    286   // NOTE:  Do not test for C16 != 0., to allow calling from Hexagonal
287   return (C11 != 0. && C12 != 0. && C13 != 0.     287   return (C11 != 0. && C12 != 0. && C13 != 0. && C33 != 0. && C44 != 0. && C66 != 0.);
288 }                                                 288 }
289                                                   289 
290 //....oooOO0OOooo........oooOO0OOooo........oo    290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
291                                                   291 
292 G4bool G4CrystalUnitCell::FillOrthorhombic(G4d    292 G4bool G4CrystalUnitCell::FillOrthorhombic(G4double Cij[6][6]) const
293 {                                                 293 {
294   // No degenerate elements; just check for al    294   // No degenerate elements; just check for all non-zero
295   ReflectElReduced(Cij);                          295   ReflectElReduced(Cij);
296                                                   296 
297   G4bool good = true;                             297   G4bool good = true;
298   for (size_t i = 0; i < 6; i++) {                298   for (size_t i = 0; i < 6; i++) {
299     for (size_t j = i + 1; j < 3; j++) {          299     for (size_t j = i + 1; j < 3; j++) {
300       good &= (Cij[i][j] != 0);                   300       good &= (Cij[i][j] != 0);
301     }                                             301     }
302   }                                               302   }
303                                                   303 
304   return good;                                    304   return good;
305 }                                                 305 }
306                                                   306 
307 //....oooOO0OOooo........oooOO0OOooo........oo    307 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
308                                                   308 
309 G4bool G4CrystalUnitCell::FillRhombohedral(G4d    309 G4bool G4CrystalUnitCell::FillRhombohedral(G4double Cij[6][6]) const
310 {                                                 310 {
311   G4double C11 = Cij[0][0], C12 = Cij[0][1], C    311   G4double C11 = Cij[0][0], C12 = Cij[0][1], C13 = Cij[0][2], C14 = Cij[0][3];
312   G4double C15 = Cij[0][4], C33 = Cij[2][2], C    312   G4double C15 = Cij[0][4], C33 = Cij[2][2], C44 = Cij[3][3], C66 = 0.5 * (C11 - C12);
313                                                   313 
314   Cij[1][1] = C11;  // Copy small number of in    314   Cij[1][1] = C11;  // Copy small number of individual elements
315   Cij[1][2] = C13;                                315   Cij[1][2] = C13;
316   Cij[1][3] = -C14;                               316   Cij[1][3] = -C14;
317   Cij[1][4] = -C15;                               317   Cij[1][4] = -C15;
318   Cij[3][5] = -C15;                               318   Cij[3][5] = -C15;
319   Cij[4][4] = C44;                                319   Cij[4][4] = C44;
320   Cij[4][5] = C14;                                320   Cij[4][5] = C14;
321                                                   321 
322   // NOTE:  C15 may be zero (c.f. rhombohedral    322   // NOTE:  C15 may be zero (c.f. rhombohedral(I) vs. (II))
323   return (C11 != 0 && C12 != 0 && C13 != 0 &&     323   return (C11 != 0 && C12 != 0 && C13 != 0 && C14 != 0. && C33 != 0. && C44 != 0. && C66 != 0.);
324 }                                                 324 }
325                                                   325 
326 //....oooOO0OOooo........oooOO0OOooo........oo    326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
327                                                   327 
328 G4bool G4CrystalUnitCell::FillMonoclinic(G4dou    328 G4bool G4CrystalUnitCell::FillMonoclinic(G4double Cij[6][6]) const
329 {                                                 329 {
330   // The monoclinic matrix has 13 independent     330   // The monoclinic matrix has 13 independent elements with no degeneracies
331   // Sanity condition is same as orthorhombic,    331   // Sanity condition is same as orthorhombic, plus C45, C(1,2,3)6
332                                                   332 
333   return (FillOrthorhombic(Cij) && Cij[0][5] !    333   return (FillOrthorhombic(Cij) && Cij[0][5] != 0. && Cij[1][5] != 0. && Cij[2][5] != 0. &&
334           Cij[3][4] != 0.);                       334           Cij[3][4] != 0.);
335 }                                                 335 }
336                                                   336 
337 //....oooOO0OOooo........oooOO0OOooo........oo    337 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
338                                                   338 
339 G4bool G4CrystalUnitCell::FillTriclinic(G4doub    339 G4bool G4CrystalUnitCell::FillTriclinic(G4double Cij[6][6]) const
340 {                                                 340 {
341   // The triclinic matrix has the entire upper    341   // The triclinic matrix has the entire upper half filled (21 elements)
342                                                   342 
343   ReflectElReduced(Cij);                          343   ReflectElReduced(Cij);
344                                                   344 
345   G4bool good = true;                             345   G4bool good = true;
346   for (size_t i = 0; i < 6; i++) {                346   for (size_t i = 0; i < 6; i++) {
347     for (size_t j = i; j < 6; j++) {              347     for (size_t j = i; j < 6; j++) {
348       good &= (Cij[i][j] != 0);                   348       good &= (Cij[i][j] != 0);
349     }                                             349     }
350   }                                               350   }
351                                                   351 
352   return good;                                    352   return good;
353 }                                                 353 }
354                                                   354 
355 //....oooOO0OOooo........oooOO0OOooo........oo    355 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
356                                                   356 
357 G4bool G4CrystalUnitCell::FillHexagonal(G4doub    357 G4bool G4CrystalUnitCell::FillHexagonal(G4double Cij[6][6]) const
358 {                                                 358 {
359   Cij[0][5] = 0.;                                 359   Cij[0][5] = 0.;
360   Cij[4][5] = 0.5 * (Cij[0][0] - Cij[0][1]);      360   Cij[4][5] = 0.5 * (Cij[0][0] - Cij[0][1]);
361   return true;                                    361   return true;
362 }                                                 362 }
363                                                   363 
364 //....oooOO0OOooo........oooOO0OOooo........oo    364 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
365                                                   365 
366 G4bool G4CrystalUnitCell::ReflectElReduced(G4d    366 G4bool G4CrystalUnitCell::ReflectElReduced(G4double Cij[6][6]) const
367 {                                                 367 {
368   for (size_t i = 1; i < 6; i++) {                368   for (size_t i = 1; i < 6; i++) {
369     for (size_t j = i + 1; j < 6; j++) {          369     for (size_t j = i + 1; j < 6; j++) {
370       Cij[j][i] = Cij[i][j];                      370       Cij[j][i] = Cij[i][j];
371     }                                             371     }
372   }                                               372   }
373   return true;                                    373   return true;
374 }                                                 374 }
375                                                   375 
376 //....oooOO0OOooo........oooOO0OOooo........oo    376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
377                                                   377 
378 G4double G4CrystalUnitCell::ComputeCellVolume(    378 G4double G4CrystalUnitCell::ComputeCellVolume()
379 {                                                 379 {
380   G4double a = theSize[0], b = theSize[1], c =    380   G4double a = theSize[0], b = theSize[1], c = theSize[2];
381                                                   381 
382   switch (GetLatticeSystem()) {                   382   switch (GetLatticeSystem()) {
383     case Amorphous:                               383     case Amorphous:
384       return 0.;                                  384       return 0.;
385       break;                                      385       break;
386     case Cubic:                                   386     case Cubic:
387       return a * a * a;                           387       return a * a * a;
388       break;                                      388       break;
389     case Tetragonal:                              389     case Tetragonal:
390       return a * a * c;                           390       return a * a * c;
391       break;                                      391       break;
392     case Orthorhombic:                            392     case Orthorhombic:
393       return a * b * c;                           393       return a * b * c;
394       break;                                      394       break;
395     case Rhombohedral:                            395     case Rhombohedral:
396       return a * a * a * std::sqrt(1. - 3. * c    396       return a * a * a * std::sqrt(1. - 3. * cosa * cosa + 2. * cosa * cosa * cosa);
397       break;                                      397       break;
398     case Monoclinic:                              398     case Monoclinic:
399       return a * b * c * sinb;                    399       return a * b * c * sinb;
400       break;                                      400       break;
401     case Triclinic:                               401     case Triclinic:
402       return a * b * c *                          402       return a * b * c *
403              std::sqrt(1. - cosa * cosa - cosb    403              std::sqrt(1. - cosa * cosa - cosb * cosb - cosg * cosg * 2. * cosa * cosb * cosg);
404       break;                                      404       break;
405     case Hexagonal:                               405     case Hexagonal:
406       return std::sqrt(3.0) / 2. * a * a * c;     406       return std::sqrt(3.0) / 2. * a * a * c;
407       break;                                      407       break;
408     default:                                      408     default:
409       break;                                      409       break;
410   }                                               410   }
411                                                   411 
412   return 0.;                                      412   return 0.;
413 }                                                 413 }
414                                                   414 
415 //....oooOO0OOooo........oooOO0OOooo........oo    415 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
416                                                   416 
417 G4double G4CrystalUnitCell::GetIntSp2(G4int h,    417 G4double G4CrystalUnitCell::GetIntSp2(G4int h, G4int k, G4int l)
418 {                                                 418 {
419   /* Reference:                                   419   /* Reference:
420    Table 2.4, pag. 65                             420    Table 2.4, pag. 65
421                                                   421 
422    @Inbook{Ladd2003,                              422    @Inbook{Ladd2003,
423    author="Ladd, Mark and Palmer, Rex",           423    author="Ladd, Mark and Palmer, Rex",
424    title="Lattices and Space-Group Theory",       424    title="Lattices and Space-Group Theory",
425    bookTitle="Structure Determination by X-ray    425    bookTitle="Structure Determination by X-ray Crystallography",
426    year="2003",                                   426    year="2003",
427    publisher="Springer US",                       427    publisher="Springer US",
428    address="Boston, MA",                          428    address="Boston, MA",
429    pages="51--116",                               429    pages="51--116",
430    isbn="978-1-4615-0101-5",                      430    isbn="978-1-4615-0101-5",
431    doi="10.1007/978-1-4615-0101-5_2",             431    doi="10.1007/978-1-4615-0101-5_2",
432    url="http://dx.doi.org/10.1007/978-1-4615-0    432    url="http://dx.doi.org/10.1007/978-1-4615-0101-5_2"
433    }                                              433    }
434   */                                              434   */
435                                                   435 
436   G4double a = theSize[0], b = theSize[1], c =    436   G4double a = theSize[0], b = theSize[1], c = theSize[2];
437   G4double a2 = a * a, b2 = b * b, c2 = c * c;    437   G4double a2 = a * a, b2 = b * b, c2 = c * c;
438   G4double h2 = h * h, k2 = k * k, l2 = l * l;    438   G4double h2 = h * h, k2 = k * k, l2 = l * l;
439                                                   439 
440   G4double cos2a, sin2a, sin2b;                   440   G4double cos2a, sin2a, sin2b;
441   G4double R, T;                                  441   G4double R, T;
442                                                   442 
443   switch (GetLatticeSystem()) {                   443   switch (GetLatticeSystem()) {
444     case Amorphous:                               444     case Amorphous:
445       return 0.;                                  445       return 0.;
446       break;                                      446       break;
447     case Cubic:                                   447     case Cubic:
448       return a2 / (h2 + k2 + l2);                 448       return a2 / (h2 + k2 + l2);
449       break;                                      449       break;
450     case Tetragonal:                              450     case Tetragonal:
451       return 1.0 / ((h2 + k2) / a2 + l2 / c2);    451       return 1.0 / ((h2 + k2) / a2 + l2 / c2);
452       break;                                      452       break;
453     case Orthorhombic:                            453     case Orthorhombic:
454       return 1.0 / (h2 / a2 + k2 / b2 + l2 / c    454       return 1.0 / (h2 / a2 + k2 / b2 + l2 / c2);
455       break;                                      455       break;
456     case Rhombohedral:                            456     case Rhombohedral:
457       cos2a = cosa * cosa;                        457       cos2a = cosa * cosa;
458       sin2a = sina * sina;                        458       sin2a = sina * sina;
459       T = h2 + k2 + l2 + 2. * (h * k + k * l +    459       T = h2 + k2 + l2 + 2. * (h * k + k * l + h * l) * ((cos2a - cosa) / sin2a);
460       R = sin2a / (1. - 3 * cos2a + 2. * cos2a    460       R = sin2a / (1. - 3 * cos2a + 2. * cos2a * cosa);
461       return a * a / (T * R);                     461       return a * a / (T * R);
462       break;                                      462       break;
463     case Monoclinic:                              463     case Monoclinic:
464       sin2b = sinb * sinb;                        464       sin2b = sinb * sinb;
465       return 1. / (1. / sin2b * (h2 / a2 + l2     465       return 1. / (1. / sin2b * (h2 / a2 + l2 / c2 - 2 * h * l * cosb / (a * c)) + k2 / b2);
466       break;                                      466       break;
467     case Triclinic:                               467     case Triclinic:
468       return 1. / GetRecIntSp2(h, k, l);          468       return 1. / GetRecIntSp2(h, k, l);
469       break;                                      469       break;
470     case Hexagonal:                               470     case Hexagonal:
471       return 1. / ((4. * (h2 + k2 + h * k) / (    471       return 1. / ((4. * (h2 + k2 + h * k) / (3. * a2)) + l2 / c2);
472       break;                                      472       break;
473     default:                                      473     default:
474       break;                                      474       break;
475   }                                               475   }
476                                                   476 
477   return 0.;                                      477   return 0.;
478 }                                                 478 }
479                                                   479 
480 //....oooOO0OOooo........oooOO0OOooo........oo    480 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
481                                                   481 
482 G4double G4CrystalUnitCell::GetRecIntSp2(G4int    482 G4double G4CrystalUnitCell::GetRecIntSp2(G4int h, G4int k, G4int l)
483 {                                                 483 {
484   /* Reference:                                   484   /* Reference:
485    Table 2.4, pag. 65                             485    Table 2.4, pag. 65
486                                                   486 
487    @Inbook{Ladd2003,                              487    @Inbook{Ladd2003,
488    author="Ladd, Mark and Palmer, Rex",           488    author="Ladd, Mark and Palmer, Rex",
489    title="Lattices and Space-Group Theory",       489    title="Lattices and Space-Group Theory",
490    bookTitle="Structure Determination by X-ray    490    bookTitle="Structure Determination by X-ray Crystallography",
491    year="2003",                                   491    year="2003",
492    publisher="Springer US",                       492    publisher="Springer US",
493    address="Boston, MA",                          493    address="Boston, MA",
494    pages="51--116",                               494    pages="51--116",
495    isbn="978-1-4615-0101-5",                      495    isbn="978-1-4615-0101-5",
496    doi="10.1007/978-1-4615-0101-5_2",             496    doi="10.1007/978-1-4615-0101-5_2",
497    url="http://dx.doi.org/10.1007/978-1-4615-0    497    url="http://dx.doi.org/10.1007/978-1-4615-0101-5_2"
498    }                                              498    }
499    */                                             499    */
500                                                   500 
501   G4double a = theRecSize[0], b = theRecSize[1    501   G4double a = theRecSize[0], b = theRecSize[1], c = theRecSize[2];
502   G4double a2 = a * a, b2 = b * b, c2 = c * c;    502   G4double a2 = a * a, b2 = b * b, c2 = c * c;
503   G4double h2 = h * h, k2 = k * k, l2 = l * l;    503   G4double h2 = h * h, k2 = k * k, l2 = l * l;
504                                                   504 
505   switch (GetLatticeSystem()) {                   505   switch (GetLatticeSystem()) {
506     case Amorphous:                               506     case Amorphous:
507       return 0.;                                  507       return 0.;
508       break;                                      508       break;
509     case Cubic:                                   509     case Cubic:
510       return a2 * (h2 + k2 + l2);                 510       return a2 * (h2 + k2 + l2);
511       break;                                      511       break;
512     case Tetragonal:                              512     case Tetragonal:
513       return (h2 + k2) * a2 + l2 * c2;            513       return (h2 + k2) * a2 + l2 * c2;
514       break;                                      514       break;
515     case Orthorhombic:                            515     case Orthorhombic:
516       return h2 * a2 + k2 + b2 + h2 * c2;         516       return h2 * a2 + k2 + b2 + h2 * c2;
517       break;                                      517       break;
518     case Rhombohedral:                            518     case Rhombohedral:
519       return (h2 + k2 + l2 + 2. * (h * k + k *    519       return (h2 + k2 + l2 + 2. * (h * k + k * l + h * l) * cosar) * a2;
520       break;                                      520       break;
521     case Monoclinic:                              521     case Monoclinic:
522       return h2 * a2 + k2 * b2 + l2 * c2 + 2.     522       return h2 * a2 + k2 * b2 + l2 * c2 + 2. * h * l * a * c * cosbr;
523       break;                                      523       break;
524     case Triclinic:                               524     case Triclinic:
525       return h2 * a2 + k2 * b2 + l2 * c2 + 2.     525       return h2 * a2 + k2 * b2 + l2 * c2 + 2. * k * l * b * c * cosar + 2. * l * h * c * a * cosbr +
526              2. * h * k * a * b * cosgr;          526              2. * h * k * a * b * cosgr;
527       break;                                      527       break;
528     case Hexagonal:                               528     case Hexagonal:
529       return (h2 + k2 + h * k) * a2 + l2 * c2;    529       return (h2 + k2 + h * k) * a2 + l2 * c2;
530       break;                                      530       break;
531     default:                                      531     default:
532       break;                                      532       break;
533   }                                               533   }
534                                                   534 
535   return 0.;                                      535   return 0.;
536 }                                                 536 }
537                                                   537 
538 //....oooOO0OOooo........oooOO0OOooo........oo    538 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
539                                                   539 
540 G4double G4CrystalUnitCell::GetIntCosAng(G4int    540 G4double G4CrystalUnitCell::GetIntCosAng(G4int h1, G4int k1, G4int l1, G4int h2, G4int k2, G4int l2)
541 {                                                 541 {
542   /* Reference:                                   542   /* Reference:
543    Table 2.4, pag. 65                             543    Table 2.4, pag. 65
544                                                   544 
545    @Inbook{Kelly2012,                             545    @Inbook{Kelly2012,
546    author="Anthony A. Kelly and Kevin M. Knowl    546    author="Anthony A. Kelly and Kevin M. Knowles",
547    title="Appendix 3 Interplanar Spacings and     547    title="Appendix 3 Interplanar Spacings and Interplanar Angles",
548    bookTitle="Crystallography and Crystal Defe    548    bookTitle="Crystallography and Crystal Defects, 2nd Edition",
549    year="2012",                                   549    year="2012",
550    publisher="John Wiley & Sons, Ltd.",           550    publisher="John Wiley & Sons, Ltd.",
551    isbn="978-0-470-75014-8",                      551    isbn="978-0-470-75014-8",
552    doi="10.1002/9781119961468",                   552    doi="10.1002/9781119961468",
553    url="http://onlinelibrary.wiley.com/book/10    553    url="http://onlinelibrary.wiley.com/book/10.1002/9781119961468"
554    }                                              554    }
555    */                                             555    */
556                                                   556 
557   G4double a = theRecSize[0], b = theRecSize[1    557   G4double a = theRecSize[0], b = theRecSize[1], c = theRecSize[2];
558   G4double a2 = a * a, b2 = b * b, c2 = c * c;    558   G4double a2 = a * a, b2 = b * b, c2 = c * c;
559   G4double dsp1dsp2;                              559   G4double dsp1dsp2;
560   switch (GetLatticeSystem()) {                   560   switch (GetLatticeSystem()) {
561     case Amorphous:                               561     case Amorphous:
562       return 0.;                                  562       return 0.;
563       break;                                      563       break;
564     case Cubic:                                   564     case Cubic:
565       return (h1 * h2 + k1 * k2 + l1 + l2) /      565       return (h1 * h2 + k1 * k2 + l1 + l2) /
566              (std::sqrt(h1 * h1 + k1 * k1 + l1    566              (std::sqrt(h1 * h1 + k1 * k1 + l1 * l1) * std::sqrt(h2 * h2 + k2 * k2 + l2 * l2));
567       break;                                      567       break;
568     case Tetragonal:                              568     case Tetragonal:
569       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    569       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
570       return 0.;                                  570       return 0.;
571       break;                                      571       break;
572     case Orthorhombic:                            572     case Orthorhombic:
573       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    573       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
574       return dsp1dsp2 * (h1 * h2 * a2 + k1 * k    574       return dsp1dsp2 * (h1 * h2 * a2 + k1 * k2 * a2 + l1 * l2 * c2);
575       break;                                      575       break;
576     case Rhombohedral:                            576     case Rhombohedral:
577       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    577       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
578       return dsp1dsp2 *                           578       return dsp1dsp2 *
579              (h1 * h2 * a2 + k1 * k2 * b2 + l1    579              (h1 * h2 * a2 + k1 * k2 * b2 + l1 * l2 * c2 + (k1 * l2 + k2 * l1) * b * c * cosar +
580                (h1 * l2 + h2 * l1) * a * c * c    580                (h1 * l2 + h2 * l1) * a * c * cosbr + (h1 * k2 + h2 * k1) * a * b * cosgr);
581       break;                                      581       break;
582     case Monoclinic:                              582     case Monoclinic:
583       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    583       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
584       return dsp1dsp2 *                           584       return dsp1dsp2 *
585              (h1 * h2 * a2 + k1 * k2 * b2 + l1    585              (h1 * h2 * a2 + k1 * k2 * b2 + l1 * l2 * c2 + (k1 * l2 + k2 * l1) * b * c * cosar +
586                (h1 * l2 + h2 * l1) * a * c * c    586                (h1 * l2 + h2 * l1) * a * c * cosbr + (h1 * k2 + h2 * k1) * a * b * cosgr);
587       break;                                      587       break;
588     case Triclinic:                               588     case Triclinic:
589       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    589       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
590       return dsp1dsp2 *                           590       return dsp1dsp2 *
591              (h1 * h2 * a2 + k1 * k2 * b2 + l1    591              (h1 * h2 * a2 + k1 * k2 * b2 + l1 * l2 * c2 + (k1 * l2 + k2 * l1) * b * c * cosar +
592                (h1 * l2 + h2 * l1) * a * c * c    592                (h1 * l2 + h2 * l1) * a * c * cosbr + (h1 * k2 + h2 * k1) * a * b * cosgr);
593       break;                                      593       break;
594     case Hexagonal:                               594     case Hexagonal:
595       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l    595       dsp1dsp2 = std::sqrt(GetIntSp2(h1, k1, l1) * GetIntSp2(h2, k2, l2));
596       return dsp1dsp2 * ((h1 * h2 + k1 * k2 +     596       return dsp1dsp2 * ((h1 * h2 + k1 * k2 + 0.5 * (h1 * k2 + k1 * h2)) * a2 + l1 * l2 * c2);
597       break;                                      597       break;
598     default:                                      598     default:
599       break;                                      599       break;
600   }                                               600   }
601                                                   601 
602   return 0.;                                      602   return 0.;
603 }                                                 603 }
604                                                   604 
605 //....oooOO0OOooo........oooOO0OOooo........oo    605 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
606                                                   606