1#ifndef PSPG_AM_ITERATOR_BASIS_TPP
2#define PSPG_AM_ITERATOR_BASIS_TPP
11#include "AmIteratorBasis.h"
12#include <pspg/System.h>
13#include <pscf/inter/Interaction.h>
14#include <pscf/iterator/NanException.h>
15#include <pspg/field/RDField.h>
27 { setClassName(
"AmIteratorBasis"); }
43 interaction_.setNMonomer(system().mixture().nMonomer());
50 readOptional(in,
"isFlexible", isFlexible_);
51 readOptional(in,
"scaleStress", scaleStress_);
64 interaction_.update(system().interaction());
82 for (
int i=0; i < n; ++i) {
84 if (std::isnan(a[i]) || std::isnan(b[i])) {
85 throw NanException(
"AmIteratorBasis::dotProduct", __FILE__,
100 for (
int i = 0; i < n; i++) {
102 if (std::isnan(value)) {
103 throw NanException(
"AmIteratorBasis::dotProduct", __FILE__,
106 if (fabs(value) > max)
119 for (
int i=0; i < n; ++i) {
132 const int length = resBasis[0].capacity();
134 double dotprod = 0.0;
135 for(
int i = 0; i < length; i++) {
136 dotprod += resBasis[m][i] * resBasis[n][i];
145 AmIteratorBasis<D>::computeVDotProd(
DArray<double> const & resCurrent,
149 const int length = resBasis[0].capacity();
151 double dotprod = 0.0;
152 for(
int i = 0; i < length; i++) {
153 dotprod += resCurrent[i] * resBasis[m][i];
167 for (
int m = maxHist-1; m > 0; --m) {
168 for (
int n = maxHist-1; n > 0; --n) {
174 for (
int m = 0; m < nHist; ++m) {
175 double dotprod = computeUDotProd(resBasis,0,m);
189 for (
int m = 0; m < nHist; ++m) {
190 v[m] = computeVDotProd(resCurrent,resBasis,m);
204 const int n = hists[0].capacity();
208 for (
int i = 0; i < n; i++) {
210 newbasis[i] = hists[0][i] - hists[1][i];
213 basis.append(newbasis);
224 for (
int i = 0; i < nHist; i++) {
225 for (
int j = 0; j < n; j++) {
227 trial[j] += coeffs[i] * -1 * basis[i][j];
233 void AmIteratorBasis<D>::addPredictedError(
DArray<double>& fieldTrial,
238 for (
int i = 0; i < n; i++) {
239 fieldTrial[i] += lambda * resTrial[i];
245 bool AmIteratorBasis<D>::hasInitialGuess()
247 return system().w().hasData();
252 int AmIteratorBasis<D>::nElements()
254 const int nMonomer = system().mixture().nMonomer();
255 const int nBasis = system().basis().nBasis();
257 int nEle = nMonomer*nBasis;
260 nEle += system().unitCell().nParameter();
272 const int nMonomer = system().mixture().nMonomer();
273 const int nBasis = system().basis().nBasis();
276 for (
int i = 0; i < nMonomer; i++) {
277 for (
int k = 0; k < nBasis; k++) {
278 curr[i*nBasis+k] = (*currSys)[i][k];
283 const int begin = nMonomer*nBasis;
284 const int nParam = system().unitCell().nParameter();
286 = system().unitCell().parameters();
287 for (
int i = 0; i < nParam; i++) {
288 curr[begin + i] = scaleStress_ * parameters[i];
296 void AmIteratorBasis<D>::evaluate()
303 system().mixture().computeStress(system().domain().waveList());
312 const int nMonomer = system().mixture().nMonomer();
313 const int nBasis = system().basis().nBasis();
314 const int n = nElements();
317 for (
int i = 0 ; i < n; ++i) {
322 for (
int i = 0; i < nMonomer; ++i) {
323 for (
int j = 0; j < nMonomer; ++j) {
324 for (
int k = 0; k < nBasis; ++k) {
325 int idx = i*nBasis + k;
327 interaction_.chi(i,j)*system().c().basis(j)[k] -
328 interaction_.p(i,j)*system().w().basis(j)[k];
334 if (!system().mixture().isCanonical()) {
335 for (
int i = 0; i < nMonomer; ++i) {
336 resid[i*nBasis] -= 1.0/interaction_.sumChiInverse();
340 for (
int i = 0; i < nMonomer; ++i) {
341 resid[i*nBasis] = 0.0;
347 const int nParam = system().unitCell().nParameter();
348 for (
int i = 0; i < nParam ; i++) {
349 resid[nMonomer*nBasis + i] = -1.0 * scaleStress_
350 * system().mixture().stress(i);
371 const int nMonomer = system().mixture().nMonomer();
372 const int nBasis = system().basis().nBasis();
378 for (
int i = 0; i < nMonomer; i++) {
380 for (
int k = 0; k < nBasis; k++) {
381 wField[i][k] = newGuess[i*nBasis + k];
386 if (system().mixture().isCanonical()) {
387 for (
int i = 0; i < nMonomer; ++i) {
389 for (
int j = 0; j < nMonomer; ++j) {
391 interaction_.chi(i,j) * system().c().basis(j)[0];
395 system().setWBasis(wField);
398 const int nParam = system().unitCell().nParameter();
399 const int begin = nMonomer*nBasis;
402 for (
int i = 0; i < nParam; i++) {
403 value = newGuess[begin + i]/scaleStress_;
406 system().setUnitCell(parameters);
412 void AmIteratorBasis<D>::outputToLog()
415 const int nParam = system().unitCell().nParameter();
416 for (
int i = 0; i < nParam; i++) {
417 Log::file() <<
"Parameter " << i <<
" = "
418 <<
Dbl(system().unitCell().parameters()[i])
Template for Anderson mixing iterator algorithm.
virtual double norm(DArray< double > const &hist)
Find the L2 norm of a vector.
Exception thrown when not-a-number (NaN) is encountered.
Pspg implementation of the Anderson Mixing iterator.
void setup(bool isContinuation)
Setup iterator just before entering iteration loop.
void readParameters(std::istream &in)
Read all parameters and initialize.
~AmIteratorBasis()
Destructor.
AmIteratorBasis(System< D > &system)
Constructor.
Base class for iterative solvers for SCF equations.
Main class in SCFT simulation of one system.
int capacity() const
Return allocated size.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
Dynamically allocated Matrix.
Wrapper for a double precision number, for formatted ostream output.
A fixed capacity (static) contiguous array with a variable logical size.
void append(Data const &data)
Append data to the end of the array.
static std::ostream & file()
Get log ostream by reference.
int capacity1() const
Get number of rows (range of the first array index).
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.