PSCF v1.3
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.
24 */
25 template <int D>
27 : nParameter_(0),
28 isInitialized_(false),
29 signalPtr_(nullptr)
30 { initializeToZero(); }
31
32 /*
33 * Destructor.
34 */
35 template <int D>
38
39 /*
40 * Set all the unit cell parameters.
41 */
42 template <int D>
43 void
45 {
47 isInitialized_ = false;
48 for (int i = 0; i < nParameter_; ++i) {
49 parameters_[i] = parameters[i];
50 }
51 setLattice();
52 }
53
54 /*
55 * Get all the unit cell parameters.
56 */
57 template <int D>
59 {
61 for (int i = 0; i < nParameter_; ++i) {
62 parameters.append(parameters_[i]);
63 }
64 return parameters;
65 }
66
67 /*
68 * Get square magnitude of reciprocal basis vector.
69 */
70 template <int D>
71 double UnitCellBase<D>::ksq(IntVec<D> const & k) const
72 {
73 RealVec<D> g(0.0);
74 RealVec<D> p;
75 for (int i = 0; i < D; ++i) {
76 p.multiply(kBasis_[i], k[i]);
77 g += p;
78 }
79 double value = 0.0;
80 for (int i = 0; i < D; ++i) {
81 value += g[i]*g[i];
82 }
83 return value;
84 }
85
86 /*
87 * Get magnitude of derivative of square of reciprocal basis vector.
88 */
89 template <int D>
90 double UnitCellBase<D>::dksq(IntVec<D> const & vec, int n) const
91 {
92 double element = 0.0;
93 double value = 0.0;
94
95 for (int p = 0; p < D; ++p){
96 for (int q = 0; q < D; ++q){
97 element = dkkBasis(n, p, q);
98 value += vec[p]*vec[q]*element;
99 }
100 }
101
102 return value;
103 }
104
105 // Signal
106
107 template <int D>
110
111 template <int D>
113 { return bool(signalPtr_); }
114
115 template <int D>
117 {
118 UTIL_CHECK(signalPtr_);
119 return *signalPtr_;
120 }
121
122 // Protected member functions
123
124 /*
125 * Initialize internal arrays to zero.
126 */
127 template <int D>
128 void UnitCellBase<D>::initializeToZero()
129 {
130 // Initialize all elements to zero
131 int i, j, k;
132 for (i = 0; i < D; ++i) {
133 for (j = 0; j < D; ++j) {
134 rBasis_[i][j] = 0.0;
135 kBasis_[i][j] = 0.0;
136 }
137 }
138 for (k = 0; k < 6; ++k){
139 for (i = 0; i < D; ++i) {
140 for (j = 0; j < D; ++j) {
141 drBasis_[k](i,j) = 0.0;
142 dkBasis_[k](i,j) = 0.0;
143 drrBasis_[k](i,j) = 0.0;
144 dkkBasis_[k](i,j) = 0.0;
145 }
146 }
147 }
149
150 /*
151 * Compute quantities involving derivatives.
152 */
153 template <int D>
154 void UnitCellBase<D>::computeDerivatives()
155 {
156 // Compute dkBasis
157 int p, q, r, s, t;
158 for (p = 0; p < nParameter_; ++p) {
159 for (q = 0; q < D; ++q) {
160 for (r = 0; r < D; ++r) {
161
162 // Loop over free indices s, t
163 for (s = 0; s < D; ++s) {
164 for (t = 0; t < D; ++t) {
165 dkBasis_[p](q,r)
166 -= kBasis_[q][s]*drBasis_[p](t,s)*kBasis_[t][r];
167 }
168 }
169 dkBasis_[p](q,r) /= 2.0*Constants::Pi;
170
172 }
173 }
174
175 // Compute drrBasis and dkkBasis
176 for (p = 0; p < nParameter_; ++p) {
177 for (q = 0; q < D; ++q) {
178 for (r = 0; r < D; ++r) {
179 for (s = 0; s < D; ++s) {
180 drrBasis_[p](q,r) += rBasis_[q][s]*drBasis_[p](r,s);
181 drrBasis_[p](q,r) += rBasis_[r][s]*drBasis_[p](q,s);
182 dkkBasis_[p](q,r) += kBasis_[q][s]*dkBasis_[p](r,s);
183 dkkBasis_[p](q,r) += kBasis_[r][s]*dkBasis_[p](q,s);
184
185 }
186 }
187 }
188 }
189
190 }
191
192 /*
193 * Set all lattice parameters.
194 */
195 template <int D>
197 {
198 initializeToZero();
199 setBasis();
200 computeDerivatives();
201 isInitialized_ = true;
202 if (hasSignal()) {
203 signalPtr_->notify();
204 }
205 }
206
207}
208}
209#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_
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 CField.cpp:11
PSCF package top-level namespace.
Definition param_pc.dox:1