1#ifndef PRDC_UNIT_CELL_BASE_H
2#define PRDC_UNIT_CELL_BASE_H
11#include <util/signal/Signal.h>
12#include <util/containers/FArray.h>
13#include <util/containers/FSArray.h>
14#include <util/containers/FMatrix.h>
15#include <pscf/math/IntVec.h>
16#include <pscf/math/RealVec.h>
17#include <util/math/Constants.h>
200 template <
class Observer>
303 bool hasSignal()
const;
311 void initializeToZero();
320 virtual void setBasis() = 0;
325 void computeDerivatives();
345 {
return nParameter_; }
355 for (
int i = 0; i < nParameter_; ++i) {
356 parameters.
append(parameters_[i]);
367 {
return parameters_[i]; }
375 {
return rBasis_[i]; }
383 {
return kBasis_[i]; }
391 {
return drBasis_[k](i,j); }
399 {
return dkBasis_[k](i, j); }
407 {
return dkkBasis_[k](i, j); }
415 {
return drrBasis_[k](i, j); }
423 {
return isInitialized_; }
433 isInitialized_(false),
435 { initializeToZero(); }
455 isInitialized_ =
false;
456 for (
int i = 0; i < nParameter_; ++i) {
457 parameters_[i] = parameters[i];
470 for (
int i = 0; i < D; ++i) {
475 for (
int i = 0; i < D; ++i) {
487 double element = 0.0;
490 for (
int p = 0; p < D; ++p){
491 for (
int q = 0; q < D; ++q){
492 element = dkkBasis(n, p, q);
493 value += vec[p]*vec[q]*element;
503 template <
class Observer>
510 signalPtr_->addObserver(observer, methodPtr);
519 signalPtr_ =
nullptr;
527 return signalPtr_->nObserver();
543 for (i = 0; i < D; ++i) {
544 for (j = 0; j < D; ++j) {
549 for (k = 0; k < 6; ++k){
550 for (i = 0; i < D; ++i) {
551 for (j = 0; j < D; ++j) {
552 drBasis_[k](i,j) = 0.0;
553 dkBasis_[k](i,j) = 0.0;
554 drrBasis_[k](i,j) = 0.0;
555 dkkBasis_[k](i,j) = 0.0;
565 void UnitCellBase<D>::computeDerivatives()
569 for (p = 0; p < nParameter_; ++p) {
570 for (q = 0; q < D; ++q) {
571 for (r = 0; r < D; ++r) {
574 for (s = 0; s < D; ++s) {
575 for (t = 0; t < D; ++t) {
577 -= kBasis_[q][s]*drBasis_[p](t,s)*kBasis_[t][r];
587 for (p = 0; p < nParameter_; ++p) {
588 for (q = 0; q < D; ++q) {
589 for (r = 0; r < D; ++r) {
590 for (s = 0; s < D; ++s) {
591 drrBasis_[p](q,r) += rBasis_[q][s]*drBasis_[p](r,s);
592 drrBasis_[p](q,r) += rBasis_[r][s]*drBasis_[p](q,s);
593 dkkBasis_[p](q,r) += kBasis_[q][s]*dkBasis_[p](r,s);
594 dkkBasis_[p](q,r) += kBasis_[r][s]*dkBasis_[p](q,s);
611 computeDerivatives();
612 isInitialized_ =
true;
614 signalPtr_->notify();
620 {
return bool(signalPtr_); }
An IntVec<D, T> is a D-component vector of elements of integer type T.
Base class template for a crystallographic unit cell.
bool isInitialized() const
Has this unit cell been initialized?
bool isInitialized_
Has this unit cell been fully initialized?
~UnitCellBase()
Destructor.
const RealVec< D > & rBasis(int i) const
Get Bravais basis vector i, denoted by a_i.
void setParameters(FSArray< double, 6 > const ¶meters)
Set all the parameters of unit cell.
void addObserver(Observer &observer, void(Observer::*methodPtr)())
Add an Observer to this unit cell.
UnitCellBase()
Constructor.
const RealVec< D > & kBasis(int i) const
Get reciprocal basis vector i, denoted by b_i.
double drrBasis(int k, int i, int j) const
Get derivative of dot product ai.aj with respect to parameter k.
FArray< RealVec< D >, D > rBasis_
Array of Bravais lattice basis vectors.
FArray< FMatrix< double, D, D >, 6 > drBasis_
Array of derivatives of rBasis.
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.
FSArray< double, 6 > parameters() const
Get the parameters of this unit cell.
double drBasis(int k, int i, int j) const
Get component j of derivative of rBasis vector a_i w/respect to k.
FArray< double, 6 > parameters_
Parameters used to describe the unit cell.
void clearObservers()
Clear all observers and delete the Signal<> object.
virtual double ksq(IntVec< D > const &k) const
Compute square magnitude of reciprocal lattice vector.
FArray< FMatrix< double, D, D >, 6 > dkBasis_
Array of derivatives of kBasis.
FArray< FMatrix< double, D, D >, 6 > drrBasis_
Array of derivatives of a_i.a_j.
int nObserver() const
Return the current number of observers.
double dkBasis(int k, int i, int j) const
Get component j of derivative of kBasis vector b_i w/respect to k.
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.
double parameter(int i) const
Get a single parameter of this unit cell.
FArray< FMatrix< double, D, D >, 6 > dkkBasis_
Array of derivatives of b_i.b_j.
int nParameter() const
Get the number of parameters in the unit cell.
A RealVec<D, T> is D-component vector with elements of floating type T.
Vec< D, T > & multiply(const Vec< D, T > &v, T s)
Multiply a vector v by a scalar s.
static const double Pi
Trigonometric constant Pi.
A fixed size (static) contiguous array template.
A fixed capacity (static) contiguous array with a variable logical size.
int size() const
Return logical size of this array (i.e., number of elements).
void append(Data const &data)
Append data to the end of the array.
Abstract class template for observer in the observer design pattern.
Notifier (or subject) in the Observer design pattern.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
PSCF package top-level namespace.
Utility classes for scientific computation.