1#ifndef RPG_LR_COMPRESSOR_TPP
2#define RPG_LR_COMPRESSOR_TPP
11#include "LrCompressor.h"
12#include <rpg/system/System.h>
13#include <prdc/crystal/shiftToMinimum.h>
14#include <prdc/cuda/resources.h>
15#include <pscf/mesh/MeshIterator.h>
16#include <pscf/iterator/NanException.h>
17#include <util/format/Dbl.h>
35 errorType_(
"rmsResid"),
38 isIntraCalculated_(false),
57 read(in,
"epsilon", epsilon_);
69 const int nMonomer =
system().mixture().nMonomer();
75 for (
int i = 0; i < D; ++i) {
77 kMeshDimensions_[i] = dimensions[i];
79 kMeshDimensions_[i] = dimensions[i]/2 + 1;
85 for (
int i = 0; i < D; ++i) {
86 kSize_ *= kMeshDimensions_[i];
92 resid_.allocate(dimensions);
93 residK_.allocate(dimensions);
94 wFieldTmp_.allocate(nMonomer);
95 intraCorrelationK_.allocate(kMeshDimensions_);
96 for (
int i = 0; i < nMonomer; ++i) {
97 wFieldTmp_[i].allocate(dimensions);
103 if (!isIntraCalculated_){
104 intra_.computeIntraCorrelations(intraCorrelationK_);
105 isIntraCalculated_ =
true;
130 for (itr_ = 0; itr_ < maxItr_; ++itr_) {
133 Log::file() <<
"------------------------------- \n";
144 error = computeError(verbose_);
146 Log::file() <<
", error = NaN" << std::endl;
150 Log::file() <<
", error = " <<
Dbl(error, 15) << std::endl;
154 if (error < epsilon_) {
160 Log::file() <<
"-------------------------------\n";
190 Log::file() <<
"Iterator failed to converge.\n";
199 void LrCompressor<D>::getResidual()
201 const int nMonomer = system().mixture().nMonomer();
207 for (
int i = 1; i < nMonomer; i++) {
216 void LrCompressor<D>::updateWFields(){
217 const int nMonomer = system().mixture().nMonomer();
218 const double vMonomer = system().mixture().vMonomer();
221 system().domain().fft().forwardTransform(resid_, residK_);
227 system().domain().fft().inverseTransformUnsafe(residK_, resid_);
230 for (
int i = 0; i < nMonomer; i++) {
231 VecOp::addVV(wFieldTmp_[i], system().w().rgrid(i), resid_);
235 system().w().setRGrid(wFieldTmp_);
242 void LrCompressor<D>::outputToLog()
252 double total = timerTotal_.time();
254 out <<
"LrCompressor time contributions:\n";
256 out <<
"Total" << std::setw(22)<<
"Per Iteration"
257 << std::setw(9) <<
"Fraction" <<
"\n";
258 out <<
"MDE solution: "
259 <<
Dbl(timerMDE_.time(), 9, 3) <<
" s, "
260 <<
Dbl(timerMDE_.time()/totalItr_, 9, 3) <<
" s, "
261 <<
Dbl(timerMDE_.time()/total, 9, 3) <<
"\n";
278 double LrCompressor<D>::maxAbs(
RField<D> const & a)
280 return Reduce::maxAbs(a);
287 double LrCompressor<D>::dotProduct(RField<D>
const & a,
291 return Reduce::innerProduct(a, b);
298 double LrCompressor<D>::norm(RField<D>
const & a)
300 double normSq = dotProduct(a, a);
308 double LrCompressor<D>::computeError(
int verbose)
310 const int meshSize = system().domain().mesh().size();
314 double maxRes = maxAbs(resid_);
316 double normRes = norm(resid_);
318 double rmsRes = normRes/sqrt(meshSize);
319 if (errorType_ ==
"maxResid") {
321 }
else if (errorType_ ==
"normResid") {
323 }
else if (errorType_ ==
"rmsResid") {
326 UTIL_THROW(
"Invalid iterator error type in parameter file.");
331 Log::file() <<
"Max Residual = " <<
Dbl(maxRes,15) <<
"\n";
332 Log::file() <<
"Residual Norm = " <<
Dbl(normRes,15) <<
"\n";
333 Log::file() <<
"RMS Residual = " <<
Dbl(rmsRes,15) <<
"\n";
An IntVec<D, T> is a D-component vector of elements of integer type T.
Exception thrown when not-a-number (NaN) is encountered.
static void computeKMesh(IntVec< D > const &rMeshDimensions, IntVec< D > &kMeshDimensions, int &kSize)
Compute dimensions and size of k-space mesh for DFT of real data.
Field of real double precision values on an FFT mesh.
int mdeCounter_
Count how many times MDE has been solved.
Compressor(System< D > &system)
Constructor.
System< D > const & system() const
Return const reference to parent system.
void setup()
Initialize just before entry to iterative loop.
void readParameters(std::istream &in)
Read all parameters and initialize.
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 clearTimers()
Clear timers.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
Add and read a new optional ScalarParam < Type > object.
~LrCompressor()
Destructor.
int compress()
Iterate pressure field to obtain partial saddle point.
LrCompressor(System< D > &system)
Constructor.
void outputTimers(std::ostream &out) const
Return compressor times contributions.
Main class, representing one complete system.
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.
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.
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 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 subVS(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, const cudaReal c, const int beginIdA, const int beginIdB, const int n)
Vector subtraction, a[i] = b[i] - c, 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.
SCFT and PS-FTS with real periodic fields (GPU)
PSCF package top-level namespace.