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 #ifndef WF_WRITER_H_INCLUDED
22 #define WF_WRITER_H_INCLUDED
23 #include <string>
24 #include <vector>
25 #include <iostream>
26 #include <cassert>
27 #include "converter.h"
28 #include "basis_writer.h"
29 
30 class Wf_writer {
31   public:
32     virtual void print_wavefunction(std::ostream & os)=0;
33 };
34 
35 
36 class Slat_wf_writer:public Wf_writer {
37 public:
Slat_wf_writer()38   Slat_wf_writer() { magnification=-1; orbtype="ORBITALS"; write_centers=false;}
39   int nup, ndown; //number of up and down electrons
40   int spin_dwn_start;  //the MO at which the down orbitals start(for a UHF calctype only)
41   double magnification;
42   std::string calctype; //RHF, ROHF, UHF, or GVB
43   std::string mo_matrix_type; //CUTOFF_MO, BLAS_MO, STANDARD_MO, etc
44   std::string orbname;  //name of the orbitals file
45   std::string orbtype;  //ORBITALS or CORBITALS
46   std::string centername; //name of the centers file(if used, probably not)
47   std::string basisname; //name of the basis file
48   bool write_centers; //whether or not to use the centers file
49   bool use_global_centers; //whether to use the global centers generated by the System object
50                           //(for a molecular system, it doesn't matter, but for a periodic
51                           // system, this should be set to true, assuming we're using an atom-centered basis)
52 
53   std::vector < double > kpoint; //the k-point at which we're doing the calculation
54                               //This really should be kept in the system, so don't use it.
55                               //It's just kept around because it pervades crystal2qmc..
56 
57 
58   std::vector < double > detwt; //the determinantal weights.  If this is not set, a single determinant will
59                                 //be assumed, and occ_up and occ_down will automatically be filled in.
60                                 //If detwt is set, then it is expected that occ-up and occ_down are filled in
61                                 //appropriately for each determinant.
62   std::vector < std:: vector < int > > occ_up;  //the occupation of the up molecular orbitals for each determinant,
63                                                 //starting from 1.
64                                                 //For single determinant calculations (RHF, UHF, ROHF), this will
65                                                 //automatically be filled as 1-nup.
66   std::vector < std:: vector < int > > occ_down;//same as occ_up, except it will be filled as 1-ndown for RHF and ROHF
67                                                 // and as spin_dwn_start-spin_down_start+ndown for UHF
68 
69 
70   void print_wavefunction(std::ostream & inputfile );
71 };
72 
73 class Atom;
74 class Basis_writer;
75 
76 class Jastrow_wf_writer:public Wf_writer {
77 public:
78   std::vector <std::string > atomnames;
79   std::vector <Basis_writer * > basis;
80   void print_wavefunction(std::ostream & inputfile);
81 
82   /*!
83     Gets the unique names from the list of atoms.
84   */
85   void set_atoms(std::vector <Atom > & atoms);
86 
87   /*!
88     Add a basis to the list of ones to print in the Jastrow section
89   */
90   void add_basis(Basis_writer & b);
91 };
92 
93 class Jastrow2_wf_writer:public Wf_writer {
94 public:
95   int ngroups;
96   std::vector < int > spindiff; //!< Whether we have different like/unlike channels for a group
97 
98 
99   std::vector <std::string > atomnames;
100   std::vector < std::vector <Basis_writer * >  > ee_basis;
101   std::vector < std::vector <Basis_writer * >  > ei_basis;
102   void print_wavefunction(std::ostream & inputfile);
103 
104   /*!
105     Gets the unique names from the list of atoms.
106   */
107   void set_atoms(std::vector <Atom > & atoms);
108 
set_groups(int ngroups_)109   void set_groups(int ngroups_) {
110     ee_basis.resize(ngroups_);
111     ei_basis.resize(ngroups_);
112     ngroups=ngroups_;
113     spindiff.resize(ngroups);
114     for(int g=0; g< ngroups; g++) spindiff[g]=0;
115   }
116 
set_spin_diff(int group)117   void set_spin_diff(int group){
118     assert(group < ngroups);
119     spindiff[group]=1;
120   }
121 
122 
123 
124   /*!
125     Add a basis to the list of ones to print in the Jastrow section
126   */
127   void add_ee_basis(Basis_writer & b, int group);
128   void add_ei_basis(Basis_writer & b, int group);
129 };
130 
131 
132 
133 void print_std_jastrow2(Jastrow2_wf_writer & jast2writer, std::ostream & os,
134                         double basis_cutoff);
135 
136 void print_3b_jastrow2(std::ostream & os,std::vector<std::string> & unique_atoms, double cutoff=7.5);
137 /*
138  Doubles a periodic cell in the specified direction.  latvec, moCoeff, and the atoms are all changed
139  to reflect the new cell.  Assumes atom-centered basis functions..
140 */
141 
142 using namespace std;
143 
144 template <typename T>
fold_kpoint(Slat_wf_writer & slwriter,std::vector<std::vector<double>> & latvec,int dir,std::vector<std::vector<T>> & moCoeff,std::vector<Atom> & atoms)145 void fold_kpoint(Slat_wf_writer & slwriter,
146                  std::vector <std::vector <double> > & latvec,
147                  int dir,
148                  std::vector <std::vector <T> > & moCoeff,
149                  std::vector <Atom> & atoms) {
150   //Note: this won't work for UHF wavefunctions..
151 
152   vector <Atom> natoms;
153   for(vector<Atom>::iterator i=atoms.begin(); i!=atoms.end(); i++) {
154     Atom tmp=*i;
155     for(int d=0;d < 3; d++) {
156       tmp.pos[d]+=latvec[dir][d];
157     }
158     natoms.push_back(tmp);
159   }
160   atoms.insert(atoms.end(), natoms.begin(), natoms.end());
161 
162   vector <vector <T> > nmocoeff;
163   vector<T> motmp;
164   int count=1;
165   for(typename vector<vector<T> >::iterator i=moCoeff.begin(); i!=moCoeff.end();
166       i++)
167     {
168       motmp.clear();
169       //gamma point
170       for(typename vector<T>::iterator j=i->begin(); j!= i->end(); j++) {
171 	motmp.push_back(*j);
172       }
173       for(typename vector<T>::iterator j=i->begin(); j!= i->end(); j++) {
174 	motmp.push_back(*j);
175       }
176       nmocoeff.push_back(motmp);
177       motmp.clear();
178       cout << "count " << count << " "  << nmocoeff.size() << " ";
179       //X point
180       for(typename vector<T>::iterator j=i->begin(); j!= i->end(); j++) {
181 	motmp.push_back(*j);
182       }
183       for(typename vector<T>::iterator j=i->begin(); j!= i->end(); j++) {
184 	motmp.push_back(-*j);
185       }
186       nmocoeff.push_back(motmp);
187       cout << " " << nmocoeff.size() << endl;
188       count++;
189     }
190   moCoeff=nmocoeff;
191 
192   for(int d=0; d< 3; d++) {
193     latvec[dir][d]*=2;
194   }
195 
196 }
197 
198 //----------------------------------------------------------------------
199 #endif
200