PSCF v1.3
rpc/fts/analyzer/AverageListAnalyzer.tpp
1#ifndef RPC_AVERAGE_LIST_ANALYZER_TPP
2#define RPC_AVERAGE_LIST_ANALYZER_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 "AverageListAnalyzer.h"
12
13#include <rpc/system/System.h>
14#include <util/format/Int.h>
15#include <util/format/Dbl.h>
16#include <util/misc/FileMaster.h>
17#include <util/misc/ioUtil.h>
18
19namespace Pscf {
20namespace Rpc
21{
22
23 using namespace Util;
24
25 /*
26 * Constructor.
27 */
28 template <int D>
31 : Analyzer<D>(),
32 simulatorPtr_(&simulator),
33 systemPtr_(&system),
34 nSamplePerOutput_(1),
35 nValue_(0),
36 hasAccumulators_(false)
37 {}
38
39 /*
40 * Destructor.
41 */
42 template <int D>
45
46 /*
47 * Read interval and outputFileName.
48 */
49 template <int D>
51 {
53 nSamplePerOutput_ = 1;
54 readOptional(in,"nSamplePerOutput", nSamplePerOutput_);
55 if (nSamplePerOutput() > 0) {
56 std::string fileName = outputFileName(".dat");
57 system().fileMaster().openOutputFile(fileName, outputFile_);
58 }
59 // Note: ReadParameters method of derived classes should call this,
60 // determine nValue and then call initializeAccumulators(nValue).
61 }
62
63 template <int D>
64 void AverageListAnalyzer<D>::setName(int i, std::string name)
65 {
66 UTIL_CHECK(hasAccumulators_);
67 UTIL_CHECK(i >= 0 && i < nValue_);
68 names_[i] = name;
69 }
70
71 /*
72 * Setup before system.
73 */
74 template <int D>
76 {
77 UTIL_CHECK(hasAccumulators_);
79 }
80
81 /*
82 * Compute and sample current values.
83 */
84 template <int D>
86 {
87 UTIL_CHECK(hasAccumulators_);
88 if (!isAtInterval(iStep)) return;
89 compute();
90 updateAccumulators(iStep);
91 }
92
93 /*
94 * Output results after a simulation is completed.
95 */
96 template <int D>
98 {
99 UTIL_CHECK(hasAccumulators_);
100
101 // Close data file, if any
102 if (outputFile_.is_open()) {
103 outputFile_.close();
104 }
105
106 #if 0
107 // Write parameter (*.prm) file
108 std::string filename = outputFileName(".prm");
109 system().fileMaster().openOutputFile(filename, outputFile_);
111 outputFile_.close();
112 #endif
113
114 // Write average (*.ave) and error analysis (*.aer) files
116
117 }
118
122 template <int D>
124 {
125 UTIL_CHECK(nValue > 0);
126 UTIL_CHECK(nValue_ == 0);
127 UTIL_CHECK(nSamplePerOutput_ >= 0);
128
129 // Allocate arrays
130 accumulators_.allocate(nValue);
131 names_.allocate(nValue);
132 values_.allocate(nValue);
133 nValue_ = nValue;
134 hasAccumulators_ = true;
135
136 // Set the accumulators to compute block averages with
137 // nSamplePerOutput_ sampled values per block
138 for (int i = 0; i < nValue_; ++i) {
139 accumulators_[i].setNSamplePerBlock(nSamplePerOutput_);
140 }
141
143 }
144
145 /*
146 * Clear accumulators.
147 */
148 template <int D>
150 {
151 UTIL_CHECK(hasAccumulators_);
152 UTIL_CHECK(nValue_ > 0);
153 for (int i = 0; i < nValue_; ++i) {
154 accumulators_[i].clear();
155 }
156 }
157
158 /*
159 * Update accumulators for all current values.
160 */
161 template <int D>
163 {
164 UTIL_CHECK(hasAccumulators_);
165 UTIL_CHECK(accumulators_.capacity() == nValue_);
166
167 // Update accumulators.
168 for (int i = 0; i < nValue(); ++i) {
169 double data = value(i);
170 accumulators_[i].sample(data);
171 }
172
173 // Output block averages
174 if (nSamplePerOutput_ > 0) {
175 if (accumulators_[0].isBlockComplete()) {
176 UTIL_CHECK(outputFile_.is_open());
177 int beginStep = iStep - (nSamplePerOutput_ - 1)*interval();
178 outputFile_ << Int(beginStep);
179 for (int i = 0; i < nValue(); ++i) {
180 UTIL_CHECK(accumulators_[i].isBlockComplete());
181 double block = accumulators_[i].blockAverage();
182 outputFile_ << Dbl(block);
183 }
184 outputFile_ << "\n";
185 }
186 }
187
188 }
189
190 /*
191 * Output results to file after simulation is completed.
192 */
193 template <int D>
195 {
196 UTIL_CHECK(hasAccumulators_);
197
198 // Close data (*.dat) file, if any
199 if (outputFile_.is_open()) {
200 outputFile_.close();
201 }
202
203 // Compute maximum length of name field
204 int nameWidth = 0;
205 int length;
206 for (int i = 0; i < nValue_; ++i) {
207 length = names_[i].length();
208 if (length > nameWidth) {
209 nameWidth = length;
210 }
211 }
212 nameWidth += 2;
213
214 // Write average (*.ave) file
215 std::string fileName = outputFileName(".ave");
216 system().fileMaster().openOutputFile(fileName, outputFile_);
217 double ave, err;
218 for (int i = 0; i < nValue_; ++i) {
219 ave = accumulators_[i].average();
220 err = accumulators_[i].blockingError();
221 outputFile_ << " " << std::left << std::setw(nameWidth)
222 << names_[i] << " ";
223 outputFile_ << Dbl(ave) << " +- " << Dbl(err, 9, 2) << "\n";
224 }
225 outputFile_.close();
226
227 // Write error analysis (*.aer) file
228 fileName = outputFileName(".aer");
229 system().fileMaster().openOutputFile(fileName, outputFile_);
230 std::string line;
231 line =
232 "---------------------------------------------------------------------";
233 for (int i = 0; i < nValue_; ++i) {
234 outputFile_ << line << std::endl;
235 outputFile_ << names_[i] << " :" << std::endl;
236 accumulators_[i].output(outputFile_);
237 outputFile_ << std::endl;
238 }
239 outputFile_.close();
240
241 #if 0
242 // Write data format file (*.dfm) file
243 fileName = outputFileName();
244 fileName += ".dfm";
245 system().fileMaster().openOutputFile(fileName, outputFile_);
246 outputFile_ << "Value = " << nValue() << std::endl;
247 outputFile_ << "iStep ";
248 for (int i = 0; i < nValue_; ++i) {
249 outputFile_ << names_[i] << " ";
250 }
251 outputFile_ << std::endl;
252 outputFile_.close();
253 #endif
254
255 }
256
257}
258}
259#endif
bool isAtInterval(long counter) const
Return true iff counter is a multiple of the interval.
virtual void readParameters(std::istream &in)
Read parameters from archive.
const std::string & outputFileName() const
Return outputFileName string.
int interval() const
Get interval value.
Analyzer()
Default constructor.
void updateAccumulators(long iStep)
Add current value to accumulator, output block average if needed.
void clearAccumulators()
Clear internal state of all accumulators.
int nSamplePerOutput() const
Get value of nSamplePerOutput.
AverageListAnalyzer(Simulator< D > &simulator, System< D > &system)
Constructor.
void initializeAccumulators(int nValue)
Instantiate Average accumulators and set nValue.
virtual void output()
Write final results to file after a simulation.
double value(int i) const
Get current value of a specific variable.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
Add and read a new optional ScalarParam < Type > object.
const std::string & name(int i) const
Get name associated with value.
System< D > & system()
Return reference to parent system.
virtual void compute()=0
Compute value of sampled quantities.
void setName(int i, std::string name)
Set name of variable.
virtual void sample(long iStep)
Compute a sampled value and update the accumulator.
void outputAccumulators()
Write results of statistical analysis to files.
Simulator< D > & simulator()
Return reference to parent Simulator.
virtual void readParameters(std::istream &in)
Read interval, outputFileName and (optionally) nSamplePerOutput.
Field theoretic simulator (base class).
Main class, representing one complete system.
Wrapper for a double precision number, for formatted ostream output.
Definition Dbl.h:40
Wrapper for an int, for formatted ostream output.
Definition Int.h:37
virtual void writeParam(std::ostream &out) const
Write all parameters to an output stream.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
Real periodic fields, SCFT and PS-FTS (CPU).
Definition param_pc.dox:2
PSCF package top-level namespace.
Definition param_pc.dox:1