9#include <util/math/Constants.h>
34 lattice_ = other.lattice_;
53 if (lattice_ == UnitCell<3>::Tetragonal) {
56 if (lattice_ == UnitCell<3>::Orthorhombic) {
82 void UnitCell<3>::setBasis()
92 for (i=0; i < 3; ++i) {
93 rBasis_[i][i] = parameters_[0];
94 kBasis_[i][i] = twoPi/parameters_[0];
95 drBasis_[0](i,i) = 1.0;
101 rBasis_[0][0] = parameters_[0];
102 rBasis_[1][1] = parameters_[0];
103 rBasis_[2][2] = parameters_[1];
105 drBasis_[0](0,0) = 1.0;
106 drBasis_[0](1,1) = 1.0;
107 drBasis_[1](2,2) = 1.0;
109 kBasis_[0][0] = twoPi/parameters_[0];
110 kBasis_[1][1] = kBasis_[0][0];
111 kBasis_[2][2] = twoPi/parameters_[1];
116 for (i=0; i < 3; ++i) {
117 rBasis_[i][i] = parameters_[i];
118 drBasis_[i](i,i) = 1.0;
119 kBasis_[i][i] = twoPi/parameters_[i];
124 double a = parameters_[0];
125 double c = parameters_[1];
126 double rt3 = sqrt(3.0);
129 rBasis_[1][0] = -0.5*a;
130 rBasis_[1][1] = 0.5*rt3*a;
133 drBasis_[0](0, 0) = 1.0;
134 drBasis_[0](1, 0) = -0.5;
135 drBasis_[0](1, 1) = 0.5*rt3;
136 drBasis_[1](2, 2) = 1.0;
138 kBasis_[0][0] = twoPi/a;
139 kBasis_[0][1] = twoPi/(rt3*a);
141 kBasis_[1][1] = twoPi/(0.5*rt3*a);
142 kBasis_[2][2] = twoPi/(c);
149 double a, beta, theta;
151 beta = parameters_[1];
152 theta = acos( sqrt( (2.0*cos(beta) + 1.0)/3.0 ) );
185 double cosT = cos(theta);
186 double sinT = sin(theta);
187 double sqrt3 = sqrt(3.0);
188 double sinPi3 = 0.5*sqrt3;
192 rBasis_[0][0] = sinT * a;
193 rBasis_[0][2] = cosT * a;
194 rBasis_[1][0] = -cosPi3 * sinT * a;
195 rBasis_[1][1] = sinPi3 * sinT * a;
196 rBasis_[1][2] = cosT * a;
197 rBasis_[2][0] = -cosPi3 * sinT * a;
198 rBasis_[2][1] = -sinPi3 * sinT * a;
199 rBasis_[2][2] = cosT * a;
202 kBasis_[0][0] = 2.0 * twoPi /( 3.0 * sinT * a);
203 kBasis_[0][2] = twoPi /( 3.0 * cosT * a);
204 kBasis_[1][0] = -2.0 * cosPi3 * twoPi /( 3.0 * sinT * a);
205 kBasis_[1][1] = 2.0 * sinPi3 * twoPi /( 3.0 * sinT * a);
206 kBasis_[1][2] = twoPi /( 3.0 * cosT * a);
207 kBasis_[2][0] = -2.0 * cosPi3 * twoPi /( 3.0 * sinT * a);
208 kBasis_[2][1] = -2.0 * sinPi3 * twoPi /( 3.0 * sinT * a);
209 kBasis_[2][2] = twoPi /( 3.0 * cosT * a);
212 drBasis_[0](0,0) = sinT;
213 drBasis_[0](0,2) = cosT;
214 drBasis_[0](1,0) = -cosPi3 * sinT;
215 drBasis_[0](1,1) = sinPi3 * sinT;
216 drBasis_[0](1,2) = cosT;
217 drBasis_[0](2,0) = -cosPi3 * sinT;
218 drBasis_[0](2,1) = -sinPi3* sinT;
219 drBasis_[0](2,2) = cosT;
222 double alpha = -sin(beta)/(3.0*cosT*sinT);
225 drBasis_[1](0,0) = cosT * alpha * a;
226 drBasis_[1](0,2) = -sinT * alpha * a;
227 drBasis_[1](1,0) = -cosPi3 * cosT * alpha * a;
228 drBasis_[1](1,1) = sinPi3 * cosT * alpha * a;
229 drBasis_[1](1,2) = -sinT * alpha * a;
230 drBasis_[1](2,0) = -cosPi3 * cosT * alpha * a;
231 drBasis_[1](2,1) = -sinPi3* cosT * alpha * a;
232 drBasis_[1](2,2) = -sinT * alpha * a;
248 double a = parameters_[0];
249 double b = parameters_[1];
250 double c = parameters_[2];
251 double beta = parameters_[3];
253 double cb = cos(beta);
254 double sb = sin(beta);
260 rBasis_[2][0] = c*cb;
261 rBasis_[2][2] = c*sb;
265 drBasis_[0](0,0) = 1.0;
266 drBasis_[1](1,1) = 1.0;
267 drBasis_[2](2,0) = cb;
268 drBasis_[2](2,2) = sb;
269 drBasis_[3](2,0) = c*sb;
270 drBasis_[3](2,2) = -c*cb;
273 kBasis_[0][0] = twoPi/a;
274 kBasis_[0][2] = -twoPi*cb/(a*sb);
275 kBasis_[1][1] = twoPi / b;
276 kBasis_[2][2] = twoPi/(c*sb);
290 double a = parameters_[0];
291 double b = parameters_[1];
292 double c = parameters_[2];
293 double phi = parameters_[3];
294 double theta = parameters_[4];
295 double gamma = parameters_[5];
298 double cosPhi = cos(phi);
299 double sinPhi = sin(phi);
300 double cosTheta = cos(theta);
301 double sinTheta = sin(theta);
302 double cosGamma = cos(gamma);
303 double sinGamma = sin(gamma);
307 rBasis_[1][0] = b * cosGamma;
308 rBasis_[1][1] = b * sinGamma;
309 rBasis_[2][0] = c * sinTheta * cosPhi;
310 rBasis_[2][1] = c * sinTheta * sinPhi;
311 rBasis_[2][2] = c * cosTheta;
314 drBasis_[0](0,0) = 1.0;
315 drBasis_[1](1,0) = cosGamma;
316 drBasis_[1](1,1) = sinGamma;
317 drBasis_[2](2,0) = sinTheta * cosPhi;
318 drBasis_[2](2,1) = sinTheta * sinPhi;
319 drBasis_[2](2,2) = cosTheta;
320 drBasis_[3](2,0) = -c * sinTheta * sinPhi;
321 drBasis_[3](2,1) = c * sinTheta * cosPhi;
322 drBasis_[4](2,0) = c * cosTheta * cosPhi;
323 drBasis_[4](2,1) = c * cosTheta * sinPhi;
324 drBasis_[4](2,2) = -c * sinTheta;
325 drBasis_[5](1,0) = -b * sinGamma;
326 drBasis_[5](1,1) = b * cosGamma;
329 kBasis_[0][0] = twoPi / a;
330 kBasis_[0][1] = -twoPi * cosGamma / (a * sinGamma);
331 kBasis_[0][2] = sinTheta * (cosGamma * sinPhi - sinGamma * cosPhi);
332 kBasis_[0][2] = twoPi * kBasis_[0][2] / (a * sinGamma * cosTheta);
334 kBasis_[1][1] = twoPi/(b*sinGamma);
335 kBasis_[1][2] = -twoPi*sinPhi*sinTheta/(b*cosTheta*sinGamma);
337 kBasis_[2][2] = twoPi/(c*cosTheta);
398 if (buffer ==
"Cubic" || buffer ==
"cubic") {
401 if (buffer ==
"Tetragonal" || buffer ==
"tetragonal") {
404 if (buffer ==
"Orthorhombic" || buffer ==
"orthorhombic") {
407 if (buffer ==
"Monoclinic" || buffer ==
"monoclinic") {
410 if (buffer ==
"Triclinic" || buffer ==
"triclinic") {
413 if (buffer ==
"Rhombohedral" || buffer ==
"rhombohedral") {
416 if (buffer ==
"Hexagonal" || buffer ==
"hexagonal") {
419 UTIL_THROW(
"Invalid UnitCell<3>::LatticeSystem value input");
437 out <<
"orthorhombic";
446 out <<
"rhombohedral";
bool isInitialized_
Has this unit cell been fully initialized?
FArray< RealVec< D >, D > rBasis_
Array of Bravais lattice basis vectors.
FSArray< double, 6 > parameters() const
Get the parameters of this unit cell.
FArray< double, 6 > parameters_
Parameters used to describe the unit cell.
void setLattice()
Compute all protected data, given latticeSystem and parameters.
int nParameter_
Number of parameters required to specify unit cell.
void set(UnitCell< 3 >::LatticeSystem lattice)
Set the lattice system, but not unit cell parameters.
LatticeSystem lattice() const
Return lattice system enumeration value.
Base template for UnitCell<D> classes, D=1, 2 or 3.
static const double Pi
Trigonometric constant Pi.
A fixed capacity (static) contiguous array with a variable logical size.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Periodic fields and crystallography.
PSCF package top-level namespace.
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.