8#include "BinaryRelaxIterator.h"
9#include <r1d/system/System.h>
10#include <r1d/solvers/Mixture.h>
11#include <r1d/solvers/Polymer.h>
12#include <pscf/chem/Ensemble.h>
13#include <pscf/interaction/Interaction.h>
14#include <util/misc/Log.h>
15#include <util/misc/Timer.h>
42 read(in,
"epsilon", epsilon_);
43 read(in,
"maxIter", maxItr_);
44 read(in,
"lambdaPlus", lambdaPlus_);
45 read(in,
"lambdaMinus", lambdaMinus_);
51 void BinaryRelaxIterator::allocate()
53 if (isAllocated_)
return;
62 wFieldsNew_.allocate(nm);
63 cFieldsNew_.allocate(nm);
64 for (
int i = 0; i < nm; ++i) {
65 wFieldsNew_[i].allocate(nx);
66 cFieldsNew_[i].allocate(nx);
68 dWNew_[i].allocate(nx);
73 void BinaryRelaxIterator::computeDW(
Array<FieldT> const & wOld,
79 double dWm, dWp, c0, c1, w0, w1, wm;
85 for (
int i = 0; i < nx; ++i) {
92 dWm = 0.5*( c0 - c1 - wm/chi);
100 dWNorm = (dWpNorm + dWmNorm)/
double(nx);
101 dWNorm = sqrt(dWNorm);
104 void BinaryRelaxIterator::updateWFields(
Array<FieldT> const & wOld,
116 for (j = 0; j < nx; j++){
119 wNew[0][j] = w0 + dW[0][j];
120 wNew[1][j] = w1 + dW[1][j];
125 double shift = wNew[nm-1][nx-1];
126 for (i = 0; i < nm; ++i) {
127 for (j = 0; j < nx; ++j) {
151 for (
int i = 0; i < np; ++i) {
153 if (ensemble == Ensemble::Unknown) {
156 if (ensemble == Ensemble::Open) {
157 isCanonical_ =
false;
164 double shift =
wFields()[nm-1][nx-1];
166 for (i = 0; i < nm; ++i) {
167 for (j = 0; j < nx; ++j) {
179 for (i = 0; i < maxItr_; ++i) {
181 <<
" , error = " << dWNorm_
184 if (dWNorm_ < epsilon_) {
188 Log::file() <<
"The epsilon is " << epsilon_<< std::endl;
195 << timerTotal.
time() <<
" s " << std::endl;
196 Log::file() <<
"Average time cost of each iteration: "
197 << timerTotal.
time()/i <<
" s " << std::endl;
205 computeDW(wFieldsNew_, cFieldsNew_, dWNew_, dWNormNew_);
209 while (dWNormNew_ > dWNorm_ && j < 3) {
212 << dWNormNew_ <<
", decreasing increment" << std::endl;
217 << lambdaPlus_ << std::endl;
219 << lambdaMinus_<< std::endl;
228 if (dWNormNew_ < dWNorm_) {
230 for (j = 0; j < nm; ++j) {
231 for (k = 0; k < nx; ++k) {
234 dW_[j][k] = dWNew_[j][k];
236 dWNorm_ = dWNormNew_;
239 Log::file() <<
"Iteration failed, norm = "
240 << dWNormNew_ << std::endl;
DMatrix< double > const & chi() const
Return the chi matrix by const reference.
int nPolymer() const
Get number of polymer species.
int nMonomer() const
Get number of monomer types.
PolymerT & polymer(int id)
Get a polymer solver object by non-const reference.
virtual ~BinaryRelaxIterator()
Destructor.
int solve(bool isContinuation=false)
Iterate self-consistent field equations to solution.
void readParameters(std::istream &in)
Read all parameters and initialize.
BinaryRelaxIterator(System &system)
Constructor.
int nx() const
Get number of spatial grid points, including both endpoints.
Iterator()
Default constructor.
void compute(DArray< FieldT > const &wFields, DArray< FieldT > &cFields)
Compute concentrations.
const Domain & domain() const
Get spatial domain (including grid info) by reference.
DArray< System::CField > & cFields()
Get array of all chemical potential fields.
DArray< System::WField > & wFields()
Get array of all chemical potential fields.
const System & system() const
Get parent System by reference.
const Mixture & mixture() const
Get Mixture by reference.
Main class in SCFT simulation of one system.
Interaction & interaction()
Get interaction (i.e., excess free energy) by reference.
void computeFreeEnergy()
Compute free energy density and pressure for current fields.
Field & cField(int monomerId)
Get chemical potential field for a specific monomer type.
WField & wField(int monomerId)
Get chemical potential field for a specific monomer type.
Array container class template.
void allocate(int capacity)
Allocate the underlying C array.
static std::ostream & file()
Get log ostream by reference.
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.
void start(TimePoint begin)
Start timing from an externally supplied time.
double time() const
Return the accumulated time, in seconds.
void stop(TimePoint end)
Stop the clock at an externally supplied time.
#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.
Ensemble
Statistical ensemble type for the number of molecules of one species.
SCFT with real 1D fields.
PSCF package top-level namespace.