PSCF v1.2
replicateUnitCell.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 "replicateUnitCell.h"
9#include <prdc/crystal/UnitCell.h>
10#include <pscf/math/IntVec.h>
11#include <util/containers/FArray.h>
12#include <util/containers/FSArray.h>
13
14namespace Pscf {
15namespace Prdc {
16
17 using namespace Util;
18
19 /*
20 * Create a replicated UnitCell<1>.
21 */
22 template<>
23 void replicateUnitCell(IntVec<1> const & replicas,
24 UnitCell<1> const & cellIn,
25 UnitCell<1> & cellOut)
26 {
27 UTIL_CHECK(cellIn.lattice() != UnitCell<1>::Null);
28 FSArray<double, 6> const & paramIn = cellIn.parameters();
29
30 // Choose lattice type and parameter
33 if (cellIn.lattice() == UnitCell<1>::Lamellar) {
34 lattice = UnitCell<1>::Lamellar;
35 param[0] = replicas[0]*paramIn[0];
36 } else {
37 UTIL_THROW("Invalid lattice system value");
38 }
39
40 cellOut.set(lattice);
41 FSArray<double, 6> paramOut;
42 for (int i=0; i < cellOut.nParameter(); ++i) {
43 paramOut.append(param[i]);
44 }
45 cellOut.set(lattice, paramOut);
46 }
47
48 /*
49 * Create a replicated UnitCell<2>.
50 */
51 template<>
52 void replicateUnitCell(IntVec<2> const & replicas,
53 UnitCell<2> const & cellIn,
54 UnitCell<2> & cellOut)
55 {
56 UTIL_CHECK(cellIn.lattice() != UnitCell<2>::Null);
57 FSArray<double, 6> const & paramIn = cellIn.parameters();
58
59 // Choose lattice type and parameters
62 int nParameter;
63 if (cellIn.lattice() == UnitCell<2>::Square) {
64 UTIL_CHECK(cellIn.nParameter() == 1);
65 if (replicas[0] == replicas[1]) {
66 lattice = UnitCell<2>::Square;
67 param[0] = replicas[0]*paramIn[0];
68 nParameter = 1;
69 } else {
71 param[0] = replicas[0]*paramIn[0];
72 param[1] = replicas[1]*paramIn[0];
73 nParameter = 2;
74 }
75 } else
76 if (cellIn.lattice() == UnitCell<2>::Rectangular) {
77 UTIL_CHECK(cellIn.nParameter() == 2);
79 param[0] = replicas[0]*paramIn[0];
80 param[1] = replicas[1]*paramIn[1];
81 nParameter = 2;
82 } else
83 if (cellIn.lattice() == UnitCell<2>::Hexagonal) {
84 UTIL_CHECK(cellIn.nParameter() == 1);
85 if (replicas[0] == replicas[1]) {
86 lattice = UnitCell<2>::Hexagonal;
87 param[0] = replicas[0]*paramIn[0];
88 nParameter = 1;
89 } else {
90 UTIL_THROW("Prohibited unit cell replication");
91 }
92 } else
93 if (cellIn.lattice() == UnitCell<2>::Rhombic) {
94 UTIL_CHECK(cellIn.nParameter() == 2);
95 if (replicas[0] == replicas[1]) {
96 lattice = UnitCell<2>::Rhombic;
97 param[0] = replicas[0]*paramIn[0];
98 param[1] = paramIn[1];
99 nParameter = 2;
100 } else {
101 lattice = UnitCell<2>::Oblique;
102 param[0] = replicas[0]*paramIn[0];
103 param[1] = replicas[1]*paramIn[0];
104 param[2] = paramIn[1];
105 nParameter = 3;
106 }
107 } else
108 if (cellIn.lattice() == UnitCell<2>::Oblique) {
109 UTIL_CHECK(cellIn.nParameter() == 3);
110 lattice = UnitCell<2>::Oblique;
111 param[0] = replicas[0]*paramIn[0];
112 param[1] = replicas[1]*paramIn[1];
113 param[2] = paramIn[2];
114 nParameter = 3;
115 } else {
116 UTIL_THROW("Invalid lattice system value");
117 }
118
119 // Set cellOut object
120 cellOut.set(lattice);
121 UTIL_CHECK(cellOut.nParameter() == nParameter);
122 FSArray<double, 6> paramOut;
123 for (int i=0; i < cellOut.nParameter(); ++i) {
124 paramOut.append(param[i]);
125 }
126 cellOut.set(lattice, paramOut);
127 }
128
129 /*
130 * Create a replicated UnitCell<3>.
131 */
132 template<>
133 void replicateUnitCell(IntVec<3> const & replicas,
134 UnitCell<3> const & cellIn,
135 UnitCell<3> & cellOut)
136 {
137 UTIL_CHECK(cellIn.lattice() != UnitCell<3>::Null);
138 FSArray<double, 6> const & paramIn = cellIn.parameters();
139
140 // Choose lattice type and parameters
142 FArray<double, 6> param;
143 int nParameter;
144 if (cellIn.lattice() == UnitCell<3>::Cubic) {
145 UTIL_CHECK(cellIn.nParameter() == 1);
146 if (replicas[0] == replicas[1]) {
147 if (replicas[1] == replicas[2]) {
148 lattice = UnitCell<3>::Cubic;
149 param[0] = replicas[0]*paramIn[0];
150 nParameter = 1;
151 } else {
152 lattice = UnitCell<3>::Tetragonal;
153 param[0] = replicas[0]*paramIn[0];
154 param[1] = replicas[2]*paramIn[0];
155 nParameter = 2;
156 }
157 } else {
159 param[0] = replicas[0]*paramIn[0];
160 param[1] = replicas[1]*paramIn[0];
161 param[2] = replicas[2]*paramIn[0];
162 nParameter = 3;
163 }
164 } else
165 if (cellIn.lattice() == UnitCell<3>::Tetragonal) {
166 UTIL_CHECK(cellIn.nParameter() == 2);
167 if (replicas[0] == replicas[1]) {
168 lattice = UnitCell<3>::Tetragonal;
169 param[0] = replicas[0]*paramIn[0];
170 param[1] = replicas[2]*paramIn[1];
171 nParameter = 2;
172 } else {
174 param[0] = replicas[0]*paramIn[0];
175 param[1] = replicas[1]*paramIn[0];
176 param[2] = replicas[2]*paramIn[1];
177 nParameter = 3;
178 }
179 } else
180 if (cellIn.lattice() == UnitCell<3>::Orthorhombic) {
181 UTIL_CHECK(cellIn.nParameter() == 3);
183 param[0] = replicas[0]*paramIn[0];
184 param[1] = replicas[1]*paramIn[1];
185 param[2] = replicas[2]*paramIn[2];
186 nParameter = 3;
187 } else
188 if (cellIn.lattice() == UnitCell<3>::Monoclinic) {
189 UTIL_CHECK(cellIn.nParameter() == 4);
190 lattice = UnitCell<3>::Monoclinic;
191 param[0] = replicas[0]*paramIn[0];
192 param[1] = replicas[1]*paramIn[1];
193 param[2] = replicas[2]*paramIn[2];
194 param[3] = paramIn[3];
195 nParameter = 4;
196 } else
197 if (cellIn.lattice() == UnitCell<3>::Triclinic) {
198 UTIL_CHECK(cellIn.nParameter() == 6);
199 lattice = UnitCell<3>::Triclinic;
200 param[0] = replicas[0]*paramIn[0];
201 param[1] = replicas[1]*paramIn[1];
202 param[2] = replicas[2]*paramIn[2];
203 param[3] = paramIn[3];
204 param[4] = paramIn[4];
205 param[5] = paramIn[5];
206 nParameter = 6;
207 } else
208 if (cellIn.lattice() == UnitCell<3>::Rhombohedral) {
209 UTIL_CHECK(cellIn.nParameter() == 2);
210 if (replicas[0] == replicas[1] && replicas[1] == replicas[2]) {
212 param[0] = replicas[0]*paramIn[0];
213 param[1] = paramIn[1];
214 nParameter = 2;
215 } else {
216 UTIL_THROW("Prohibited unit cell replication");
217 }
218 } else
219 if (cellIn.lattice() == UnitCell<3>::Hexagonal) {
220 UTIL_CHECK(cellIn.nParameter() == 2);
221 if (replicas[0] == replicas[1]) {
222 lattice = UnitCell<3>::Hexagonal;
223 param[0] = replicas[0]*paramIn[0];
224 param[1] = replicas[2]*paramIn[1];
225 nParameter = 2;
226 } else {
227 UTIL_THROW("Prohibited unit cell replication");
228 }
229 } else {
230 UTIL_THROW("Invalid value of cellIn.lattice()");
231 }
232
233 // Set cellOut object
234 cellOut.set(lattice);
235 UTIL_CHECK(cellOut.nParameter() == nParameter);
236 FSArray<double, 6> paramOut;
237 for (int i=0; i < nParameter; ++i) {
238 paramOut.append(param[i]);
239 }
240 cellOut.set(lattice, paramOut);
241 }
242
243}
244}
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
FSArray< double, 6 > parameters() const
Get the parameters of this unit cell.
int nParameter() const
Get the number of parameters in the unit cell.
Base template for UnitCell<D> classes, D=1, 2 or 3.
Definition rpg/System.h:34
A fixed size (static) contiguous array template.
Definition FArray.h:47
A fixed capacity (static) contiguous array with a variable logical size.
Definition rpg/System.h:28
void append(Data const &data)
Append data to the end of the array.
Definition FSArray.h:258
#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
void replicateUnitCell(IntVec< 1 > const &replicas, UnitCell< 1 > const &cellIn, UnitCell< 1 > &cellOut)
Create a replicated UnitCell<1>.
PSCF package top-level namespace.
Definition param_pc.dox:1
Utility classes for scientific computation.