forked from sanshar/Block
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsortNpdm.C
180 lines (139 loc) · 4.71 KB
/
sortNpdm.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <sstream>
#include <boost/filesystem.hpp>
#include <communicate.h> // enable Boost MPI wrappers if defined SERIAL
#include "sortNpdm.h"
void sort1pdm (FORTINT N_act, FORTINT iRoot, FORTINT jRoot)
{
// Sorting 3PDMs as Chemist's order
if(mpigetrank() == 0) {
std::ostringstream ifname;
ifname << "./node0/spatial_binary_onepdm." << iRoot << "." << jRoot << ".bin";
std::ostringstream ofname;
ofname << "./SORTED1PDM." << iRoot << "." << jRoot << ".0";
boost::filesystem::path path_to_1pdm(ifname.str().c_str());
assert(boost::filesystem::exists(path_to_1pdm));
int N1 = N_act;
int N2 = N1*N1;
// sort 1pdm as chemist's notation in column-major order
FILE *ifp = fopen(ifname.str().c_str(),"rb");
FILE *ofp = fopen(ofname.str().c_str(),"wb");
// sort <i,j> (in row-major) to G(i,j) (in col-major)
// i.e. G(i,j) = <i,j>
int Ndum;
fread(&Ndum,sizeof(int),1,ifp);
assert(Ndum == N_act);
double *xbuf = new double[N2];
fread(xbuf,sizeof(double),N2,ifp);
double *vbuf = new double[N2];
double *p = vbuf;
for(int j = 0; j < N_act; ++j) {
for(int i = 0; i < N_act; ++i, ++p) {
*p = xbuf[N1*i+j];
}
}
fwrite(vbuf,sizeof(double),N2,ofp);
delete [] vbuf;
delete [] xbuf;
fclose(ifp);
fclose(ofp);
boost::filesystem::remove(path_to_1pdm);
}
}
void sort2pdm (FORTINT N_act, FORTINT iRoot, FORTINT jRoot)
{
// Sorting 3PDMs as Chemist's order
if(mpigetrank() == 0) {
std::ostringstream ifname;
ifname << "./node0/spatial_binary_twopdm." << iRoot << "." << jRoot << ".bin";
std::ostringstream ofname;
ofname << "./SORTED2PDM." << iRoot << "." << jRoot << ".0";
boost::filesystem::path path_to_2pdm(ifname.str().c_str());
assert(boost::filesystem::exists(path_to_2pdm));
int N1 = N_act;
int N2 = N1*N1;
int N3 = N2*N1;
int N4 = N3*N1;
// sort 2pdm as chemist's notation in column-major order
FILE *ifp = fopen(ifname.str().c_str(),"rb");
FILE *ofp = fopen(ofname.str().c_str(),"wb");
// sort <i,j,k,l> (in row-major) to G(i,l,j,k) (in col-major)
// i.e. G(i,j,k,l) = <i,k,l,j>
int Ndum;
fread(&Ndum,sizeof(int),1,ifp);
assert(Ndum == N_act);
double *xbuf = new double[N4];
fread(xbuf,sizeof(double),N4,ifp);
double *vbuf = new double[N2];
for(int l = 0; l < N_act; ++l) {
size_t Lxxlx = N1*l;
for(int k = 0; k < N_act; ++k) {
size_t Lxklx = Lxxlx + N2*k;
double *p = vbuf;
for(int j = 0; j < N_act; ++j) {
size_t Lxklj = Lxklx + j;
for(int i = 0; i < N_act; ++i, ++p) {
size_t Liklj = Lxklj + N3*i;
// Re-scale by 2, because twopdm module computes (1/2) d_iklj
*p = 2.0*xbuf[Liklj];
}
}
fwrite(vbuf,sizeof(double),N2,ofp);
}
}
delete [] vbuf;
delete [] xbuf;
fclose(ifp);
fclose(ofp);
boost::filesystem::remove(path_to_2pdm);
}
}
void sort3pdm (FORTINT N_act, FORTINT iRoot, FORTINT jRoot)
{
// Sorting 3PDMs as Chemist's order
if(mpigetrank() == 0) {
std::ostringstream ifname;
ifname << "./node0/spatial_threepdm." << iRoot << "." << jRoot << ".bin";
std::ostringstream ofname;
ofname << "./SORTED3PDM." << iRoot << "." << jRoot << ".0";
boost::filesystem::path path_to_3pdm(ifname.str().c_str());
assert(boost::filesystem::exists(path_to_3pdm));
int N1 = N_act;
int N2 = N1*N1;
int N3 = N2*N1;
int N4 = N3*N1;
int N5 = N4*N1;
// sort 3pdm as chemist's notation in column-major order
FILE *ifp = fopen(ifname.str().c_str(),"rb");
FILE *ofp = fopen(ofname.str().c_str(),"wb");
// sort <i,j,k,l,m,n> (in row-major) to G(i,n,j,m,k,l) (in col-major)
// i.e. G(i,j,k,l,m,n) = <i,k,m,n,l,j>
// O(N^4) memory is allocated as buffer (lower overheads?)
double *vbuf = new double[N4];
for(int n = 0; n < N_act; ++n) {
size_t Lxxxnxx = N2*n;
for(int m = 0; m < N_act; ++m) {
size_t Lxxmnxx = Lxxxnxx + N3*m;
double *p = vbuf;
for(int l = 0; l < N_act; ++l) {
size_t Lxxmnlx = Lxxmnxx + N1*l;
for(int k = 0; k < N_act; ++k) {
size_t Lxkmnlx = Lxxmnlx + N4*k;
for(int j = 0; j < N_act; ++j) {
size_t Lxkmnlj = Lxkmnlx + j;
for(int i = 0; i < N_act; ++i, ++p) {
size_t Likmnlx = Lxkmnlj + N5*i;
fseek(ifp,sizeof(double)*Likmnlx,SEEK_SET);
fread(p,sizeof(double),1,ifp);
}
}
}
}
fwrite(vbuf,sizeof(double),N4,ofp);
}
}
delete [] vbuf;
fclose(ifp);
fclose(ofp);
boost::filesystem::remove(path_to_3pdm);
}
}