1#ifndef RPG_LR_AM_COMPRESSOR_TPP
2#define RPG_LR_AM_COMPRESSOR_TPP
11#include "LrAmPreCompressor.h"
12#include <rpg/System.h>
13#include <rpg/fts/compressor/intra/IntraCorrelation.h>
14#include <prdc/crystal/shiftToMinimum.h>
15#include <prdc/cuda/resources.h>
16#include <pscf/chem/Monomer.h>
17#include <pscf/mesh/MeshIterator.h>
31 isIntraCalculated_(false),
33 { setClassName(
"LrAmPreCompressor"); }
53 const int nMonomer = system().mixture().nMonomer();
54 const int meshSize = system().domain().mesh().size();
55 IntVec<D> const & dimensions = system().mesh().dimensions();
62 for (
int i = 0; i < D; ++i) {
64 kMeshDimensions_[i] = dimensions[i];
66 kMeshDimensions_[i] = dimensions[i]/2 + 1;
72 for (
int i = 0; i < D; ++i) {
73 kSize_ *= kMeshDimensions_[i];
78 w0_.allocate(nMonomer);
79 wFieldTmp_.allocate(nMonomer);
80 error_.allocate(dimensions);
81 resid_.allocate(dimensions);
82 residK_.allocate(dimensions);
83 intraCorrelation_.allocate(kMeshDimensions_);
84 for (
int i = 0; i < nMonomer; ++i) {
85 w0_[i].allocate(dimensions);
86 wFieldTmp_[i].allocate(dimensions);
92 if (!isIntraCalculated_){
93 intra_.computeIntraCorrelations(intraCorrelation_);
94 isIntraCalculated_ =
true;
98 for (
int i = 0; i < nMonomer; ++i) {
134 double LrAmPreCompressor<D>::maxAbs(DeviceArray<cudaReal>
const & a)
142 LrAmPreCompressor<D>::updateBasis(
RingBuffer< DeviceArray<cudaReal> > & basis,
143 RingBuffer< DeviceArray<cudaReal> >
const & hists)
149 if (basis[0].isAllocated()) {
150 UTIL_CHECK(basis[0].capacity() == hists[0].capacity());
152 basis[0].allocate(hists[0].capacity());
160 LrAmPreCompressor<D>::addHistories(DeviceArray<cudaReal>& trial,
161 RingBuffer<DeviceArray<cudaReal> >
const & basis,
165 for (
int i = 0; i < nHist; i++) {
172 LrAmPreCompressor<D>::addPredictedError(DeviceArray<cudaReal>& fieldTrial,
173 DeviceArray<cudaReal>
const & resTrial,
181 bool LrAmPreCompressor<D>::hasInitialGuess()
182 {
return system().w().hasData(); }
186 int LrAmPreCompressor<D>::nElements()
187 {
return system().domain().mesh().size(); }
191 void LrAmPreCompressor<D>::getCurrent(DeviceArray<cudaReal>& curr)
204 void LrAmPreCompressor<D>::evaluate()
212 void LrAmPreCompressor<D>::getResidual(DeviceArray<cudaReal>& resid)
214 const int nMonomer = system().mixture().nMonomer();
215 const double vMonomer = system().mixture().vMonomer();
219 for (
int i = 1; i < nMonomer; i++) {
224 system().fft().forwardTransform(resid_, residK_);
230 system().fft().inverseTransformUnsafe(residK_, resid_);
239 void LrAmPreCompressor<D>::update(DeviceArray<cudaReal>& newGuess)
242 const int nMonomer = system().mixture().nMonomer();
245 for (
int i = 0; i < nMonomer; i++) {
250 system().setWRGrid(wFieldTmp_);
254 void LrAmPreCompressor<D>::outputToLog()
262 out <<
"Compressor times contributions:\n";
283 std::string errorType,
287 const int n = nElements();
288 const int nMonomer = system().mixture().nMonomer();
292 for (
int i = 1; i < nMonomer; i++) {
297 double maxRes = maxAbs(error_);
304 double rmsRes = normRes/sqrt(n);
307 Log::file() <<
"Max Residual = " <<
Dbl(maxRes,15) <<
"\n";
308 Log::file() <<
"Residual Norm = " <<
Dbl(normRes,15) <<
"\n";
316 if (errorType ==
"maxResid") {
318 }
else if (errorType ==
"normResid") {
320 }
else if (errorType ==
"rmsResid") {
323 UTIL_THROW(
"Invalid iterator error type in parameter file.");
328 if (errorType ==
"maxResid") {
330 }
else if (errorType ==
"normResid") {
332 }
else if (errorType ==
"rmsResid") {
333 error = normRes/sqrt(n);
335 UTIL_THROW(
"Invalid iterator error type in parameter file.");
Template for Anderson mixing iterator algorithm.
Dynamic array on the GPU device with aligned data.
int capacity() const
Return allocated capacity.
An IntVec<D, T> is a D-component vector of elements of integer type T.
Base class for iterators that impose incompressibility.
Anderson Mixing compressor with linear-response preconditioning.
LrAmPreCompressor(System< D > &system)
Constructor.
double computeError(DeviceArray< cudaReal > &residTrial, DeviceArray< cudaReal > &fieldTrial, std::string errorType, int verbose)
Compute and return error used to test for convergence.
void readParameters(std::istream &in)
Read all parameters and initialize.
void setup(bool isContinuation)
Initialize just before entry to iterative loop.
void clearTimers()
Reset / clear all timers.
int compress()
Compress to obtain partial saddle point w+.
void outputTimers(std::ostream &out)
Write a report of time contributions used by this algorithm.
~LrAmPreCompressor()
Destructor.
Main class for calculations that represent one system.
Dynamically allocatable contiguous array template.
Wrapper for a double precision number, for formatted ostream output.
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.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
cudaReal innerProduct(DeviceArray< cudaReal > const &a, DeviceArray< cudaReal > const &b)
Compute inner product of two real arrays (GPU kernel wrapper).
cudaReal maxAbs(DeviceArray< cudaReal > const &in)
Get maximum absolute magnitude of array elements (GPU kernel wrapper).
void addEqV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, const int beginIdA, const int beginIdB, const int n)
Vector addition in-place, a[i] += b[i], kernel wrapper (cudaReal).
void eqV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, const int beginIdA, const int beginIdB, const int n)
Vector assignment, a[i] = b[i], kernel wrapper (cudaReal).
void subVS(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c, const int beginIdA, const int beginIdB, const int n)
Vector subtraction, a[i] = b[i] - c, kernel wrapper (cudaReal).
void addVV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, DeviceArray< cudaReal > const &c, const int beginIdA, const int beginIdB, const int beginIdC, const int n)
Vector addition, a[i] = b[i] + c[i], kernel wrapper (cudaReal).
void subVV(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, DeviceArray< cudaReal > const &c, const int beginIdA, const int beginIdB, const int beginIdC, const int n)
Vector subtraction, a[i] = b[i] - c[i], kernel wrapper (cudaReal).
void divEqVc(DeviceArray< cudaComplex > &a, DeviceArray< cudaReal > const &b, cudaReal const c)
Vector division in-place w/ coeff., a[i] /= (b[i] * c), kernel wrapper.
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.
Utility classes for scientific computation.