9#include <util/math/Constants.h>
32 if (lattice_ == UnitCell<3>::Tetragonal) {
35 if (lattice_ == UnitCell<3>::Orthorhombic) {
38 if (lattice_ == UnitCell<3>::Monoclinic) {
41 if (lattice_ == UnitCell<3>::Triclinic) {
44 if (lattice_ == UnitCell<3>::Rhombohedral) {
47 if (lattice_ == UnitCell<3>::Hexagonal) {
61 void UnitCell<3>::setBasis()
69 if (lattice_ == UnitCell<3>::Cubic) {
71 for (i=0; i < 3; ++i) {
72 rBasis_[i][i] = parameters_[0];
73 kBasis_[i][i] = twoPi/parameters_[0];
74 drBasis_[0](i,i) = 1.0;
77 if (lattice_ == UnitCell<3>::Tetragonal) {
80 rBasis_[0][0] = parameters_[0];
81 rBasis_[1][1] = parameters_[0];
82 rBasis_[2][2] = parameters_[1];
84 drBasis_[0](0,0) = 1.0;
85 drBasis_[0](1,1) = 1.0;
86 drBasis_[1](2,2) = 1.0;
88 kBasis_[0][0] = twoPi/parameters_[0];
89 kBasis_[1][1] = kBasis_[0][0];
90 kBasis_[2][2] = twoPi/parameters_[1];
93 if (lattice_ == UnitCell<3>::Orthorhombic) {
95 for (i=0; i < 3; ++i) {
96 rBasis_[i][i] = parameters_[i];
97 drBasis_[i](i,i) = 1.0;
98 kBasis_[i][i] = twoPi/parameters_[i];
101 if (lattice_ == UnitCell<3>::Hexagonal) {
103 double a = parameters_[0];
104 double c = parameters_[1];
105 double rt3 = sqrt(3.0);
108 rBasis_[1][0] = -0.5*a;
109 rBasis_[1][1] = 0.5*rt3*a;
112 drBasis_[0](0, 0) = 1.0;
113 drBasis_[0](1, 0) = -0.5;
114 drBasis_[0](1, 1) = 0.5*rt3;
115 drBasis_[1](2, 2) = 1.0;
117 kBasis_[0][0] = twoPi/a;
118 kBasis_[0][1] = twoPi/(rt3*a);
120 kBasis_[1][1] = twoPi/(0.5*rt3*a);
121 kBasis_[2][2] = twoPi/(c);
124 if (lattice_ == UnitCell<3>::Rhombohedral) {
128 double a, beta, theta;
130 beta = parameters_[1];
131 theta = acos( sqrt( (2.0*cos(beta) + 1.0)/3.0 ) );
164 double cosT = cos(theta);
165 double sinT = sin(theta);
166 double sqrt3 = sqrt(3.0);
167 double sinPi3 = 0.5*sqrt3;
171 rBasis_[0][0] = sinT * a;
172 rBasis_[0][2] = cosT * a;
173 rBasis_[1][0] = -cosPi3 * sinT * a;
174 rBasis_[1][1] = sinPi3 * sinT * a;
175 rBasis_[1][2] = cosT * a;
176 rBasis_[2][0] = -cosPi3 * sinT * a;
177 rBasis_[2][1] = -sinPi3 * sinT * a;
178 rBasis_[2][2] = cosT * a;
181 kBasis_[0][0] = 2.0 * twoPi /( 3.0 * sinT * a);
182 kBasis_[0][2] = twoPi /( 3.0 * cosT * a);
183 kBasis_[1][0] = -2.0 * cosPi3 * twoPi /( 3.0 * sinT * a);
184 kBasis_[1][1] = 2.0 * sinPi3 * twoPi /( 3.0 * sinT * a);
185 kBasis_[1][2] = twoPi /( 3.0 * cosT * a);
186 kBasis_[2][0] = -2.0 * cosPi3 * twoPi /( 3.0 * sinT * a);
187 kBasis_[2][1] = -2.0 * sinPi3 * twoPi /( 3.0 * sinT * a);
188 kBasis_[2][2] = twoPi /( 3.0 * cosT * a);
191 drBasis_[0](0,0) = sinT;
192 drBasis_[0](0,2) = cosT;
193 drBasis_[0](1,0) = -cosPi3 * sinT;
194 drBasis_[0](1,1) = sinPi3 * sinT;
195 drBasis_[0](1,2) = cosT;
196 drBasis_[0](2,0) = -cosPi3 * sinT;
197 drBasis_[0](2,1) = -sinPi3* sinT;
198 drBasis_[0](2,2) = cosT;
201 double alpha = -sin(beta)/(3.0*cosT*sinT);
204 drBasis_[1](0,0) = cosT * alpha * a;
205 drBasis_[1](0,2) = -sinT * alpha * a;
206 drBasis_[1](1,0) = -cosPi3 * cosT * alpha * a;
207 drBasis_[1](1,1) = sinPi3 * cosT * alpha * a;
208 drBasis_[1](1,2) = -sinT * alpha * a;
209 drBasis_[1](2,0) = -cosPi3 * cosT * alpha * a;
210 drBasis_[1](2,1) = -sinPi3* cosT * alpha * a;
211 drBasis_[1](2,2) = -sinT * alpha * a;
214 if (lattice_ == UnitCell<3>::Monoclinic) {
227 double a = parameters_[0];
228 double b = parameters_[1];
229 double c = parameters_[2];
230 double beta = parameters_[3];
232 double cb = cos(beta);
233 double sb = sin(beta);
239 rBasis_[2][0] = c*cb;
240 rBasis_[2][2] = c*sb;
244 drBasis_[0](0,0) = 1.0;
245 drBasis_[1](1,1) = 1.0;
246 drBasis_[2](2,0) = cb;
247 drBasis_[2](2,2) = sb;
248 drBasis_[3](2,0) = c*sb;
249 drBasis_[3](2,2) = -c*cb;
252 kBasis_[0][0] = twoPi/a;
253 kBasis_[0][2] = -twoPi*cb/(a*sb);
254 kBasis_[1][1] = twoPi / b;
255 kBasis_[2][2] = twoPi/(c*sb);
258 if (lattice_ == UnitCell<3>::Triclinic) {
269 double a = parameters_[0];
270 double b = parameters_[1];
271 double c = parameters_[2];
272 double phi = parameters_[3];
273 double theta = parameters_[4];
274 double gamma = parameters_[5];
277 double cosPhi = cos(phi);
278 double sinPhi = sin(phi);
279 double cosTheta = cos(theta);
280 double sinTheta = sin(theta);
281 double cosGamma = cos(gamma);
282 double sinGamma = sin(gamma);
286 rBasis_[1][0] = b * cosGamma;
287 rBasis_[1][1] = b * sinGamma;
288 rBasis_[2][0] = c * sinTheta * cosPhi;
289 rBasis_[2][1] = c * sinTheta * sinPhi;
290 rBasis_[2][2] = c * cosTheta;
293 drBasis_[0](0,0) = 1.0;
294 drBasis_[1](1,0) = cosGamma;
295 drBasis_[1](1,1) = sinGamma;
296 drBasis_[2](2,0) = sinTheta * cosPhi;
297 drBasis_[2](2,1) = sinTheta * sinPhi;
298 drBasis_[2](2,2) = cosTheta;
299 drBasis_[3](2,0) = -c * sinTheta * sinPhi;
300 drBasis_[3](2,1) = c * sinTheta * cosPhi;
301 drBasis_[4](2,0) = c * cosTheta * cosPhi;
302 drBasis_[4](2,1) = c * cosTheta * sinPhi;
303 drBasis_[4](2,2) = -c * sinTheta;
304 drBasis_[5](1,0) = -b * sinGamma;
305 drBasis_[5](1,1) = b * cosGamma;
308 kBasis_[0][0] = twoPi / a;
309 kBasis_[0][1] = -twoPi * cosGamma / (a * sinGamma);
310 kBasis_[0][2] = sinTheta * (cosGamma * sinPhi - sinGamma * cosPhi);
311 kBasis_[0][2] = twoPi * kBasis_[0][2] / (a * sinGamma * cosTheta);
313 kBasis_[1][1] = twoPi/(b*sinGamma);
314 kBasis_[1][2] = -twoPi*sinPhi*sinTheta/(b*cosTheta*sinGamma);
316 kBasis_[2][2] = twoPi/(c*cosTheta);
332 if (buffer ==
"Cubic" || buffer ==
"cubic") {
335 if (buffer ==
"Tetragonal" || buffer ==
"tetragonal") {
338 if (buffer ==
"Orthorhombic" || buffer ==
"orthorhombic") {
341 if (buffer ==
"Monoclinic" || buffer ==
"monoclinic") {
344 if (buffer ==
"Triclinic" || buffer ==
"triclinic") {
347 if (buffer ==
"Rhombohedral" || buffer ==
"rhombohedral") {
350 if (buffer ==
"Hexagonal" || buffer ==
"hexagonal") {
353 UTIL_THROW(
"Invalid UnitCell<3>::LatticeSystem value input");
371 out <<
"orthorhombic";
380 out <<
"rhombohedral";
398 isInitialized_ =
false;
399 lattice_ = other.lattice_;
402 for (
int i = 0; i < nParameter_; ++i) {
414 isInitialized_ =
false;
425 isInitialized_ =
false;
428 for (
int i = 0; i < nParameter_; ++i) {
429 parameters_[i] = parameters[i];
int nParameter_
Number of parameters required to specify unit cell.
FArray< double, 6 > parameters_
Parameters used to describe the unit cell.
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.
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
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.