CheMPS2
TwoIndex.cpp
1 /*
2  CheMPS2: a spin-adapted implementation of DMRG for ab initio quantum chemistry
3  Copyright (C) 2013-2016 Sebastian Wouters
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 #include <stdlib.h>
21 #include <assert.h>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 
26 #include "TwoIndex.h"
27 #include "MyHDF5.h"
28 
29 using namespace std;
30 
31 CheMPS2::TwoIndex::TwoIndex(const int nGroup, const int * IrrepSizes){
32 
33  SymmInfo.setGroup(nGroup);
34 
35  Isizes = new int[SymmInfo.getNumberOfIrreps()];
36  storage = new double*[SymmInfo.getNumberOfIrreps()];
37 
38  for (int cnt=0; cnt<SymmInfo.getNumberOfIrreps(); cnt++){
39  Isizes[cnt] = IrrepSizes[cnt];
40  if (Isizes[cnt]>0) storage[cnt] = new double[Isizes[cnt]*(Isizes[cnt]+1)/2];
41  }
42 
43  Clear();
44 
45 }
46 
48 
49  for (int cnt=0; cnt<SymmInfo.getNumberOfIrreps(); cnt++) if (Isizes[cnt]>0) delete [] storage[cnt];
50  delete [] storage;
51  delete [] Isizes;
52 
53 }
54 
56 
57  for (int irrep = 0; irrep < SymmInfo.getNumberOfIrreps(); irrep++){
58  const int loopsize = (Isizes[irrep]*(Isizes[irrep]+1))/2;
59  for (int count = 0; count < loopsize; count++){ storage[irrep][count] = 0.0; }
60  }
61 
62 }
63 
64 void CheMPS2::TwoIndex::set(const int irrep, const int i, const int j, const double val){
65 
66  if (i>j) storage[irrep][j + i*(i+1)/2] = val;
67  else storage[irrep][i + j*(j+1)/2] = val;
68 
69 }
70 
71 double CheMPS2::TwoIndex::get(const int irrep, const int i, const int j) const{
72 
73  if (i>j) return storage[irrep][j + i*(i+1)/2];
74  return storage[irrep][i + j*(j+1)/2];
75 
76 }
77 
78 void CheMPS2::TwoIndex::save(const std::string name) const{
79 
80  //The hdf5 file
81  hid_t file_id = H5Fcreate(name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
82 
83  //The metadata
84  hid_t group_id = H5Gcreate(file_id, "/MetaData", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
85 
86  //The IrrepSizes
87  hsize_t dimarray = SymmInfo.getNumberOfIrreps();
88  hid_t dataspace_id = H5Screate_simple(1, &dimarray, NULL);
89  hid_t dataset_id = H5Dcreate(group_id, "IrrepSizes", H5T_STD_I32LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
90  H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Isizes);
91 
92  //Attributes
93  hid_t attribute_space_id1 = H5Screate(H5S_SCALAR);
94  hid_t attribute_id1 = H5Acreate(dataset_id, "nGroup", H5T_STD_I32LE, attribute_space_id1, H5P_DEFAULT, H5P_DEFAULT);
95  int nGroup = SymmInfo.getGroupNumber();
96  H5Awrite(attribute_id1, H5T_NATIVE_INT, &nGroup);
97 
98  hid_t attribute_space_id2 = H5Screate(H5S_SCALAR);
99  hid_t attribute_id2 = H5Acreate(dataset_id, "nIrreps", H5T_STD_I32LE, attribute_space_id2, H5P_DEFAULT, H5P_DEFAULT);
100  int nIrreps = SymmInfo.getNumberOfIrreps();
101  H5Awrite(attribute_id2, H5T_NATIVE_INT, &nIrreps);
102 
103  H5Aclose(attribute_id1);
104  H5Aclose(attribute_id2);
105  H5Sclose(attribute_space_id1);
106  H5Sclose(attribute_space_id2);
107 
108  H5Dclose(dataset_id);
109  H5Sclose(dataspace_id);
110 
111  H5Gclose(group_id);
112 
113  //The object itself.
114  for (int cnt=0; cnt<SymmInfo.getNumberOfIrreps(); cnt++){
115 
116  if (Isizes[cnt]>0) {
117 
118  std::stringstream sstream;
119  sstream << "/TwoIndex" << cnt ;
120  hid_t group_id3 = H5Gcreate(file_id, sstream.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
121 
122  hsize_t dimarray3 = Isizes[cnt]*(Isizes[cnt]+1)/2;
123  hid_t dataspace_id3 = H5Screate_simple(1, &dimarray3, NULL);
124  hid_t dataset_id3 = H5Dcreate(group_id3, "Matrix elements", H5T_IEEE_F64LE, dataspace_id3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
125  H5Dwrite(dataset_id3, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, storage[cnt]);
126 
127  H5Dclose(dataset_id3);
128  H5Sclose(dataspace_id3);
129 
130  H5Gclose(group_id3);
131 
132  }
133 
134  }
135 
136  H5Fclose(file_id);
137 
138 }
139 
140 void CheMPS2::TwoIndex::read(const std::string name){
141 
142  //The hdf5 file
143  hid_t file_id = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
144 
145  //The metadata
146  hid_t group_id = H5Gopen(file_id, "/MetaData",H5P_DEFAULT);
147 
148  //The IrrepSizes
149  hid_t dataset_id = H5Dopen(group_id, "IrrepSizes", H5P_DEFAULT);
150 
151  //Attributes
152  hid_t attribute_id1 = H5Aopen_by_name(group_id,"IrrepSizes", "nGroup", H5P_DEFAULT, H5P_DEFAULT);
153  int nGroup;
154  H5Aread(attribute_id1, H5T_NATIVE_INT, &nGroup);
155  assert( nGroup==SymmInfo.getGroupNumber() );
156 
157  hid_t attribute_id2 = H5Aopen_by_name(group_id,"IrrepSizes", "nIrreps", H5P_DEFAULT, H5P_DEFAULT);
158  int nIrreps;
159  H5Aread(attribute_id2, H5T_NATIVE_INT, &nIrreps);
160  assert( nIrreps==SymmInfo.getNumberOfIrreps() );
161 
162  H5Aclose(attribute_id1);
163  H5Aclose(attribute_id2);
164 
165  int * IsizesAgain = new int[SymmInfo.getNumberOfIrreps()];
166  H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, IsizesAgain);
167  for (int cnt=0; cnt<SymmInfo.getNumberOfIrreps(); cnt++){
168  assert( IsizesAgain[cnt]==Isizes[cnt] );
169  }
170  delete [] IsizesAgain;
171  H5Dclose(dataset_id);
172 
173  H5Gclose(group_id);
174 
175  //The object itself.
176  for (int cnt=0; cnt<SymmInfo.getNumberOfIrreps(); cnt++){
177 
178  if (Isizes[cnt]>0) {
179 
180  std::stringstream sstream;
181  sstream << "/TwoIndex" << cnt ;
182  hid_t group_id3 = H5Gopen(file_id, sstream.str().c_str(), H5P_DEFAULT);
183 
184  hid_t dataset_id3 = H5Dopen(group_id3, "Matrix elements", H5P_DEFAULT);
185  H5Dread(dataset_id3, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, storage[cnt]);
186  H5Dclose(dataset_id3);
187 
188  H5Gclose(group_id3);
189 
190  }
191 
192  }
193 
194  H5Fclose(file_id);
195 
196 }
197 
198 
199 
void Clear()
Set all one-body matrix elements to zero.
Definition: TwoIndex.cpp:55
virtual ~TwoIndex()
Destructor.
Definition: TwoIndex.cpp:47
STL namespace.
void read(const std::string name)
Load the TwoIndex object.
Definition: TwoIndex.cpp:140
TwoIndex(const int nGroup, const int *IrrepSizes)
Constructor.
Definition: TwoIndex.cpp:31
void set(const int irrep, const int i, const int j, const double val)
Set an element.
Definition: TwoIndex.cpp:64
double get(const int irrep, const int i, const int j) const
Get an element.
Definition: TwoIndex.cpp:71
void save(const std::string name) const
Save the TwoIndex object.
Definition: TwoIndex.cpp:78