1#ifndef PSCF_AM_ITERATOR_TMPL_TPP
2#define PSCF_AM_ITERATOR_TMPL_TPP
11#include "NanException.h"
12#include <pscf/inter/Interaction.h>
13#include <pscf/math/LuSolver.h>
14#include <util/format/Dbl.h>
15#include <util/format/Int.h>
16#include <util/misc/Timer.h>
17#include <util/misc/FileMaster.h>
31 template <
typename Iterator,
typename T>
52 template <
typename Iterator,
typename T>
59 template <
typename Iterator,
typename T>
97 template <
typename Iterator,
typename T>
101 setup(isContinuation);
116 nBasis_ = stateBasis_.size();
117 for (itr_ = 0; itr_ <
maxItr_; ++itr_) {
121 stateHistory_.append(temp_);
126 Log::file() <<
"------------------------------- \n";
138 residualHistory_.append(temp_);
146 Log::file() <<
", error = NaN" << std::endl;
149 if (verbose_ > 0 && verbose_ < 3) {
164 projectionRatio_ += projectionError_/preError_;
165 correctionRatio_ += correctionError_/preError_;
168 preError_ = correctionError_;
210 addCorrection(stateTrial_, residualTrial_);
229 Log::file() <<
"Iterator failed to converge.\n";
234 template <
typename Iterator,
typename T>
238 double total = timerTotal_.time();
241 out <<
"Total" << std::setw(22)<<
"Per Iteration"
242 << std::setw(9) <<
"Fraction" <<
"\n";
243 out <<
"MDE solution: "
244 <<
Dbl(timerMDE_.time(), 9, 3) <<
" s, "
245 <<
Dbl(timerMDE_.time()/totalItr_, 9, 3) <<
" s, "
246 <<
Dbl(timerMDE_.time()/total, 9, 3) <<
"\n";
247 out <<
"residual computation: "
248 <<
Dbl(timerResid_.time(), 9, 3) <<
" s, "
249 <<
Dbl(timerResid_.time()/totalItr_, 9, 3) <<
" s, "
250 <<
Dbl(timerResid_.time()/total, 9, 3) <<
"\n";
251 out <<
"mixing coefficients: "
252 <<
Dbl(timerCoeff_.time(), 9, 3) <<
" s, "
253 <<
Dbl(timerCoeff_.time()/totalItr_, 9, 3) <<
" s, "
254 <<
Dbl(timerCoeff_.time()/total, 9, 3) <<
"\n";
255 out <<
"checking convergence: "
256 <<
Dbl(timerError_.time(), 9, 3) <<
" s, "
257 <<
Dbl(timerError_.time()/totalItr_, 9, 3) <<
" s, "
258 <<
Dbl(timerError_.time()/total, 9, 3) <<
"\n";
259 out <<
"updating guess: "
260 <<
Dbl(timerOmega_.time(), 9, 3) <<
" s, "
261 <<
Dbl(timerOmega_.time()/totalItr_, 9, 3) <<
" s, "
262 <<
Dbl(timerOmega_.time()/total, 9, 3)<<
"\n";
263 out <<
"total time: "
264 <<
Dbl(total, 9, 3) <<
" s, "
265 <<
Dbl(total/totalItr_, 9, 3) <<
" s \n";
270 out <<
"Average Projection Step Reduction Ratio: "
271 <<
Dbl(projectionRatio_/testCounter, 3, 3)<<
"\n";
272 out <<
"Average Correction Step Reduction Ratio: "
273 <<
Dbl(correctionRatio_/testCounter, 3, 3)<<
"\n";
278 template <
typename Iterator,
typename T>
296 template <
typename Iterator,
typename T>
309 std::string msg =
"Invalid iterator error type [";
311 msg +=
"] in parameter file";
319 template <
typename Iterator,
typename T>
341 template <
typename Iterator,
typename T>
347 useLambdaRamp_ = useLambdaRamp;
352 if (useLambdaRamp_) {
361 template <
typename Iterator,
typename T>
365 if (isAllocatedAM_)
return;
368 nElem_ = nElements();
372 residualHistory_.allocate(
maxHist_+1);
377 stateTrial_.allocate(nElem_);
378 residualTrial_.allocate(nElem_);
379 temp_.allocate(nElem_);
386 isAllocatedAM_ =
true;
393 template <
typename Iterator,
typename T>
400 residualHistory_.clear();
401 stateHistory_.clear();
402 if (!isContinuation) {
404 residualBasis_.clear();
413 template <
typename Iterator,
typename T>
417 residualHistory_.clear();
418 stateHistory_.clear();
419 residualBasis_.clear();
428 template <
typename Iterator,
typename T>
429 void AmIteratorTmpl<Iterator,T>::computeTrialCoeff()
433 if (itr_ == 0 && nBasis_ == 0) {
435 for (m = 0; m < maxHist_; ++m) {
438 for (n = 0; n < maxHist_; ++n) {
446 if (itr_ == 0)
return;
449 if (stateHistory_.size() > 1) {
452 updateBasis(stateBasis_, stateHistory_);
455 updateBasis(residualBasis_, residualHistory_);
458 updateU(U_, residualBasis_);
463 nBasis_ = residualBasis_.size();
468 computeV(v_, residualHistory_[0], residualBasis_);
477 coeffs_[0] = v_[0] / U_(0,0);
479 if (nBasis_ < maxHist_) {
488 for (
int i = 0; i < nBasis_; ++i) {
490 for (
int j = 0; j < nBasis_; ++j) {
491 tempU(i,j) = U_(i,j);
498 solver.computeLU(tempU);
499 solver.solve(tempv, tempcoeffs);
502 for (
int i = 0; i < nBasis_; ++i) {
503 coeffs_[i] = tempcoeffs[i];
507 if (nBasis_ == maxHist_) {
511 solver.computeLU(U_);
512 solver.solve(v_, coeffs_);
517 for (
int i = 0; i < nBasis_; ++i) {
524 template <
typename Iterator,
typename T>
525 void AmIteratorTmpl<Iterator,T>::updateTrial()
529 setEqual(stateTrial_, stateHistory_[0]);
530 setEqual(residualTrial_, residualHistory_[0]);
536 addEqVectors(stateTrial_, stateBasis_, coeffs_);
537 addEqVectors(residualTrial_, residualBasis_, coeffs_);
559 projectionError_ = computeError(temp_, stateTrial_, errorType_, 0);
572 template <
typename Iterator,
typename T>
575 if (useLambdaRamp_ && (nBasis_ <
maxHist_)) {
576 double factor = 1.0 - pow(r_, nBasis_ + 1);
577 return factor*lambda_;
586 template <
typename Iterator,
typename T>
592 int nBasis = residualBasis.
size();
597 for (
int m = maxHist - 1; m > 0; --m) {
598 for (
int n = maxHist-1; n > 0; --n) {
604 for (
int m = 0; m < nBasis; ++m) {
605 double dotprod = dotProduct(residualBasis[0],residualBasis[m]);
619 template <
typename Iterator,
typename T>
620 void AmIteratorTmpl<Iterator, T>::computeV(
622 T
const & resCurrent,
625 int nBasis = residualBasis.
size();
627 for (
int m = 0; m < nBasis; ++m) {
628 v[m] = dotProduct(resCurrent, residualBasis[m]);
635 template <
typename Iterator,
typename T>
645 double maxRes = maxAbs(residTrial);
648 double normRes = norm(residTrial);
654 double rmsRes = normRes/sqrt(nElements());
657 double normField = norm(stateTrial);
658 double relNormRes = normRes/normField;
667 }
else if (
errorType ==
"relNormResid") {
670 UTIL_THROW(
"Invalid iterator error type in parameter file.");
675 Log::file() <<
"Max Residual = " <<
Dbl(maxRes,15) <<
"\n";
676 Log::file() <<
"Residual Norm = " <<
Dbl(normRes,15) <<
"\n";
677 Log::file() <<
"RMS Residual = " <<
Dbl(rmsRes,15) <<
"\n";
688 template <
typename Iterator,
typename T>
691 return computeError(residualHistory_[0], stateHistory_[0],
699 template <
typename Iterator,
typename T>
701 AmIteratorTmpl<Iterator,T>::updateBasis(
RingBuffer<T> & basis,
709 if (basis[0].isAllocated()) {
710 UTIL_CHECK(basis[0].capacity() == history[0].capacity());
712 basis[0].
allocate(history[0].capacity());
716 subVV(basis[0], history[0], history[1]);
722 template <
typename Iterator,
typename T>
724 AmIteratorTmpl<Iterator,T>::addEqVectors(T& v,
728 int nBasis = basis.
size();
730 for (
int i = 0; i < nBasis; i++) {
731 addEqVc(v, basis[i], coeffs[i]);
738 template <
typename Iterator,
typename T>
740 AmIteratorTmpl<Iterator,T>::addCorrection(T& stateTrial,
741 T
const & residualTrial)
743 double lambda = computeLambda();
744 addEqVc(stateTrial, residualTrial, lambda);
752 template <
typename Iterator,
typename T>
753 double AmIteratorTmpl<Iterator,T>::norm(T
const & a)
755 double normSq = dotProduct(a, a);
Template for Anderson mixing iterator algorithm.
virtual void setup(bool isContinuation)
Initialize just before entry to iterative loop.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void readMixingParameters(std::istream &in, bool useLambdaRamp=true)
Read optional parameters used in default correction algorithm.
void allocateAM()
Allocate memory required by AM algorithm, if necessary.
bool isAllocatedAM() const
Have data structures required by the AM algorithm been allocated?
virtual void clear()
Clear information about history.
void outputTimers(std::ostream &out) const
Log output timing results.
std::string errorType() const
Get error type string.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
void clearTimers()
Clear timers.
int verbose() const
Verbosity level, allowed values 0, 1, or 2.
~AmIteratorTmpl()
Destructor.
void readErrorType(std::istream &in)
Read and validate the optional errorType string parameter.
int verbose_
Verbosity level.
double epsilon_
Error tolerance.
AmIteratorTmpl()
Constructor.
virtual double computeLambda()
Compute mixing parameter for correction step of Anderson mixing.
virtual bool isValidErrorType()
Checks if a string is a valid error type.
int maxItr_
Maximum number of iterations to attempt.
virtual double computeError(DeviceArray< cudaReal > &residTrial, DeviceArray< cudaReal > &stateTrial, std::string errorType, int verbose)
std::string errorType_
Type of error criterion used to test convergence.
virtual void readParameters(std::istream &in)
Read all parameters and initialize.
int maxHist_
Maximum number of basis vectors in AM algorithm.
int solve(bool isContinuation=false)
Iterate to a solution.
Solve Ax=b by LU decomposition of A.
void allocate(int n)
Allocate memory.
Exception thrown when not-a-number (NaN) is encountered.
int capacity() const
Return allocated size.
Dynamically allocatable contiguous array template.
void allocate(int capacity)
Allocate the underlying C array.
Dynamically allocated Matrix.
void allocate(int capacity1, int capacity2)
Allocate memory for a matrix.
Wrapper for a double precision number, for formatted ostream output.
Wrapper for an int, for formatted ostream output.
static std::ostream & file()
Get log ostream by reference.
int capacity1() const
Get number of rows (range of the first array index).
void setClassName(const char *className)
Set class name string.
Class for storing history of previous values in an array.
void allocate(int capacity)
Allocate a new empty buffer.
void advance()
Advances the pointer to an added element without assigning a value.
int size() const
Return number of values currently in the buffer.
#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.
void subVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector subtraction, a[i] = b[i] - c[i].
void addEqVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c)
Vector addition in-place w/ coefficient, a[i] += b[i] * c, kernel wrapper.
PSCF package top-level namespace.