MADNESS 0.10.1
MolecularOrbitals.h
Go to the documentation of this file.
1/*
2 * MolecularOrbitals.h
3 *
4 * Created on: 11 Jul 2019
5 * Author: fbischoff
6 */
7
8#ifndef SRC_APPS_CHEM_MOLECULARORBITALS_H_
9#define SRC_APPS_CHEM_MOLECULARORBITALS_H_
10
11#include<vector>
16#include<stdio.h>
17
18namespace madness {
19
20template<typename T, std::size_t NDIM> class Function;
21//class World;
22class AtomicBasisSet;
23
24template<typename T, std::size_t NDIM>
26public:
27
29
30 MolecularOrbitals() = default;
31
33 : mo(mo), eps(), irreps(), occ(), localize_sets() {
34 }
35
37 : mo(mo), eps(eps), irreps(), occ(), localize_sets() {
38 }
39
41 const std::vector<std::string>& irrep, const Tensor<double>& occ,
42 const std::vector<int>& set)
43 : mo(mo), eps(eps), irreps(irrep), occ(occ), localize_sets(set) {
44 }
45
46 MolecularOrbitals get_subset(const int iset) const {
48 auto s=slices[iset];
49 MolecularOrbitals result;
50 MADNESS_CHECK(mo.size()>=size_t(s.end+1));
51// result.mo.assign(mo.begin()+s.start,mo.begin()+s.end+1);
52 for (int i=s.start; i<s.end+1; ++i) result.mo.push_back(copy(mo[i]));
53 if (eps.size()>0) result.eps=copy(eps(s));
54 if (irreps.size()>0) result.irreps.assign(irreps.begin()+s.start,irreps.begin()+s.end+1);
55 if (occ.size()>0) result.occ=copy(occ(s));
56 if (localize_sets.size()>0) result.localize_sets.assign(localize_sets.begin()+s.start,localize_sets.begin()+s.end+1);
57
58 return result;
59 }
60
61 std::size_t size() const {
62 return mo.size();
63 }
64
65 std::vector<Function<T,NDIM> > get_mos() const {
66 return mo;
67 }
68
69 [[nodiscard]] Tensor<double> get_eps() const {
70 return eps;
71 }
72
73 [[nodiscard]] std::vector<std::string> get_irreps() const {
74 return irreps;
75 }
76
77 std::vector<int> get_localize_sets() const {
78 return localize_sets;
79 }
80
82 return occ;
83 }
84
85 /// setters will always invalidate all other member variables
86 MolecularOrbitals& set_mos(const std::vector<Function<T,NDIM> >& mo_new) {
88 mo=mo_new;
89 return *this;
90 }
91
92 /// updates will keep other member variables
93 MolecularOrbitals& update_mos(const std::vector<Function<T,NDIM> >& mo_new) {
94 mo=mo_new;
95 return *this;
96 }
97
99 occ=occ_new;
100 return *this;
101 }
102
103 /// updates will keep other member variables
104 MolecularOrbitals& update_localize_set(const std::vector<int>& set) {
105 localize_sets=set;
106 return *this;
107 }
108
109 /// updates will keep other member variables
111 const Tensor<double>& eps_new) {
112 mo=mo_new;
113 eps=copy(eps_new);
114 return *this;
115 }
116
117 MolecularOrbitals& recompute_irreps(const std::string pointgroup,
118 const Function<typename Tensor<T>::scalar_type,NDIM>& metric);
119
120 /// group orbitals into sets of similar orbital energies for localization
121 MolecularOrbitals& recompute_localize_sets(const double bandwidth=1.5) {
123 std::size_t nmo = mo.size();
124 std::vector<int> set = std::vector<int>(static_cast<size_t>(nmo), 0);
125 for (size_t i = 1; i < nmo; ++i) {
126 set[i] = set[i - 1];
127 // Only the new/boys localizers can tolerate not separating out the core orbitals
128 if (eps(i) - eps(i - 1) > bandwidth || get_occ()(i) != 1.0) ++(set[i]);
129 }
131 return *this;
132 }
133
134 static std::vector<Slice> convert_set_to_slice(const std::vector<int>& localized_set) {
135 std::vector<Slice> blocks;
136 long ilo=0;
137 for (size_t i=1; i<localized_set.size(); ++i) {
138 if (not (localized_set[i]==localized_set[i-1])) {
139 blocks.push_back(Slice(ilo, i-1));
140 ilo=i;
141 }
142 }
143 // add final block
144 blocks.push_back(Slice(ilo,localized_set.size()-1));
145 return blocks;
146 }
147
148
150 occ=Tensor<double>(mo.size());
151 occ=1.0;
152 return *this;
153 }
154
162
164 mo.clear();
165 }
166
168 eps.clear();
169 }
170
172 irreps.clear();
173 }
174
176 occ.clear();
177 }
178
180 localize_sets.clear();
181 }
182
183 void pretty_print(std::string message, std::vector<std::string> flags=std::vector<std::string>()) const {
184 print(message);
185 if (flags.size()==0) flags.resize(mo.size());
186 std::vector<std::string> irreps=get_irreps();
187 if (irreps.size()==0) irreps=std::vector<std::string>(mo.size(),"unknown");
188 print("orbital # irrep energy occupation localize_set");
189 for (int i=mo.size()-1; i>=0; --i) {
190// double n=get_mos()[i].norm2();
191 constexpr std::size_t bufsize=1024;
192 char buf[bufsize];
193 snprintf(buf,bufsize,"%5d %10s %12.8f %6.2f %8d %15s", i, irreps[i].c_str(),get_eps()[i],
194 get_occ()[i],get_localize_sets()[i], flags[i].c_str());
195 cout << std::string(buf) <<endl;
196 }
197 }
198
199
200 void print_frozen_orbitals(const long freeze) const {
201
202 World& world=mo.front().world();
203 MolecularOrbitals<T, 3> dummy_mo(*this);
204 dummy_mo.recompute_localize_sets();
205 if (world.rank() == 0) {
206 auto flags=std::vector<std::string>(dummy_mo.get_mos().size(),"active");
207 for (int i=0; i<freeze; ++i) flags[i]="frozen";
208 dummy_mo.pretty_print("diagonal Fock matrix elements with core/valence separation for freezing",flags);
209 print("\nfreezing orbitals: ", freeze,"\n");
210 }
211
212 }
213
214
215 /// @param[in] cubefile_header header of the cube file, from molecule::cubefile_header()
216 void print_cubefiles(const std::string name, const std::vector<std::string> cubefile_header) const;
217
218 template <typename Archive>
219 void serialize (Archive& ar) {
220 std::size_t nmo=mo.size();
221 ar & nmo;
222 if (nmo!=mo.size()) mo.resize(nmo);
223 for (auto& m : mo) ar & m;
224 ar & eps & irreps & occ & localize_sets;
225 if (ar.is_input_archive) {
226 if (irreps.size()==0) irreps=std::vector<std::string>(nmo,"unknown");
227 if (localize_sets.size()==0) localize_sets=std::vector<int>(nmo,0);
228 if (occ.size()==0) occ=Tensor<double>(nmo);
229 if (eps.size()==0) eps=Tensor<double>(nmo);
230 }
231 }
232
233 friend bool similar(const MolecularOrbitals& mo1, const MolecularOrbitals& mo2, const double thresh=1.e-6) {
234
235 if (mo1.mo.size()!=mo2.mo.size()) return false;
236 if (mo1.mo.size()==0) return true;
237
238 World& world=mo1.mo.front().world();
239 bool similar=((mo1.eps-mo2.eps).normf()<thresh);
240 similar=similar and (norm2(world,mo1.mo-mo2.mo)<thresh);
241 similar=similar and (mo1.irreps==mo2.irreps);
243 return similar;
244 }
245
246 void write_to(std::vector<Function<T,NDIM> >& mo_out, Tensor<double>& eps_out,
247 std::vector<std::string>& irrep_out, Tensor<double>& occ_out, std::vector<int>& set_out) const;
248
249 /// reads amo and bmo from the restartdata file
250
251 /// @return amo and bmo
252 std::pair<MolecularOrbitals<T,NDIM>, MolecularOrbitals<T,NDIM> >
253 static read_restartdata(World& world, const std::string filename, const Molecule& molecule,
254 const std::size_t nmo_alpha, const std::size_t nmo_beta) {
255
256 // The header layout belongs to RestartMetadata (chem/Restart.h), shared
257 // with SCF::{save,load}_mos; it reads version 4 and 5 alike.
258 //
259 // NB: the archive's molecule lands in meta and is NOT written back over
260 // the caller's. The previous open-coded read passed `molecule` straight
261 // to operator&, which const_casts, so it silently replaced the caller's
262 // geometry with the archive's -- the same trap removed from
263 // SCF::load_mos. The requested geometry wins.
265 RestartMetadata meta;
266 meta.read(ar);
267
269 amo.load_mos(ar, molecule, nmo_alpha);
270 bool have_beta=(not meta.spin_restricted) and (nmo_beta>0);
271 if (have_beta) {
272 bmo.load_mos(ar,molecule,nmo_beta);
273 }
274 return std::make_pair(amo,bmo);
275 }
276
277 /// writes amo and bmo to a restartdata file
278
279 /// The header is written through RestartMetadata, so an archive produced here
280 /// is readable by SCF::load_mos. Most header fields describe an SCF this
281 /// function does not have (energy, convergence, xc), so they keep their
282 /// "unknown" defaults -- a restart will treat these orbitals as a guess to
283 /// iterate on rather than a converged answer, which is what they are.
284 void static save_restartdata(World& world, const std::string filename, const Molecule& molecule,
287
288 RestartMetadata meta;
289 meta.spin_restricted = false;
290 meta.molecule = molecule;
292 meta.eprec = molecule.parameters.eprec();
293 meta.madness_version = MADNESS_PACKAGE_VERSION;
294 meta.write(ar);
295
296 amo.save_mos(ar,molecule);
297 bmo.save_mos(ar,molecule);
298 }
299
300 /// legacy code
301 void load_mos(archive::ParallelInputArchive<>& ar, const Molecule& molecule, const std::size_t nmo_from_input) {
302
303 unsigned int nmo = 0;
304
305 ar & nmo;
306 // must hold in release builds too: too few orbitals in the archive
307 // otherwise silently yields a short mo vector further down
308 MADNESS_CHECK_THROW(nmo >= nmo_from_input,
309 "restart archive holds fewer orbitals than requested");
310 ar & eps & occ & localize_sets;
311 mo.resize(nmo);
312 for (unsigned int i = 0; i < mo.size(); ++i)
313 ar & mo[i];
314 unsigned int n_core = molecule.n_core_orb_all();
315 if (nmo > nmo_from_input) {
316 localize_sets = vector<int>(localize_sets.begin() + n_core,
317 localize_sets.begin() + n_core + nmo_from_input);
318 mo = std::vector<Function<T,NDIM> >(mo.begin() + n_core,
319 mo.begin() + n_core + nmo_from_input);
320 eps = copy(eps(Slice(n_core, n_core + nmo_from_input - 1)));
321 occ = copy(occ(Slice(n_core, n_core + nmo_from_input - 1)));
322 }
323 }
324
325 /// legacy code
327
328 unsigned int nmo=mo.size();
329
330 ar & nmo;
331 ar & eps & occ & localize_sets;
332 for (unsigned int i = 0; i < mo.size(); ++i)
333 ar & mo[i];
334 //unsigned int n_core = molecule.n_core_orb_all();
335 }
336
337 void post_process_mos(World& world, const double thresh, const int k);
338
339
340 /// save MOs in the AO projection for geometry restart
341
342 /// compute the aos in MRA projection as:
343 static void save_restartaodata(World& world, const Molecule& molecule,
345 const AtomicBasisSet& aobasis);
346
347 /// uses AO-projection as a restart guess
348
349 /// @return amo and bmo
350 std::pair<MolecularOrbitals<T,NDIM>, MolecularOrbitals<T,NDIM> >
351 static read_restartaodata(World& world,
352 const Molecule& molecule, const bool have_beta);
353
354 void project_ao(World& world, const Tensor<T>& Saomo, const std::vector<Function<double,3> >& aos);
355
356 std::vector<Vector<typename Tensor<T>::scalar_type,3>> compute_center(
357 const Function<typename Tensor<T>::scalar_type,NDIM> metric2=Function<typename Tensor<T>::scalar_type,NDIM>()) const;
358
359private:
360 std::vector<Function<T,NDIM> > mo;
362 std::vector<std::string> irreps;
364 std::vector<int> localize_sets;
365
366};
367
368} /* namespace madness */
369
370#endif /* SRC_APPS_CHEM_MOLECULARORBITALS_H_ */
the header of a restartdata archive, in one place
Contracted Gaussian basis.
Definition apps/periodic_old/molecularbasis.h:424
Contracted Gaussian basis.
Definition madness/chem/molecularbasis.h:469
long size() const
Returns the number of elements in the tensor.
Definition basetensor.h:138
static int get_k()
Returns the default wavelet order.
Definition funcdefaults.h:164
A multiresolution adaptive numerical function.
Definition mra.h:144
Definition MolecularOrbitals.h:25
void invalidate_eps()
Definition MolecularOrbitals.h:167
MolecularOrbitals get_subset(const int iset) const
Definition MolecularOrbitals.h:46
static void save_restartaodata(World &world, const Molecule &molecule, const MolecularOrbitals< T, NDIM > &amo, const MolecularOrbitals< T, NDIM > &bmo, const AtomicBasisSet &aobasis)
save MOs in the AO projection for geometry restart
Definition MolecularOrbitals.cc:83
std::vector< std::string > irreps
Definition MolecularOrbitals.h:362
void print_cubefiles(const std::string name, const std::vector< std::string > cubefile_header) const
Definition MolecularOrbitals.cc:66
void write_to(std::vector< Function< T, NDIM > > &mo_out, Tensor< double > &eps_out, std::vector< std::string > &irrep_out, Tensor< double > &occ_out, std::vector< int > &set_out) const
Definition MolecularOrbitals.cc:34
static std::pair< MolecularOrbitals< T, NDIM >, MolecularOrbitals< T, NDIM > > read_restartdata(World &world, const std::string filename, const Molecule &molecule, const std::size_t nmo_alpha, const std::size_t nmo_beta)
reads amo and bmo from the restartdata file
Definition MolecularOrbitals.h:253
MolecularOrbitals & update_mos(const std::vector< Function< T, NDIM > > &mo_new)
updates will keep other member variables
Definition MolecularOrbitals.h:93
MolecularOrbitals & recompute_localize_sets(const double bandwidth=1.5)
group orbitals into sets of similar orbital energies for localization
Definition MolecularOrbitals.h:121
Tensor< double > get_eps() const
Definition MolecularOrbitals.h:69
std::size_t size() const
Definition MolecularOrbitals.h:61
void save_mos(archive::ParallelOutputArchive<> &ar, const Molecule &molecule) const
legacy code
Definition MolecularOrbitals.h:326
void serialize(Archive &ar)
Definition MolecularOrbitals.h:219
friend bool similar(const MolecularOrbitals &mo1, const MolecularOrbitals &mo2, const double thresh=1.e-6)
Definition MolecularOrbitals.h:233
static std::pair< MolecularOrbitals< T, NDIM >, MolecularOrbitals< T, NDIM > > read_restartaodata(World &world, const Molecule &molecule, const bool have_beta)
uses AO-projection as a restart guess
Definition MolecularOrbitals.cc:104
void invalidate_occ()
Definition MolecularOrbitals.h:175
Tensor< double > eps
Definition MolecularOrbitals.h:361
MolecularOrbitals(const std::vector< Function< T, NDIM > > &mo)
Definition MolecularOrbitals.h:32
static std::vector< Slice > convert_set_to_slice(const std::vector< int > &localized_set)
Definition MolecularOrbitals.h:134
void invalidate_mos()
Definition MolecularOrbitals.h:163
MolecularOrbitals & set_all_orbitals_occupied()
Definition MolecularOrbitals.h:149
void invalidate_irreps()
Definition MolecularOrbitals.h:171
void invalidate_localize_sets()
Definition MolecularOrbitals.h:179
MolecularOrbitals & update_occ(const Tensor< double > &occ_new)
Definition MolecularOrbitals.h:98
MolecularOrbitals & update_localize_set(const std::vector< int > &set)
updates will keep other member variables
Definition MolecularOrbitals.h:104
MolecularOrbitals & update_mos_and_eps(const std::vector< Function< T, NDIM > > &mo_new, const Tensor< double > &eps_new)
updates will keep other member variables
Definition MolecularOrbitals.h:110
MolecularOrbitals(const std::vector< Function< T, NDIM > > &mo, const Tensor< double > &eps)
Definition MolecularOrbitals.h:36
void pretty_print(std::string message, std::vector< std::string > flags=std::vector< std::string >()) const
Definition MolecularOrbitals.h:183
MolecularOrbitals(const std::vector< Function< T, NDIM > > &mo, const Tensor< double > &eps, const std::vector< std::string > &irrep, const Tensor< double > &occ, const std::vector< int > &set)
Definition MolecularOrbitals.h:40
void project_ao(World &world, const Tensor< T > &Saomo, const std::vector< Function< double, 3 > > &aos)
Definition MolecularOrbitals.cc:141
Tensor< double > get_occ() const
Definition MolecularOrbitals.h:81
std::vector< int > get_localize_sets() const
Definition MolecularOrbitals.h:77
std::vector< Function< T, NDIM > > mo
Definition MolecularOrbitals.h:360
std::vector< Function< T, NDIM > > get_mos() const
Definition MolecularOrbitals.h:65
MolecularOrbitals(const MolecularOrbitals< T, NDIM > &other)=default
std::vector< int > localize_sets
Definition MolecularOrbitals.h:364
Tensor< double > occ
Definition MolecularOrbitals.h:363
std::vector< std::string > get_irreps() const
Definition MolecularOrbitals.h:73
static void save_restartdata(World &world, const std::string filename, const Molecule &molecule, const MolecularOrbitals< T, NDIM > &amo, const MolecularOrbitals< T, NDIM > &bmo)
writes amo and bmo to a restartdata file
Definition MolecularOrbitals.h:284
void invalidate_all()
Definition MolecularOrbitals.h:155
void print_frozen_orbitals(const long freeze) const
Definition MolecularOrbitals.h:200
void post_process_mos(World &world, const double thresh, const int k)
Definition MolecularOrbitals.cc:53
void load_mos(archive::ParallelInputArchive<> &ar, const Molecule &molecule, const std::size_t nmo_from_input)
legacy code
Definition MolecularOrbitals.h:301
std::vector< Vector< typename Tensor< T >::scalar_type, 3 > > compute_center(const Function< typename Tensor< T >::scalar_type, NDIM > metric2=Function< typename Tensor< T >::scalar_type, NDIM >()) const
Definition MolecularOrbitals.cc:155
MolecularOrbitals & set_mos(const std::vector< Function< T, NDIM > > &mo_new)
setters will always invalidate all other member variables
Definition MolecularOrbitals.h:86
MolecularOrbitals & recompute_irreps(const std::string pointgroup, const Function< typename Tensor< T >::scalar_type, NDIM > &metric)
Definition MolecularOrbitals.cc:24
Definition molecule.h:129
A slice defines a sub-range or patch of a dimension.
Definition slice.h:103
A tensor is a multidimensional array.
Definition tensor.h:318
TensorTypeData< T >::scalar_type scalar_type
C++ typename of the real type associated with a complex type.
Definition tensor.h:410
void clear()
Frees all memory and resests to state of default constructor.
Definition tensor.h:1901
A parallel world class.
Definition world.h:134
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
An archive for storing local or parallel data, wrapping a BinaryFstreamInputArchive.
Definition parallel_archive.h:366
An archive for storing local or parallel data wrapping a BinaryFstreamOutputArchive.
Definition parallel_archive.h:321
Objects that implement their own parallel archive interface should derive from this class.
Definition parallel_archive.h:58
const std::size_t bufsize
Definition derivatives.cc:16
#define MADNESS_CHECK(condition)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:182
#define MADNESS_CHECK_THROW(condition, msg)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:207
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
static const char * filename
Definition legendre.cc:96
double norm2(World &world, const std::vector< Function< T, NDIM > > &v)
Computes the 2-norm of a vector of functions.
Definition vmra.h:921
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:227
std::vector< std::string > cubefile_header(std::string filename="input", const bool &no_orient=false)
Definition molecule.cc:73
std::string name(const FuncType &type, const int ex=-1)
Definition ccpairfunction.h:28
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition mra.h:2187
Implements ParallelInputArchive and ParallelOutputArchive for parallel serialization of data.
static const double m
Definition relops.cc:9
static const double thresh
Definition rk.cc:45
static const long k
Definition rk.cc:44
Definition Restart.h:105
void read(Archive &ar)
Definition Restart.h:169
void write(Archive &ar) const
write the header at the current archive position, always at CURRENT_VERSION
Definition Restart.h:153
double eprec
Definition Restart.h:139
int k
Definition Restart.h:116
std::string madness_version
MADNESS version that wrote the archive, for provenance in bug reports.
Definition Restart.h:142
bool spin_restricted
Definition Restart.h:114
Molecule molecule
Definition Restart.h:117
Defines and implements most of Tensor.
constexpr std::size_t NDIM
Definition testgconv.cc:54
static Molecule molecule
Definition testperiodicdft.cc:39
static AtomicBasisSet aobasis
Definition testperiodicdft.cc:40