PSCF v1.1
UnitCell2.cpp
1/*
2* PSCF - Polymer Self-Consistent Field Theory
3*
4* Copyright 2016 - 2022, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8#include "UnitCell.h"
9#include <util/math/Constants.h>
10
11namespace Pscf
12{
13
14 using namespace Util;
15
16 /*
17 * Constructor.
18 */
20 : lattice_(Null)
21 {}
22
23 /*
24 * Read the lattice system and set nParameter.
25 */
27 {
28 UTIL_CHECK(lattice_ != UnitCell<2>::Null);
29 if (lattice_ == UnitCell<2>::Square) {
30 nParameter_ = 1;
31 } else
32 if (lattice_ == UnitCell<2>::Hexagonal) {
33 nParameter_ = 1;
34 } else
35 if (lattice_ == UnitCell<2>::Rectangular) {
36 nParameter_ = 2;
37 } else
38 if (lattice_ == UnitCell<2>::Rhombic) {
39 nParameter_ = 2;
40 } else
41 if (lattice_ == UnitCell<2>::Oblique) {
42 nParameter_ = 3;
43 } else {
44 UTIL_THROW("Invalid lattice system value");
45 }
46 }
47
48 /*
49 * Set the Bravais and reciprocal lattice vectors.
50 */
51 void UnitCell<2>::setBasis()
52 {
53 UTIL_CHECK(lattice_ != UnitCell<2>::Null);
54 UTIL_CHECK(nParameter_ > 0);
55
56 double twoPi = 2.0*Constants::Pi;
57 int i;
58 if (lattice_ == UnitCell<2>::Square) {
59 UTIL_CHECK(nParameter_ == 1);
60 for (i=0; i < 2; ++i) {
61 rBasis_[i][i] = parameters_[0];
62 kBasis_[i][i] = twoPi/parameters_[0];
63 drBasis_[0](i,i) = 1.0;
64 }
65 } else
66 if (lattice_ == UnitCell<2>::Rectangular) {
67 UTIL_CHECK(nParameter_ == 2);
68 for (i=0; i < 2; ++i) {
69 rBasis_[i][i] = parameters_[i];
70 kBasis_[i][i] = twoPi/parameters_[i];
71 drBasis_[i](i,i) = 1.0;
72 }
73 } else
74 if (lattice_ == UnitCell<2>::Hexagonal) {
75 UTIL_CHECK(nParameter_ == 1);
76 double a = parameters_[0];
77 double rt3 = sqrt(3.0);
78
79 rBasis_[0][0] = a;
80 rBasis_[0][1] = 0.0;
81 rBasis_[1][0] = -0.5*a;
82 rBasis_[1][1] = 0.5*rt3*a;
83
84 drBasis_[0](0, 0) = 1.0;
85 drBasis_[0](0, 1) = 0.0;
86 drBasis_[0](1, 0) = -0.5;
87 drBasis_[0](1, 1) = 0.5*rt3;
88
89 kBasis_[0][0] = twoPi/a;
90 kBasis_[0][1] = twoPi/(rt3*a);
91 kBasis_[1][0] = 0.0;
92 kBasis_[1][1] = twoPi/(0.5*rt3*a);
93 } else
94 if (lattice_ == UnitCell<2>::Rhombic) {
95 UTIL_CHECK(nParameter_ == 2);
96 double a = parameters_[0];
97 double gamma = parameters_[1];
98 // gamma is the angle between the two Bravais basis vectors
99
100 double cg = cos(gamma);
101 double sg = sin(gamma);
102
103
104 rBasis_[0][0] = a;
105 rBasis_[0][1] = 0.0;
106 rBasis_[1][0] = cg*a;
107 rBasis_[1][1] = sg*a;
108
109 drBasis_[0](0, 0) = 1.0;
110 drBasis_[0](0, 1) = 0.0;
111 drBasis_[0](1, 0) = cg;
112 drBasis_[0](1, 1) = sg;
113 drBasis_[1](1, 0) = -sg*a;
114 drBasis_[1](1, 1) = cg*a;
115
116 kBasis_[0][0] = twoPi/a;
117 kBasis_[0][1] = -twoPi*cg/(sg*a);
118 kBasis_[1][0] = 0.0;
119 kBasis_[1][1] = twoPi/(a*sg);
120
121 } else
122 if (lattice_ == UnitCell<2>::Oblique) {
123 UTIL_CHECK(nParameter_ == 3);
124 double a = parameters_[0];
125 double b = parameters_[1];
126 double gamma = parameters_[2];
127 // gamma is the angle between the two Bravais basis vectors
128
129 double cg = cos(gamma);
130 double sg = sin(gamma);
131
132 rBasis_[0][0] = a;
133 rBasis_[0][1] = 0.0;
134 rBasis_[1][0] = cg*b;
135 rBasis_[1][1] = sg*b;
136
137 drBasis_[0](0, 0) = 1.0;
138 drBasis_[0](0, 1) = 0.0;
139 drBasis_[1](1, 0) = cg;
140 drBasis_[1](1, 1) = sg;
141 drBasis_[1](1, 0) = -sg*b;
142 drBasis_[1](1, 1) = cg*b;
143
144 kBasis_[0][0] = twoPi/a;
145 kBasis_[0][1] = -twoPi*cg/(sg*a);
146 kBasis_[1][0] = 0.0;
147 kBasis_[1][1] = twoPi/(b*sg);
148
149 } else {
150 UTIL_THROW("Unimplemented 2D lattice type");
151 }
152 }
153
154 /*
155 * Extract a UnitCell<2>::LatticeSystem from an istream as a string.
156 */
157 std::istream& operator >> (std::istream& in,
159 {
160
161 std::string buffer;
162 in >> buffer;
163 if (buffer == "Square" || buffer == "square") {
164 lattice = UnitCell<2>::Square;
165 } else
166 if (buffer == "Rectangular" || buffer == "rectangular") {
167 lattice = UnitCell<2>::Rectangular;
168 } else
169 if (buffer == "Rhombic" || buffer == "rhombic") {
170 lattice = UnitCell<2>::Rhombic;
171 } else
172 if (buffer == "Hexagonal" || buffer == "hexagonal") {
173 lattice = UnitCell<2>::Hexagonal;
174 } else
175 if (buffer == "Oblique" || buffer == "oblique") {
176 lattice = UnitCell<2>::Oblique;
177 } else {
178 UTIL_THROW("Invalid UnitCell<2>::LatticeSystem value input");
179 }
180 return in;
181 }
182
183 /*
184 * Insert a UnitCell<2>::LatticeSystem to an ostream as a string.
185 */
186 std::ostream& operator << (std::ostream& out,
188 {
189 if (lattice == UnitCell<2>::Square) {
190 out << "square";
191 } else
192 if (lattice == UnitCell<2>::Rectangular) {
193 out << "rectangular";
194 } else
195 if (lattice == UnitCell<2>::Rhombic) {
196 out << "rhombic";
197 } else
198 if (lattice == UnitCell<2>::Hexagonal) {
199 out << "hexagonal";
200 } else
201 if (lattice == UnitCell<2>::Oblique) {
202 out << "oblique";
203 } else
204 if (lattice == UnitCell<2>::Null) {
205 out << "Null";
206 } else {
207 UTIL_THROW("This should never happen");
208 }
209 return out;
210 }
211
212 /*
213 * Assignment operator.
214 */
216 {
217 isInitialized_ = false;
218 lattice_ = other.lattice_;
219 setNParameter();
220 UTIL_CHECK(nParameter_ == other.nParameter_);
221 for (int i = 0; i < nParameter_; ++i) {
222 parameters_[i] = other.parameters_[i];
223 }
224 setLattice();
225 return *this;
226 }
227
228 /*
229 * Set state of the unit cell (lattice system and parameters)
230 */
232 {
233 isInitialized_ = false;
234 lattice_ = lattice;
235 setNParameter();
236 }
237
238 /*
239 * Set state of the unit cell (lattice system and parameters)
240 */
242 FSArray<double, 6> const & parameters)
243 {
244 isInitialized_ = false;
245 lattice_ = lattice;
246 setNParameter();
247 for (int i = 0; i < nParameter_; ++i) {
248 parameters_[i] = parameters[i];
249 }
250 setLattice();
251 }
252
253}
int nParameter_
Number of parameters required to specify unit cell.
Definition: UnitCellBase.h:198
FArray< double, 6 > parameters_
Parameters used to describe the unit cell.
Definition: UnitCellBase.h:193
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition: UnitCell.h:44
static const double Pi
Trigonometric constant Pi.
Definition: Constants.h:35
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:38
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
Definition: Pair.h:44
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.
Definition: Pair.h:57