File: test9.cpp.in

package info (click to toggle)
chemps2 1.8.12-5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 5,432 kB
  • sloc: cpp: 38,521; python: 1,116; f90: 215; makefile: 45; sh: 23
file content (143 lines) | stat: -rw-r--r-- 5,733 bytes parent folder | download | duplicates (4)
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
/*
   CheMPS2: a spin-adapted implementation of DMRG for ab initio quantum chemistry
   Copyright (C) 2013-2018 Sebastian Wouters

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <iostream>
#include <math.h>

#include "Initialize.h"
#include "DMRG.h"
#include "MPIchemps2.h"

using namespace std;

int main(void){

   #ifdef CHEMPS2_MPI_COMPILATION
   CheMPS2::MPIchemps2::mpi_init();
   #endif

   CheMPS2::Initialize::Init();
   
   //Square 2D Hubbard model with PBC
   const int L_linear = 3;                    // Linear size
   const int L_square = L_linear * L_linear;  // Number of orbitals
   const int group = 0;                       // C1 symmetry
   const double U =  5.0;                     // On-site repulsion
   const double T = -1.0;                     // Hopping term
   
   const int N = 9;                           // Number of electrons
   const int TwoS = 1;                        // Two times the spin
   const int Irrep = 0;                       // Irrep = A (C1 symmetry)
   
   //Create the Hamiltonian (eightfold permutation symmetry is OK for site basis)
   int * irreps = new int[L_square];
   for (int cnt=0; cnt<L_square; cnt++){ irreps[cnt] = 0; }
   //The Hamiltonian initializes all its matrix elements to 0.0
   CheMPS2::Hamiltonian * Ham = new CheMPS2::Hamiltonian(L_square, group, irreps);
   delete [] irreps;
   
   //Fill with the site-basis matrix elements
   for (int cnt=0; cnt<L_square; cnt++){ Ham->setVmat(cnt,cnt,cnt,cnt,U); }
   for (int ix=0; ix<L_linear; ix++){
      for (int iy=0; iy<L_linear; iy++){
          const int idx1 = ix + L_linear * iy;                        // This site
          const int idx2 = (( ix + 1 ) % L_linear) + L_linear * iy;   // Right neighbour (PBC)
          const int idx3 = ix + L_linear * ((( iy + 1 ) % L_linear)); //Upper neighbour (PBC)
          Ham->setTmat(idx1,idx2,T);
          Ham->setTmat(idx1,idx3,T);
      }
   }
   
   //The problem object
   CheMPS2::Problem * Prob = new CheMPS2::Problem(Ham, TwoS, N, Irrep);
   
   //The convergence scheme
   CheMPS2::ConvergenceScheme * OptScheme = new CheMPS2::ConvergenceScheme(2);
   //OptScheme->setInstruction(instruction, DSU(2), Econvergence, maxSweeps, noisePrefactor);
   OptScheme->setInstruction(0,  500, 1e-10,  3, 0.05);
   OptScheme->setInstruction(1, 1000, 1e-10, 10, 0.0 );
   
   //Run ground state calculation
   CheMPS2::DMRG * theDMRG = new CheMPS2::DMRG(Prob, OptScheme);
   const double EnergySite = theDMRG->Solve();
   theDMRG->calc2DMandCorrelations();
   
   //Clean up DMRG
   if (CheMPS2::DMRG_storeMpsOnDisk){ theDMRG->deleteStoredMPS(); }
   if (CheMPS2::DMRG_storeRenormOptrOnDisk){ theDMRG->deleteStoredOperators(); }
   delete theDMRG;
   
   //Hack: overwrite the matrix elements in momentum space (4-fold symmetry!!!) directly in the Problem object
   theDMRG = new CheMPS2::DMRG(Prob, OptScheme); // Prob->construct_mxelem() is called now
   for (int orb1=0; orb1<L_square; orb1++){
      const int k1x = orb1 % L_linear;
      const int k1y = orb1 / L_linear;
      const double Telem1 = 2*T*( cos((2*M_PI*k1x)/L_linear)
                                + cos((2*M_PI*k1y)/L_linear) );
      for (int orb2=0; orb2<L_square; orb2++){
         const int k2x = orb2 % L_linear;
         const int k2y = orb2 / L_linear;
         const double Telem2 = 2*T*( cos((2*M_PI*k2x)/L_linear)
                                   + cos((2*M_PI*k2y)/L_linear) );
         for (int orb3=0; orb3<L_square; orb3++){
            const int k3x = orb3 % L_linear;
            const int k3y = orb3 / L_linear;
            for (int orb4=0; orb4<L_square; orb4++){
               const int k4x = orb4 % L_linear;
               const int k4y = orb4 / L_linear;
               const bool kx_conservation = (((k1x+k2x) % L_linear) == ((k3x+k4x) % L_linear))?true:false;
               const bool ky_conservation = (((k1y+k2y) % L_linear) == ((k3y+k4y) % L_linear))?true:false;
               double temp = 0.0;
               if ( kx_conservation && ky_conservation ){ temp += U/L_square; }
               if (( orb1 == orb3 ) && ( orb2 == orb4 )){ temp += (Telem1+Telem2)/(N-1); }
               Prob->setMxElement(orb1,orb2,orb3,orb4,temp);
            }
         }
      }
   }
   theDMRG->PreSolve(); // New matrix elements require reconstruction of complementary renormalized operators
   const double EnergyMomentum = theDMRG->Solve();
   theDMRG->calc2DMandCorrelations();
   
   //Clean up
   if (CheMPS2::DMRG_storeMpsOnDisk){ theDMRG->deleteStoredMPS(); }
   if (CheMPS2::DMRG_storeRenormOptrOnDisk){ theDMRG->deleteStoredOperators(); }
   delete theDMRG;
   delete OptScheme;
   delete Prob;
   delete Ham;
   
   //Check succes
   const bool success = ( fabs( EnergySite - EnergyMomentum ) < 1e-8 ) ? true : false;
   
   #ifdef CHEMPS2_MPI_COMPILATION
   CheMPS2::MPIchemps2::mpi_finalize();
   #endif
   
   cout << "================> Did test 9 succeed : ";
   if (success){
      cout << "yes" << endl;
      return 0; //Success
   }
   cout << "no" << endl;
   return 7; //Fail

}