PSCF v1.4.0
UnitCellBase.tpp
1#ifndef PRDC_UNIT_CELL_BASE_TPP
2#define PRDC_UNIT_CELL_BASE_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "UnitCellBase.h"
12
13#include <util/signal/Signal.h>
14#include <util/math/Constants.h>
15#include <util/containers/FSArray.h>
16
17namespace Pscf {
18namespace Prdc {
19
20 using namespace Util;
21
22 /*
23 * Constructor (protected).
24 */
25 template <int D>
27 : nParameter_(0),
28 isInitialized_(false),
29 signalPtr_(nullptr)
30 { initializeToZero(); }
31
32 /*
33 * Set all the unit cell parameters.
34 */
35 template <int D>
36 void
38 {
40 isInitialized_ = false;
41 for (int i = 0; i < nParameter_; ++i) {
42 parameters_[i] = parameters[i];
43 }
44 setLattice();
45 }
46
47 /*
48 * Get all the unit cell parameters.
49 */
50 template <int D>
52 {
54 for (int i = 0; i < nParameter_; ++i) {
55 parameters.append(parameters_[i]);
56 }
57 return parameters;
58 }
59
60 /*
61 * Get square magnitude of reciprocal basis vector.
62 */
63 template <int D>
64 double UnitCellBase<D>::ksq(IntVec<D> const & k) const
65 {
66 RealVec<D> g(0.0);
67 RealVec<D> p;
68 for (int i = 0; i < D; ++i) {
69 p.multiply(kBasis_[i], k[i]);
70 g += p;
71 }
72 double value = 0.0;
73 for (int i = 0; i < D; ++i) {
74 value += g[i]*g[i];
75 }
76 return value;
77 }
78
79 /*
80 * Get magnitude of derivative of square of reciprocal basis vector.
81 */
82 template <int D>
83 double UnitCellBase<D>::dksq(IntVec<D> const & vec, int n) const
84 {
85 double element = 0.0;
86 double value = 0.0;
87
88 for (int p = 0; p < D; ++p){
89 for (int q = 0; q < D; ++q){
90 element = dkkBasis(n, p, q);
91 value += vec[p]*vec[q]*element;
92 }
93 }
94
95 return value;
96 }
97
98 // Signal
99
100 template <int D>
103
104 template <int D>
106 { return bool(signalPtr_); }
107
108 template <int D>
110 {
111 UTIL_CHECK(signalPtr_);
112 return *signalPtr_;
113 }
114
115 // Protected member functions
116
117 /*
118 * Initialize internal arrays to zero.
119 */
120 template <int D>
121 void UnitCellBase<D>::initializeToZero()
122 {
123 // Initialize all elements to zero
124 int i, j, k;
125 for (i = 0; i < D; ++i) {
126 for (j = 0; j < D; ++j) {
127 rBasis_[i][j] = 0.0;
128 kBasis_[i][j] = 0.0;
129 }
130 }
131 for (k = 0; k < 6; ++k){
132 for (i = 0; i < D; ++i) {
133 for (j = 0; j < D; ++j) {
134 drBasis_[k](i,j) = 0.0;
135 dkBasis_[k](i,j) = 0.0;
136 drrBasis_[k](i,j) = 0.0;
137 dkkBasis_[k](i,j) = 0.0;
138 }
139 }
141 }
142
143 /*
144 * Compute quantities involving derivatives.
145 */
146 template <int D>
147 void UnitCellBase<D>::computeDerivatives()
148 {
149 // Compute dkBasis
150 int p, q, r, s, t;
151 for (p = 0; p < nParameter_; ++p) {
152 for (q = 0; q < D; ++q) {
153 for (r = 0; r < D; ++r) {
154
155 // Loop over free indices s, t
156 for (s = 0; s < D; ++s) {
157 for (t = 0; t < D; ++t) {
158 dkBasis_[p](q,r)
159 -= kBasis_[q][s]*drBasis_[p](t,s)*kBasis_[t][r];
160 }
161 }
162 dkBasis_[p](q,r) /= 2.0*Constants::Pi;
164 }
165 }
166 }
167
168 // Compute drrBasis and dkkBasis
169 for (p = 0; p < nParameter_; ++p) {
170 for (q = 0; q < D; ++q) {
171 for (r = 0; r < D; ++r) {
172 for (s = 0; s < D; ++s) {
173 drrBasis_[p](q,r) += rBasis_[q][s]*drBasis_[p](r,s);
174 drrBasis_[p](q,r) += rBasis_[r][s]*drBasis_[p](q,s);
175 dkkBasis_[p](q,r) += kBasis_[q][s]*dkBasis_[p](r,s);
176 dkkBasis_[p](q,r) += kBasis_[r][s]*dkBasis_[p](q,s);
177
178 }
179 }
180 }
181 }
182
183 }
185 /*
186 * Set all lattice parameters.
187 */
188 template <int D>
190 {
191 initializeToZero();
192 setBasis();
193 computeDerivatives();
194 isInitialized_ = true;
195 if (hasSignal()) {
196 signalPtr_->notify();
197 }
198 }
199
200}
201}
202#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
bool isInitialized_
Has this unit cell been fully initialized?
void setParameters(FSArray< double, 6 > const &parameters)
Set all the parameters of unit cell.
void setSignal(Signal< void > &signal)
Associating an externally defined signal with this unit cell.
FArray< RealVec< D >, D > rBasis_
FArray< FMatrix< double, D, D >, 6 > drBasis_
double dkkBasis(int k, int i, int j) const
Get derivative of dot product bi.bj with respect to parameter k.
FArray< RealVec< D >, D > kBasis_
Array of reciprocal lattice basis vectors.
Signal< void > & signal()
Get the associated Signal by non-const reference.
FSArray< double, 6 > parameters() const
Get the parameters of this unit cell.
FArray< double, 6 > parameters_
Parameters used to describe the unit cell.
virtual double ksq(IntVec< D > const &k) const
Compute square magnitude of reciprocal lattice vector.
FArray< FMatrix< double, D, D >, 6 > dkBasis_
FArray< FMatrix< double, D, D >, 6 > drrBasis_
bool hasSignal() const
Does this object have an associated Signal<void>?
void setLattice()
Compute all protected data, given latticeSystem and parameters.
virtual double dksq(IntVec< D > const &vec, int n) const
Compute derivative of square wavevector w/respect to cell parameter.
int nParameter_
Number of parameters required to specify unit cell.
FArray< FMatrix< double, D, D >, 6 > dkkBasis_
A RealVec<D, T> is D-component vector with elements of floating type T.
Definition RealVec.h:28
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 capacity (static) contiguous array with a variable logical size.
Definition FSArray.h:38
Notifier (or subject) in the Observer design pattern.
Definition Signal.h:39
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
Periodic fields and crystallography.
Definition complex.cpp:11
PSCF package top-level namespace.