PSCF v1.1
UnitCellBase.h
1#ifndef PSCF_UNIT_CELL_BASE_H
2#define PSCF_UNIT_CELL_BASE_H
3
4/*
5* PSCF - Polymer Self-Consistent Field Theory
6*
7* Copyright 2016 - 2022, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <util/containers/FArray.h>
12#include <util/containers/FSArray.h>
13#include <util/containers/FMatrix.h>
14#include <pscf/math/IntVec.h>
15#include <pscf/math/RealVec.h>
16#include <util/math/Constants.h>
17
18namespace Pscf
19{
20
21 using namespace Util;
22
28 template <int D>
30 {
31 public:
32
37
42
51
57 virtual double ksq(IntVec<D> const & k) const;
58
69 virtual double dksq(IntVec<D> const & vec, int n) const;
70
74 int nParameter() const;
75
80
86 double parameter(int i) const;
87
93 const RealVec<D>& rBasis(int i) const;
94
100 const RealVec<D>& kBasis(int i) const;
101
109 double drBasis(int k, int i, int j) const;
110
118 double dkBasis(int k, int i, int j) const;
119
127 double drrBasis(int k, int i, int j) const;
128
136 double dkkBasis(int k, int i, int j) const;
137
141 bool isInitialized() const
142 { return isInitialized_; }
143
144 protected:
145
150
155
163
171
180
189
194
199
204
211
212 private:
213
220 void initializeToZero();
221
229 virtual void setBasis() = 0;
230
234 void computeDerivatives();
235
236 };
237
238 /*
239 * Get the number of Parameters in the unit cell.
240 */
241 template <int D>
242 inline
244 { return nParameter_; }
245
246 /*
247 * Get the unit cell parameters.
248 */
249 template <int D>
250 inline
252 {
253 FSArray<double, 6> parameters;
254 for (int i = 0; i < nParameter_; ++i) {
255 parameters.append(parameters_[i]);
256 }
257 return parameters;
258 }
259
260 /*
261 * Get a single parameter of the unit cell.
262 */
263 template <int D>
264 inline
265 double UnitCellBase<D>::parameter(int i) const
266 { return parameters_[i]; }
267
268 /*
269 * Get Bravais basis vector i.
270 */
271 template <int D>
272 inline
274 { return rBasis_[i]; }
275
276 /*
277 * Get reciprocal basis vector i.
278 */
279 template <int D>
280 inline
282 { return kBasis_[i]; }
283
284 /*
285 * Get component j of derivative of r basis vector i w/respect to param k.
286 */
287 template <int D>
288 inline
289 double UnitCellBase<D>::drBasis(int k, int i, int j) const
290 { return drBasis_[k](i,j); }
291
292 /*
293 * Get component j of derivative of r basis vector i w/respect to param k.
294 */
295 template <int D>
296 inline
297 double UnitCellBase<D>::dkBasis(int k, int i, int j) const
298 { return dkBasis_[k](i, j); }
299
300 /*
301 * Get the derivative of ki*kj with respect to parameter k.
302 */
303 template <int D>
304 inline
305 double UnitCellBase<D>::dkkBasis(int k, int i, int j) const
306 { return dkkBasis_[k](i, j); }
307
308 /*
309 * Get the derivative of ri*rj with respect to parameter k.
310 */
311 template <int D>
312 inline
313 double UnitCellBase<D>::drrBasis(int k, int i, int j) const
314 { return drrBasis_[k](i, j); }
315
316 // Non-inline member functions
317
318 /*
319 * Constructor.
320 */
321 template <int D>
323 : nParameter_(0),
324 isInitialized_(false)
325 {}
326
327 /*
328 * Destructor.
329 */
330 template <int D>
332 {}
333
334 /*
335 * Set all the parameters in the unit cell.
336 */
337 template <int D>
339 {
340 UTIL_CHECK(parameters.size() == nParameter_);
341 isInitialized_ = false;
342 for (int i = 0; i < nParameter_; ++i) {
343 parameters_[i] = parameters[i];
344 }
345 setLattice();
346 }
347
348 /*
349 * Get square magnitude of reciprocal basis vector.
350 */
351 template <int D>
352 double UnitCellBase<D>::ksq(IntVec<D> const & k) const
353 {
354 RealVec<D> g(0.0);
355 RealVec<D> p;
356 for (int i = 0; i < D; ++i) {
357 p.multiply(kBasis_[i], k[i]);
358 g += p;
359 }
360 double value = 0.0;
361 for (int i = 0; i < D; ++i) {
362 value += g[i]*g[i];
363 }
364 return value;
365 }
366
367 /*
368 * Get magnitude of derivative of square of reciprocal basis vector.
369 */
370 template <int D>
371 double UnitCellBase<D>::dksq(IntVec<D> const & vec, int n) const
372 {
373 double element = 0.0;
374 double value = 0.0;
375
376 for (int p = 0; p < D; ++p){
377 for (int q = 0; q < D; ++q){
378 element = dkkBasis(n, p, q);
379 value += vec[p]*vec[q]*element;
380 }
381 }
382
383 return value;
384 }
385
386 // Protected member functions
387
388 /*
389 * Initialize internal arrays to zero.
390 */
391 template <int D>
393 {
394 // Initialize all elements to zero
395 int i, j, k;
396 for (i = 0; i < D; ++i) {
397 for (j = 0; j < D; ++j) {
398 rBasis_[i][j] = 0.0;
399 kBasis_[i][j] = 0.0;
400 }
401 }
402 for (k = 0; k < 6; ++k){
403 for (i = 0; i < D; ++i) {
404 for (j = 0; j < D; ++j) {
405 drBasis_[k](i,j) = 0.0;
406 dkBasis_[k](i,j) = 0.0;
407 drrBasis_[k](i,j) = 0.0;
408 dkkBasis_[k](i,j) = 0.0;
409 }
410 }
411 }
412 }
413
414 /*
415 * Compute quantities involving derivatives.
416 */
417 template <int D>
418 void UnitCellBase<D>::computeDerivatives()
419 {
420 // Compute dkBasis
421 int p, q, r, s, t;
422 for (p = 0; p < nParameter_; ++p) {
423 for (q = 0; q < D; ++q) {
424 for (r = 0; r < D; ++r) {
425
426 // Loop over free indices s, t
427 for (s = 0; s < D; ++s) {
428 for (t = 0; t < D; ++t) {
429 dkBasis_[p](q,r)
430 -= kBasis_[q][s]*drBasis_[p](t,s)*kBasis_[t][r];
431 }
432 }
433 dkBasis_[p](q,r) /= 2.0*Constants::Pi;
434
435 }
436 }
437 }
438
439 // Compute drrBasis and dkkBasis
440 for (p = 0; p < nParameter_; ++p) {
441 for (q = 0; q < D; ++q) {
442 for (r = 0; r < D; ++r) {
443 for (s = 0; s < D; ++s) {
444 drrBasis_[p](q,r) += rBasis_[q][s]*drBasis_[p](r,s);
445 drrBasis_[p](q,r) += rBasis_[r][s]*drBasis_[p](q,s);
446 dkkBasis_[p](q,r) += kBasis_[q][s]*dkBasis_[p](r,s);
447 dkkBasis_[p](q,r) += kBasis_[r][s]*dkBasis_[p](q,s);
448
449 }
450 }
451 }
452 }
453
454 }
455
456 /*
457 * Set all lattice parameters.
458 */
459 template <int D>
461 {
462 initializeToZero();
463 setBasis();
464 computeDerivatives();
465 isInitialized_ = true;
466 }
467
468}
469#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition: IntVec.h:27
A RealVec<D, T> is D-component vector with elements of floating type T.
Definition: RealVec.h:28
Base class template for a crystallographic unit cell.
Definition: UnitCellBase.h:30
FArray< FMatrix< double, D, D >, 6 > drrBasis_
Array of derivatives of a_i.a_j.
Definition: UnitCellBase.h:179
FArray< FMatrix< double, D, D >, 6 > drBasis_
Array of derivatives of rBasis.
Definition: UnitCellBase.h:162
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
int nParameter() const
Get the number of parameters in the unit cell.
Definition: UnitCellBase.h:243
virtual double dksq(IntVec< D > const &vec, int n) const
Compute derivative of square wavevector w/respect to cell parameter.
Definition: UnitCellBase.h:371
const RealVec< D > & kBasis(int i) const
Get reciprocal basis vector i, denoted by b_i.
Definition: UnitCellBase.h:281
FArray< FMatrix< double, D, D >, 6 > dkBasis_
Array of derivatives of kBasis.
Definition: UnitCellBase.h:170
void setParameters(FSArray< double, 6 > const &parameters)
Set all the parameters of unit cell.
Definition: UnitCellBase.h:338
double drrBasis(int k, int i, int j) const
Get derivative of dot product ai.aj with respect to parameter k.
Definition: UnitCellBase.h:313
FArray< FMatrix< double, D, D >, 6 > dkkBasis_
Array of derivatives of b_i.b_j.
Definition: UnitCellBase.h:188
void setLattice()
Compute all private data, given latticeSystem and parameters.
Definition: UnitCellBase.h:460
virtual double ksq(IntVec< D > const &k) const
Compute square magnitude of reciprocal lattice vector.
Definition: UnitCellBase.h:352
~UnitCellBase()
Destructor.
Definition: UnitCellBase.h:331
bool isInitialized_
Has this unit cell been fully initialized?
Definition: UnitCellBase.h:203
bool isInitialized() const
Has this unit cell been initialized?
Definition: UnitCellBase.h:141
double dkBasis(int k, int i, int j) const
Get component j of derivative of kBasis vector b_i w/respect to k.
Definition: UnitCellBase.h:297
double parameter(int i) const
Get a single parameter of this unit cell.
Definition: UnitCellBase.h:265
FArray< RealVec< D >, D > rBasis_
Array of Bravais lattice basis vectors.
Definition: UnitCellBase.h:149
FSArray< double, 6 > parameters() const
Get the parameters of this unit cell.
Definition: UnitCellBase.h:251
UnitCellBase()
Constructor.
Definition: UnitCellBase.h:322
double dkkBasis(int k, int i, int j) const
Get derivative of dot product bi.bj with respect to parameter k.
Definition: UnitCellBase.h:305
double drBasis(int k, int i, int j) const
Get component j of derivative of rBasis vector a_i w/respect to k.
Definition: UnitCellBase.h:289
const RealVec< D > & rBasis(int i) const
Get Bravais basis vector i, denoted by a_i.
Definition: UnitCellBase.h:273
FArray< RealVec< D >, D > kBasis_
Array of reciprocal lattice basis vectors.
Definition: UnitCellBase.h:154
Vec< D, T > & multiply(const Vec< D, T > &v, T s)
Multiply a vector v by a scalar s.
Definition: Vec.h:505
static const double Pi
Trigonometric constant Pi.
Definition: Constants.h:35
A fixed size (static) contiguous array template.
Definition: FArray.h:47
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:38
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
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
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1