PSCF v1.4.0
AmCompressor.tpp
1#ifndef RP_AM_COMPRESSOR_TPP
2#define RP_AM_COMPRESSOR_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "AmCompressor.h"
12#include <pscf/math/IntVec.h>
13#include <util/global.h>
14
15#include <pscf/iterator/AmIteratorTmpl.tpp>
16
17namespace Pscf {
18namespace Rp {
19
20 using namespace Util;
21
22 // Public member functions
23
24 /*
25 * Constructor.
26 */
27 template <int D, class T, class V>
28 AmCompressor<D,T,V>::AmCompressor(typename T::System& system)
29 : isAllocated_(false)
30 {
31 CompressorT::setSystem(system);
32 ParamComposite::setClassName("AmCompressor");
33 }
34
35 /*
36 * Read parameters from file.
37 */
38 template <int D, class T, class V>
40 {
41 // Default values
42 AmTmpl::maxItr_ = 100;
44 AmTmpl::errorType_ = "rms";
45 bool useLambdaRamp = false;
46
49 AmTmpl::readMixingParameters(in, useLambdaRamp);
50 }
51
52 /*
53 * Initialize just before entry to iterative loop.
54 */
55 template <int D, class T, class V>
56 void AmCompressor<D,T,V>::setup(bool isContinuation)
57 {
58 Log::file() << "\n Entering setup";
59 // Allocate memory required by AM algorithm if not done earlier.
60 AmTmpl::setup(isContinuation);
61
62 const int nMonomer = system().mixture().nMonomer();
63 const IntVec<D> dimensions = system().domain().mesh().dimensions();
64
65 // Allocate memory required by compressor if not done earlier.
66 if (!isAllocated_) {
67 w0_.allocate(nMonomer);
68 wFieldTmp_.allocate(nMonomer);
69 for (int i = 0; i < nMonomer; ++i) {
70 w0_[i].allocate(dimensions);
71 wFieldTmp_[i].allocate(dimensions);
72 }
73 isAllocated_ = true;
74 }
75
76 // Store value of initial guess chemical potential fields
77 for (int i = 0; i < nMonomer; ++i) {
78 VecOp::eqV(w0_[i], system().w().rgrid(i));
79 }
80 Log::file() << "\n Exiting setup";
81 }
83 /*
84 * Main function - identify partial saddle-point state.
85 */
86 template <int D, class T, class V>
88 {
89 Log::file() << "\n Entering compress";
90 int solve = AmTmpl::solve();
91 Log::file() << "\n Exiting compress";
92 return solve;
93 }
94
95 /*
96 * Output timer information, if requested.
97 */
98 template <int D, class T, class V>
99 void AmCompressor<D,T,V>::outputTimers(std::ostream& out) const
100 {
101 out << "\n";
102 out << "Compressor time contributions:\n";
104 }
105
106 /*
107 * Clear timers and MDE counter.
108 */
109 template <int D, class T, class V>
111 {
113 CompressorT::mdeCounter_ = 0;
114 }
115
116 // Private virtual functions that interact with the parent System
117
118 /*
119 * Compute and return the number of elements in a field vector.
120 */
121 template <int D, class T, class V>
122 int AmCompressor<D,T,V>::nElements()
123 { return system().domain().mesh().size(); }
124
125 /*
126 * Does the system have an initial field guess?
127 */
128 template <int D, class T, class V>
129 bool AmCompressor<D,T,V>::hasInitialGuess()
130 { return system().w().hasData(); }
131
132 /*
133 * Get the current field from the system.
134 */
135 template <int D, class T, class V>
136 void AmCompressor<D,T,V>::getCurrent(VectorT& curr)
137 {
138 /*
139 * The field that we are adjusting is the Langrange multiplier
140 * field. The current value is the difference between w and w0_
141 * for the first monomer type, but any monomer type would give
142 * the same answer.
143 */
144 VecOp::subVV(curr, system().w().rgrid(0), w0_[0]);
145 }
146
147 /*
148 * Perform the main system computation (solve the MDE).
149 */
150 template <int D, class T, class V>
151 void AmCompressor<D,T,V>::evaluate()
152 {
153 system().compute();
154 ++(CompressorT::mdeCounter_);
155 }
156
157 /*
158 * Compute the residual vector for the current system state.
159 */
160 template <int D, class T, class V>
161 void AmCompressor<D,T,V>::getResidual(VectorT& resid)
162 {
163 // Initialize residual to -1.0
164 VecOp::eqS(resid, -1.0);
165
166 // Add c fields to get SCF residual vector
167 const int nMonomer = system().mixture().nMonomer();
168 for (int i = 0; i < nMonomer; ++i) {
169 VecOp::addEqV(resid, system().c().rgrid(i));
170 }
171 }
172
173 /*
174 * Update the current system w fields.
175 */
176 template <int D, class T, class V>
177 void AmCompressor<D,T,V>::update(VectorT& newGuess)
178 {
179 // New field is w0_ + newGuess for the pressure field
180 const int nMonomer = system().mixture().nMonomer();
181 for (int i = 0; i < nMonomer; ++i) {
182 VecOp::addVV(wFieldTmp_[i], w0_[i], newGuess);
183 }
184
185 // Set system r-grid fields
186 system().w().setRGrid(wFieldTmp_);
187 }
188
189 /*
190 * Do-nothing output function.
191 */
192 template <int D, class T, class V>
193 void AmCompressor<D,T,V>::outputToLog()
194 {}
195
196}
197}
198#endif
virtual void setup(bool isContinuation)
void readMixingParameters(std::istream &in, bool useLambdaRamp=true)
void outputTimers(std::ostream &out) const
virtual void readParameters(std::istream &in)
int solve(bool isContinuation=false)
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
void readParameters(std::istream &in) override
Read all parameters and initialize.
void outputTimers(std::ostream &out) const override
Return compressor times contributions.
AmCompressor(typename T::System &system)
Constructor.
int compress() override
Compress to obtain partial saddle point w+.
void clearTimers() override
Clear all timers and mde counter.
void setup(bool isContinuation) override
Initialize just before entry to iterative loop.
static std::ostream & file()
Get log ostream by reference.
Definition Log.cpp:59
void setClassName(const char *className)
Set class name string.
File containing preprocessor macros for error handling.
void addEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place addition, a[i] += b[i] (real).
Definition VecOp.cpp:198
void eqV(Array< double > &a, Array< double > const &b, const int beginIdA, const int beginIdB, const int n)
Vector assignment, a[i] = b[i] (real, slice).
Definition VecOp.cpp:21
void subVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector subtraction, a[i] = b[i] - c[i] (real)
Definition VecOp.cpp:95
void eqS(Array< double > &a, double b)
Vector assignment, a[i] = b (real).
Definition VecOp.cpp:50
void addVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector addition, a[i] = b[i] + c[i] (real)
Definition VecOp.cpp:64
Class templates for real-valued periodic fields.
PSCF package top-level namespace.