1 /*
2
3 Copyright (C) 2007 Lucas K. Wagner
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 */
20
21
22 #ifndef POSTPROCESS_METHOD_H_INCLUDED
23 #define POSTPROCESS_METHOD_H_INCLUDED
24
25 #include <vector>
26 #include <fstream>
27 #include <math.h>
28 #include <stdlib.h>
29 #include "Qmc_method.h"
30 #include "qmc_io.h"
31 #include "Array.h"
32 #include "MO_matrix.h"
33 #include "Sample_point.h"
34 #include "Properties.h"
35 class System;
36 class Wavefunction;
37 class Program_options;
38
39 /*!
40 In DMC, use the option SAVE_TRACE filename to save the walker positions and their weights to a binary file (called 'filename') once every block.
41 These walkers should be decorrelated, so they can now be treated independently.
42
43 Now, you can use
44 method { POSTPROCESS
45 READCONFIG filename
46 AVERAGE { ... }
47 DENSITY { ... }
48 }
49 include sys
50 trialfunc { .. }
51
52 to take any averages that you'd like.
53
54 There are some tradeoffs with this method. First, since we only save the walkers occasionally, the error bars will b
55 e larger than if you had put AVERAGE into the DMC section directly. However, if the AVERAGE takes some time to evalu
56 ate, such as the 2-RDM, then you will also not waste time evaluating the object on highly correlated walkers. You sh
57 ould use this scheme when one of the following is true:
58 a) You're not sure what averaging variables you want when the DMC calculation is run.
59 b) The averaging variables you want dominate the cost of the DMC calculation (2-RDM!)
60
61 Otherwise, evaluation on the fly (AVERAGE in the DMC section) is better.
62
63 */
64 class Postprocess_method : public Qmc_method
65 {
66 public:
67 void read(vector <string> words,
68 unsigned int & pos,
69 Program_options & options);
70 void run(Program_options & options, ostream & output);
71 int showinfo(ostream & os);
Postprocess_method()72 Postprocess_method():sys(NULL),pseudo(NULL),wfdata(NULL) {}
~Postprocess_method()73 ~Postprocess_method()
74 {
75 if(sys != NULL) delete sys;
76 if(pseudo!=NULL) delete pseudo;
77 if(wfdata!=NULL) delete wfdata;
78 for(int i=0; i< densplt.GetDim(0); i++) delete densplt(i);
79 for(int i=0; i< average_var.GetDim(0); i++) delete average_var(i);
80 }
81
82 private:
83 int gen_point(Wavefunction * wf, Sample_point * sample,
84 Config_save_point & configpos, doublevar weight, Properties_point & pt);
85 int worker(Wavefunction * wf, Sample_point * sample);
86 int master(Wavefunction * wf, Sample_point * sample,FILE * f,ostream & );
87
88
89
90 int nskip;
91 bool evaluate_energy;
92 bool json_output;
93 string json_file;
94 System * sys;
95 Pseudopotential * pseudo;
96 Wavefunction_data * wfdata;
97 Array1 < Local_density_accumulator *> densplt;
98 Array1 < Average_generator * > average_var;
99 string configfile;
100 };
101
102 //----------------------------------------------------------------------
103
104
weighted_update_average(doublevar weight,doublevar xnew,doublevar & xavg,doublevar & xvar,doublevar & totweight)105 inline void weighted_update_average(doublevar weight, doublevar xnew,doublevar & xavg, doublevar & xvar, doublevar & totweight)
106 {
107 doublevar nweight=totweight+weight;
108 doublevar navg=(weight*xnew+totweight*xavg)/nweight;
109 doublevar nvar=(weight*xnew*xnew+totweight*(xavg*xavg+xvar))/nweight-navg*navg;
110 xavg=navg;
111 xvar=nvar;
112 }
113 //----------------------------------------------------------------------
114
115 class Postprocess_average {
116 public:
Postprocess_average(int navg)117 Postprocess_average(int navg) {
118 avgavg.Resize(navg);
119 varavg.Resize(navg);
120 avgen=varen=avgwt=varwt=0.0;
121 npoints=0;
122 }
123
124 //---------------------
125
update_average(Properties_point & pt)126 void update_average(Properties_point & pt) {
127 // cout << "here" << endl;
128 weighted_update_average(pt.weight(0),pt.energy(0),avgen,varen,avgwt);
129 for(int i=0; i< avgavg.GetDim(0); i++) {
130 //cout << "resizing avg " <<i << " avgavg " << avgavg.GetDim(0)
131 // << " varavg " << varavg.GetDim(0) << " pt.avgrets "<< pt.avgrets.GetDim(0) << " "
132 // << pt.avgrets.GetDim(1) << endl;
133 if(avgavg(i).vals.GetDim(0)==0) {
134 avgavg(i)=pt.avgrets(0,i);
135 varavg(i)=pt.avgrets(0,i);
136 avgavg(i).vals=0;
137 varavg(i).vals=0;
138 }
139 //cout << "updaing average " << endl;
140 for(int j=0; j< pt.avgrets(0,i).vals.GetDim(0); j++) {
141 weighted_update_average(pt.weight(0),pt.avgrets(0,i).vals(j),avgavg(i).vals(j),varavg(i).vals(j),avgwt);
142 }
143 }
144 avgwt+=pt.weight(0);
145 npoints++;
146 }
147 //---------------------
print(Array1<Average_generator * > average_var,ostream & output)148 void print(Array1<Average_generator *> average_var,ostream & output) {
149 output.precision(10);
150 output << "Averages" << endl;
151 if(avgen!=0 and varen!=0)
152 output << "total_energy " << avgen << " +/- " << sqrt(varen/npoints) << " (sigma " << sqrt(varen) << ") "<< endl;
153 output << "weight " << avgwt/npoints << endl;
154 for(int i=0; i< avgavg.GetDim(0); i++) {
155 for(int j=0; j< varavg(i).vals.GetDim(0); j++)
156 varavg(i).vals(j)=sqrt(varavg(i).vals(j)/npoints);
157 average_var(i)->write_summary(avgavg(i),varavg(i),output);
158 }
159
160 }
161
162 //---------------------
JsonOutput(Array1<Average_generator * > & average_var,ostream & os)163 void JsonOutput(Array1<Average_generator *> & average_var,
164 ostream & os) {
165 os.precision(14);
166 os << "{ \"label\":\"postprocess\"," << endl;
167 os << "\"npoints\":" << npoints << "," << endl;
168 os << "\"properties\":{"<< endl;
169 if(avgen!=0 and varen!=0) {
170 os << "\"energy\": { " << endl;
171 os << "\"value\": [ " << avgen << " ]," << endl;
172 os << "\"error\": [ " << sqrt(varen/npoints) << " ]," << endl;
173 os << "\"sigma\": [ " << sqrt(varen) << " ]" << endl;
174 os << "}" << endl;
175 }
176 for(int i=0; i< average_var.GetDim(0); i++) {
177 if(i!=0 or (avgen!=0 and varen!=0) )
178 os << "," << endl;
179 average_var(i)->jsonOutput(avgavg(i),varavg(i), os);
180 }
181
182 os <<"}"<< endl;
183 os << "}" << endl;
184
185
186 }
187 private:
188 doublevar avgen,varen,avgwt,varwt;
189 long int npoints;
190 Array1 <Average_return> avgavg, varavg;
191
192 };
193
194 #endif //POSTPROCESS_METHOD_H_INCLUDED
195 //------------------------------------------------------------------------
196