1#ifndef PSPC_AM_ITERATOR_TPP
2#define PSPC_AM_ITERATOR_TPP
11#include "AmIterator.h"
12#include <pspc/System.h>
13#include <pscf/inter/Interaction.h>
14#include <pscf/iterator/NanException.h>
43 interaction_.setNMonomer(system().mixture().nMonomer());
49 int np = system().unitCell().nParameter();
55 readOptional(in,
"isFlexible", isFlexible_);
60 flexibleParams_.clear();
61 for (
int i = 0; i < np; i++) {
62 flexibleParams_.append(
true);
65 readOptionalFSArray(in,
"flexibleParams", flexibleParams_, np);
66 if (nFlexibleParams() == 0) isFlexible_ =
false;
68 flexibleParams_.clear();
69 for (
int i = 0; i < np; i++) {
70 flexibleParams_.append(
false);
75 readOptional(in,
"scaleStress", scaleStress_);
85 interaction_.update(system().interaction());
103 for (
int i = 0; i < n; i++) {
105 if (std::isnan(a[i]) || std::isnan(b[i])) {
106 throw NanException(
"AmIterator::dotProduct",__FILE__,__LINE__,0);
120 for (
int i = 0; i < n; i++) {
122 if (std::isnan(value)) {
123 throw NanException(
"AmIterator::dotProduct",__FILE__,__LINE__,0);
125 if (fabs(value) > max) {
141 const int n = hists[0].capacity();
146 for (
int i = 0; i < n; i++) {
147 newbasis[i] = hists[0][i] - hists[1][i];
150 basis.append(newbasis);
161 for (
int i = 0; i < nHist; i++) {
162 for (
int j = 0; j < n; j++) {
164 trial[j] += coeffs[i] * -1 * basis[i][j];
175 for (
int i = 0; i < n; i++) {
176 fieldTrial[i] += lambda * resTrial[i];
184 bool AmIterator<D>::hasInitialGuess()
185 {
return system().w().hasData(); }
189 int AmIterator<D>::nElements()
191 const int nMonomer = system().mixture().nMonomer();
192 const int nBasis = system().basis().nBasis();
193 int nEle = nMonomer*nBasis;
196 nEle += nFlexibleParams();
208 const int nMonomer = system().mixture().nMonomer();
209 const int nBasis = system().basis().nBasis();
212 for (
int i = 0; i < nMonomer; i++) {
213 for (
int k = 0; k < nBasis; k++) {
214 curr[i*nBasis+k] = (*currSys)[i][k];
218 const int nParam = system().unitCell().nParameter();
222 for (
int i = 0; i < nParam; i++) {
223 if (flexibleParams_[i]) {
224 curr[nMonomer*nBasis + counter] = scaleStress_*currParam[i];
235 void AmIterator<D>::evaluate()
242 system().mixture().computeStress();
250 const int n = nElements();
251 const int nMonomer = system().mixture().nMonomer();
252 const int nBasis = system().basis().nBasis();
255 for (
int i = 0 ; i < n; ++i) {
260 for (
int i = 0; i < nMonomer; ++i) {
261 for (
int j = 0; j < nMonomer; ++j) {
262 double chi = interaction_.chi(i,j);
263 double p = interaction_.p(i,j);
266 for (
int k = 0; k < nBasis; ++k) {
267 int idx = i*nBasis + k;
268 resid[idx] += chi*c[k] - p*w[k];
274 if (system().hasMask()) {
275 for (
int i = 0; i < nMonomer; ++i) {
276 for (
int k = 0; k < nBasis; ++k) {
277 int idx = i*nBasis + k;
278 resid[idx] -= system().mask().basis()[k] /
279 interaction_.sumChiInverse();
286 if (system().hasExternalFields()) {
287 for (
int i = 0; i < nMonomer; ++i) {
288 for (
int j = 0; j < nMonomer; ++j) {
289 for (
int k = 0; k < nBasis; ++k) {
290 int idx = i*nBasis + k;
291 resid[idx] += interaction_.p(i,j) *
292 system().h().basis(j)[k];
299 if (!system().mixture().isCanonical()) {
300 if (!system().hasMask()) {
301 for (
int i = 0; i < nMonomer; ++i) {
302 resid[i*nBasis] -= 1.0 / interaction_.sumChiInverse();
307 for (
int i = 0; i < nMonomer; ++i) {
308 resid[i*nBasis] = 0.0;
314 const int nParam = system().unitCell().nParameter();
326 for (
int i = 0; i < nParam ; i++) {
327 if (flexibleParams_[i]) {
328 resid[nMonomer*nBasis + counter] = scaleStress_ * -1
329 * system().mixture().stress(i);
343 const int nMonomer = system().mixture().nMonomer();
344 const int nBasis = system().basis().nBasis();
350 for (
int i = 0; i < nMonomer; i++) {
352 for (
int k = 0; k < nBasis; k++)
354 wField[i][k] = newGuess[i*nBasis + k];
358 if (system().mixture().isCanonical()) {
360 for (
int i = 0; i < nMonomer; ++i) {
362 for (
int j = 0; j < nMonomer; ++j) {
363 chi = interaction_.chi(i,j);
364 wField[i][0] += chi * system().c().basis(j)[0];
368 if (system().hasExternalFields()) {
369 for (
int i = 0; i < nMonomer; ++i) {
370 wField[i][0] += system().h().basis(i)[0];
374 system().setWBasis(wField);
377 const int nParam = system().unitCell().nParameter();
381 for (
int i = 0; i < nParam; i++) {
382 if (flexibleParams_[i]) {
383 parameters[i] = 1.0/scaleStress_ *
384 newGuess[nMonomer*nBasis + counter];
390 system().setUnitCell(parameters);
396 void AmIterator<D>::outputToLog()
398 if (isFlexible() && verbose() > 1) {
399 const int nParam = system().unitCell().nParameter();
400 for (
int i = 0; i < nParam; i++) {
401 if (flexibleParams_[i]) {
403 <<
" Cell Param " << i <<
" = "
404 <<
Dbl(system().unitCell().parameters()[i], 15)
406 <<
Dbl(system().mixture().stress(i), 15)
Template for Anderson mixing iterator algorithm.
Exception thrown when not-a-number (NaN) is encountered.
Pspc implementation of the Anderson Mixing iterator.
void setClassName(const char *className)
Set class name string.
void setup(bool isContinuation)
Setup iterator just before entering iteration loop.
AmIterator(System< D > &system)
Constructor.
void readParameters(std::istream &in)
Read all parameters and initialize.
Base class for iterative solvers for SCF equations.
Main class for SCFT simulation of one system.
Base template for UnitCell<D> classes, D=1, 2 or 3.
int capacity() const
Return allocated size.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
Wrapper for a double precision number, for formatted ostream output.
A fixed capacity (static) contiguous array with a variable logical size.
static std::ostream & file()
Get log ostream by reference.
Class for storing history of previous values in an array.
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
float product(float a, float b)
Product for float Data.