PSCF v1.1
fd1d/domain/Domain.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 "Domain.h"
9#include <util/math/Constants.h>
10
11namespace Pscf {
12namespace Fd1d
13{
14
16 : xMin_(0.0),
17 xMax_(0.0),
18 dx_(0.0),
19 volume_(0.0),
20 nx_(0),
21 mode_(Planar),
22 isShell_(false)
23 { setClassName("Domain"); }
24
26 {}
27
28 void Domain::readParameters(std::istream& in)
29 {
30 mode_ = Planar;
31 isShell_ = false;
32 xMin_ = 0.0;
33 read(in, "mode", mode_);
34 if (mode_ == Planar) {
35 readOptional(in, "xMin", xMin_);
36 } else {
37 isShell_ = readOptional(in, "xMin", xMin_).isActive();
38 if (isShell_) {
39 UTIL_CHECK(xMin_ > 0.0);
40 }
41 }
42 read(in, "xMax", xMax_);
43 read(in, "nx", nx_);
44 dx_ = (xMax_ - xMin_)/double(nx_ - 1);
45 computeVolume();
46 }
47
48 void Domain::setPlanarParameters(double xMin, double xMax, int nx)
49 {
50 mode_ = Planar;
51 isShell_ = false;
52 xMin_ = xMin;
53 xMax_ = xMax;
54 nx_ = nx;
55 dx_ = (xMax_ - xMin_)/double(nx_ - 1);
56 computeVolume();
57 }
58
60 double xMin, double xMax, int nx)
61 {
62 mode_ = mode;
63 isShell_ = true;
64 xMin_ = xMin;
65 xMax_ = xMax;
66 nx_ = nx;
67 dx_ = (xMax_ - xMin_)/double(nx_ - 1);
68 computeVolume();
69 }
70
71 void Domain::setCylinderParameters(double xMax, int nx)
72 {
73 mode_ = Cylindrical;
74 isShell_ = false;
75 xMin_ = 0.0;
76 xMax_ = xMax;
77 nx_ = nx;
78 dx_ = xMax_/double(nx_ - 1);
79 computeVolume();
80 }
81
82 void Domain::setSphereParameters(double xMax, int nx)
83 {
84 mode_ = Spherical;
85 isShell_ = false;
86 xMin_ = 0.0;
87 xMax_ = xMax;
88 nx_ = nx;
89 dx_ = xMax_/double(nx_ - 1);
90 computeVolume();
91 }
92
93 void Domain::computeVolume()
94 {
95 if (mode_ == Planar) {
96 volume_ = xMax_ - xMin_;
97 } else
98 if (mode_ == Cylindrical) {
99 volume_ = xMax_*xMax_;
100 if (isShell_) {
101 volume_ -= xMin_*xMin_;
102 }
103 volume_ *= Constants::Pi;
104 } else
105 if (mode_ == Spherical) {
106 volume_ = xMax_*xMax_*xMax_;
107 if (isShell_) {
108 volume_ -= xMin_*xMin_*xMin_;
109 }
110 volume_ *= Constants::Pi*(4.0/3.0);
111 } else {
112 UTIL_THROW("Invalid geometry mode");
113 }
114 }
115
116 /*
117 * Compute spatial average of a field.
118 */
119 double Domain::spatialAverage(Field const & f) const
120 {
121 UTIL_CHECK(nx_ > 1);
122 UTIL_CHECK(dx_ > 0.0);
123 UTIL_CHECK(xMax_ - xMin_ >= dx_);
124 UTIL_CHECK(nx_ == f.capacity());
125
126 double sum = 0.0;
127 double norm = 0.0;
128 if (mode_ == Planar) {
129
130 sum += 0.5*f[0];
131 for (int i = 1; i < nx_ - 1; ++i) {
132 sum += f[i];
133 }
134 sum += 0.5*f[nx_ - 1];
135 norm = double(nx_ - 1);
136
137 } else
138 if (mode_ == Cylindrical) {
139
140 double x0 = xMin_/dx_;
141
142 // First value
143 if (isShell_) {
144 sum += 0.5*x0*f[0];
145 norm += 0.5*x0;
146 } else {
147 sum += f[0]/8.0;
148 norm += 1.0/8.0;
149 }
150
151 // Interior values
152 double x;
153 for (int i = 1; i < nx_ - 1; ++i) {
154 x = x0 + double(i);
155 sum += x*f[i];
156 norm += x;
157 }
158
159 // Last value
160 x = x0 + double(nx_-1);
161 sum += 0.5*x*f[nx_-1];
162 norm += 0.5*x;
163
164 } else
165 if (mode_ == Spherical) {
166
167 double x0 = xMin_/dx_;
168
169 // First value
170 if (isShell_) {
171 sum += 0.5*x0*x0*f[0];
172 norm += 0.5*x0*x0;
173 } else {
174 sum += f[0]/24.0;
175 norm += 1.0/24.0;
176 }
177
178 // Interior values
179 double x;
180 for (int i = 1; i < nx_ - 1; ++i) {
181 x = x0 + double(i);
182 sum += x*x*f[i];
183 norm += x*x;
184 }
185
186 // Last value
187 x = x0 + double(nx_-1);
188 sum += 0.5*x*x*f[nx_-1];
189 norm += 0.5*x*x;
190
191 } else {
192 UTIL_THROW("Invalid geometry mode");
193 }
194
195 return sum/norm;
196 }
197
198 /*
199 * Compute inner product of two real fields.
200 */
201 double Domain::innerProduct(Field const & f, Field const & g) const
202 {
203 // Preconditions
204 UTIL_CHECK(nx_ > 1);
205 UTIL_CHECK(nx_ == f.capacity());
206 UTIL_CHECK(nx_ == g.capacity());
207 if (!work_.isAllocated()) {
208 work_.allocate(nx_);
209 } else {
210 UTIL_ASSERT(nx_ == work_.capacity());
211 }
212
213 // Compute average of f(x)*g(x)
214 for (int i = 0; i < nx_; ++i) {
215 work_[i] = f[i]*g[i];
216 }
217 return spatialAverage(work_);
218 }
219
220}
221}
double spatialAverage(Field const &f) const
Compute spatial average of a field.
void setSphereParameters(double xMax, int nx)
Set grid parameters for a sphere.
double xMin() const
Get minimum spatial coordinate.
void setShellParameters(GeometryMode mode, double xMin, double xMax, int nx)
Set grid parameters for a cylindrical or spherical shell.
double xMax() const
Get maximum spatial coordinate.
void setPlanarParameters(double xMin, double xMax, int nx)
Set grid parameters for a planar domain.
GeometryMode const & mode() const
Get coordinate system flag (Planar, Cylindrical or Spherical).
void readParameters(std::istream &in)
Read all parameters and initialize.
int nx() const
Get number of spatial grid points, including both endpoints.
void setCylinderParameters(double xMax, int nx)
Set grid parameters for a cylinder.
double innerProduct(Field const &f, Field const &g) const
Compute inner product of two real fields.
int capacity() const
Return allocated size.
Definition: Array.h:159
static const double Pi
Trigonometric constant Pi.
Definition: Constants.h:35
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:199
bool isAllocated() const
Return true if this DArray has been allocated, false otherwise.
Definition: DArray.h:247
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void setClassName(const char *className)
Set class name string.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
Add and read a new optional ScalarParam < Type > object.
#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
#define UTIL_ASSERT(condition)
Assertion macro suitable for debugging serial or parallel code.
Definition: global.h:75
GeometryMode
Enumeration of geometrical modes for functions of one coordinate.
Definition: GeometryMode.h:30
C++ namespace for polymer self-consistent field theory (PSCF).