9#include <fd1d/domain/Domain.h>
47 ns_ = floor(
length()/dsTarget_ + 0.5) + 1;
51 ds_ =
length()/double(ns_ - 1);
75 ns_ = floor(
length()/dsTarget_ + 0.5) + 1;
79 ds_ =
length()/double(ns_ - 1);
137 ds_ =
length()/double(ns_ - 1);
140 double halfDs = 0.5*ds_;
141 for (
int i = 0; i < nx; ++i) {
142 dA_[i] = halfDs*w[i];
147 double db =
kuhn()/dx;
148 double c1 = halfDs*db*db/6.0;
151 if (mode == Planar) {
155 for (
int i = 1; i < nx - 1; ++i) {
167 double halfDx = 0.5*dx;
173 rp = 1.0 + halfDx/xMin;
174 if (mode == Spherical) {
178 if (mode == Spherical) {
181 if (mode == Cylindrical) {
192 for (
int i = 1; i < nx - 1; ++i) {
196 if (mode == Spherical) {
208 rm = 1.0 - halfDx/xMax;
209 if (mode == Spherical) {
218 for (
int i = 0; i < nx; ++i) {
221 for (
int i = 0; i < nx - 1; ++i) {
224 for (
int i = 0; i < nx - 1; ++i) {
229 for (
int i = 0; i < nx; ++i) {
258 for (i = 0; i < nx; ++i) {
267 for (i = 0; i < nx; ++i) {
268 cField()[i] += 0.5*p0.q(0)[i]*p1.q(ns_ - 1)[i];
270 for (
int j = 1; j < ns_ - 1; ++j) {
271 for (i = 0; i < nx; ++i) {
272 cField()[i] += p0.q(j)[i]*p1.q(ns_ - 1 - j)[i];
275 for (i = 0; i < nx; ++i) {
276 cField()[i] += 0.5*p0.q(ns_ - 1)[i]*p1.q(0)[i];
281 for (i = 0; i < nx; ++i) {
297 v_[0] = dB_[0]*q[0] + uB_[0]*q[1];
298 for (
int i = 1; i < nx - 1; ++i) {
299 v_[i] = dB_[i]*q[i] + lB_[i-1]*q[i-1] + uB_[i]*q[i+1];
301 v_[nx - 1] = dB_[nx-1]*q[nx-1] + lB_[nx-2]*q[nx-2];
302 solver_.
solve(v_, qNew);
double length() const
Get the length (number of monomers) in this block.
virtual void setLength(double length)
Set the length of this block.
double kuhn() const
Get monomer statistical segment length.
Propagator & propagator(int directionId)
Get a Propagator for a specified direction.
TP::CField & cField()
Get the associated monomer concentration field.
Domain const & domain() const
Return associated domain by reference.
virtual void setLength(double newLength)
Set length and readjust ds_ accordingly.
void step(DArray< double > const &q, DArray< double > &qNew)
Compute one step of integration loop, from i to i+1.
void setupSolver(DArray< double > const &w)
Set Crank-Nicholson solver for this block.
void setDiscretization(Domain const &domain, double ds)
Initialize discretization and allocate required memory.
void computeConcentration(double prefactor)
Compute concentration for block by integration.
One-dimensional spatial domain and discretization grid.
double dx() const
Get spatial grid step size.
bool isShell() const
Is this a cylindrical or spherical shell?
double xMin() const
Get minimum spatial coordinate.
double xMax() const
Get maximum spatial coordinate.
GeometryMode const & mode() const
Get coordinate system flag (Planar, Cylindrical or Spherical).
int nx() const
Get number of spatial grid points, including both endpoints.
void computeLU(const DArray< double > &d, const DArray< double > &u)
Compute LU decomposition of a symmetric tridiagonal matrix.
void solve(const DArray< double > &b, DArray< double > &x)
Solve Ax = b for known b to compute x.
void allocate(int n)
Allocate memory.
int capacity() const
Return allocated size.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
GeometryMode
Enumeration of geometrical modes for functions of one coordinate.
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.