DOCI-Exact  1.0
Molecule.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <assert.h>
3 #include <hdf5.h>
4 
5 #include "Molecule.h"
6 #include "Permutation.h"
7 
8 using namespace doci;
9 
10 // this helps to check the return codes of HDF5 calls
11 #define HDF5_STATUS_CHECK(status) if(status < 0) std::cerr << __FILE__ << ":" << __LINE__ << ": Problem with writing to file. Status code=" << status << std::endl;
12 
16 double Molecule::get_nucl_rep() const
17 {
18  return nucl_rep;
19 }
20 
24 unsigned int Molecule::get_n_sp() const
25 {
26  return n_sp;
27 }
28 
32 unsigned int Molecule::get_n_electrons() const
33 {
34  return n_electrons;
35 }
36 
37 
38 
50 PSI_C1_Molecule::PSI_C1_Molecule(std::string filename)
51 {
52  hid_t file_id, group_id, dataset_id, attribute_id;
53  herr_t status;
54 
55  file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
56  HDF5_STATUS_CHECK(file_id);
57 
58  group_id = H5Gopen(file_id, "/integrals", H5P_DEFAULT);
59  HDF5_STATUS_CHECK(group_id);
60 
61  attribute_id = H5Aopen(group_id, "nelectrons", H5P_DEFAULT);
62  HDF5_STATUS_CHECK(attribute_id);
63 
64  status = H5Aread(attribute_id, H5T_NATIVE_UINT, &n_electrons);
65  HDF5_STATUS_CHECK(status);
66 
67  status = H5Aclose(attribute_id);
68  HDF5_STATUS_CHECK(status);
69 
70  attribute_id = H5Aopen(group_id, "sp_dim", H5P_DEFAULT);
71  HDF5_STATUS_CHECK(attribute_id);
72 
73  status = H5Aread(attribute_id, H5T_NATIVE_UINT, &n_sp);
74  HDF5_STATUS_CHECK(status);
75 
76  status = H5Aclose(attribute_id);
77  HDF5_STATUS_CHECK(status);
78 
79  if(n_sp > Permutation::getMax() )
80  throw std::overflow_error("The used type is not big enough to store all single particle states!");
81 
82  attribute_id = H5Aopen(group_id, "nuclear_repulsion_energy", H5P_DEFAULT);
83  HDF5_STATUS_CHECK(attribute_id);
84 
85  status = H5Aread(attribute_id, H5T_NATIVE_DOUBLE, &nucl_rep);
86  HDF5_STATUS_CHECK(status);
87 
88  status = H5Aclose(attribute_id);
89  HDF5_STATUS_CHECK(status);
90 
91  // allocate space
92  OEI.reset(new helpers::matrix(n_sp, n_sp));
93 
94  TEI.reset(new helpers::matrix(n_sp*n_sp, n_sp*n_sp));
95 
96  dataset_id = H5Dopen(group_id, "OEI", H5P_DEFAULT);
97  HDF5_STATUS_CHECK(dataset_id);
98 
99  status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, OEI->getpointer());
100  HDF5_STATUS_CHECK(status);
101 
102  status = H5Dclose(dataset_id);
103  HDF5_STATUS_CHECK(status);
104 
105  dataset_id = H5Dopen(group_id, "TEI", H5P_DEFAULT);
106  HDF5_STATUS_CHECK(dataset_id);
107 
108  status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, TEI->getpointer());
109  HDF5_STATUS_CHECK(status);
110 
111  status = H5Dclose(dataset_id);
112  HDF5_STATUS_CHECK(status);
113 
114  status = H5Gclose(group_id);
115  HDF5_STATUS_CHECK(status);
116 
117  status = H5Fclose(file_id);
118  HDF5_STATUS_CHECK(status);
119 }
120 
125 {
126  OEI.reset(new helpers::matrix(*orig.OEI));
127  TEI.reset(new helpers::matrix(*orig.TEI));
128 
129  n_electrons = orig.n_electrons;
130  nucl_rep = orig.nucl_rep;
131  n_sp = orig.n_sp;
132 }
133 
138 {
139  OEI = std::move(orig.OEI);
140  TEI = std::move(orig.TEI);
141 
142  n_electrons = orig.n_electrons;
143  nucl_rep = orig.nucl_rep;
144  n_sp = orig.n_sp;
145 }
146 
148 {
149  OEI.reset(new helpers::matrix(*orig.OEI));
150  TEI.reset(new helpers::matrix(*orig.TEI));
151 
152  n_electrons = orig.n_electrons;
153  nucl_rep = orig.nucl_rep;
154  n_sp = orig.n_sp;
155 
156  return *this;
157 }
158 
160 {
161  OEI = std::move(orig.OEI);
162  TEI = std::move(orig.TEI);
163 
164  n_electrons = orig.n_electrons;
165  nucl_rep = orig.nucl_rep;
166  n_sp = orig.n_sp;
167 
168  return *this;
169 }
170 
178 {
179  return new PSI_C1_Molecule(*this);
180 }
181 
183 {
184  return new PSI_C1_Molecule(std::move(*this));
185 }
186 
194 double PSI_C1_Molecule::getT(int a, int b) const
195 {
196  assert(a<n_sp && b<n_sp);
197 
198  return (*OEI)(a,b);
199 }
200 
210 double PSI_C1_Molecule::getV(int a, int b, int c, int d) const
211 {
212  assert(a<n_sp && b<n_sp && c<n_sp && d<n_sp);
213 
214  return (*TEI)(a*n_sp + b, c*n_sp + d);
215 }
216 
221 void PSI_C1_Molecule::Print() const
222 {
223  auto L = get_n_sp();
224 
225  printf("%20.15f\t%d\t%d\t0\t0\n", 0.0, 0, 0);
226  for(int a=0;a<L;a++)
227  for(int b=0;b<L;b++)
228  printf("%20.15f\t%d\t%d\t0\t0\n", (*OEI)(a,b), a+1,b+1);
229 
230  for(int a=0;a<L;a++)
231  for(int b=0;b<L;b++)
232  for(int c=0;c<L;c++)
233  for(int d=0;d<L;d++)
234  printf("%20.15f\t%d\t%d\t%d\t%d\n", (*TEI)(a*L+b,c*L+d), a+1,c+1,b+1,d+1);
235 }
236 
244 double PSI_C1_Molecule::HF_Energy() const
245 {
246  double energy = 0;
247 
248  // one particle terms
249  for(int a=0;a<n_electrons/2;a++)
250  energy += 2 * getT(a,a);
251 
252  // two particle terms
253  for(int a=0;a<n_electrons/2;a++)
254  for(int b=0;b<n_electrons/2;b++)
255  energy += 2 * getV(a,b,a,b) - getV(a,b,b,a);
256 
257  return energy;
258 }
259 
260 /* vim: set ts=3 sw=3 expandtab :*/
virtual double get_nucl_rep() const
Definition: Molecule.cpp:16
#define HDF5_STATUS_CHECK(status)
Definition: Molecule.cpp:11
unsigned int n_electrons
number of electrons
Definition: Molecule.h:38
double getV(int, int, int, int) const
Definition: Molecule.cpp:210
double HF_Energy() const
Definition: Molecule.cpp:244
PSI_C1_Molecule(std::string)
Definition: Molecule.cpp:50
double nucl_rep
nuclear repulsion (const part to add to the energy)
Definition: Molecule.h:41
double getT(int, int) const
Definition: Molecule.cpp:194
void Print() const
Definition: Molecule.cpp:221
virtual unsigned int get_n_electrons() const
Definition: Molecule.cpp:32
unsigned int n_sp
the size of the single particles space (without spin)
Definition: Molecule.h:44
PSI_C1_Molecule * move()
Definition: Molecule.cpp:182
static unsigned int getMax()
PSI_C1_Molecule * clone() const
Definition: Molecule.cpp:177
PSI_C1_Molecule & operator=(const PSI_C1_Molecule &)
Definition: Molecule.cpp:147
virtual unsigned int get_n_sp() const
Definition: Molecule.cpp:24