// // petite.h --- definition of the PetiteList class // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Edward Seidl // Maintainer: LPS // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit 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 Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #ifndef _chemistry_qc_basis_petite_h #define _chemistry_qc_basis_petite_h #ifdef __GNUC__ #pragma interface #endif #include #include #include #include #include #include #include #include #include #include // ////////////////////////////////////////////////////////////////////////// namespace sc { inline sc_int_least64_t ij_offset64(sc_int_least64_t i, sc_int_least64_t j) { return (i>j) ? (((i*(i+1)) >> 1) + j) : (((j*(j+1)) >> 1) + i); } inline sc_int_least64_t i_offset64(sc_int_least64_t i) { return ((i*(i+1)) >> 1); } // ////////////////////////////////////////////////////////////////////////// // These are helper functions for PetiteList and GPetite4 int **compute_atom_map(const Ref &); void delete_atom_map(int **atom_map, const Ref &); int **compute_shell_map(int **atom_map, const Ref &); void delete_shell_map(int **shell_map, const Ref &); // ////////////////////////////////////////////////////////////////////////// struct contribution { int bfn; double coef; contribution(); contribution(int b, double c); ~contribution(); }; struct SO { int len; int length; contribution *cont; SO(); SO(int); ~SO(); SO& operator=(const SO&); void set_length(int); void reset_length(int); // is this equal to so to within a sign int equiv(const SO& so); }; struct SO_block { int len; SO *so; SO_block(); SO_block(int); ~SO_block(); void set_length(int); void reset_length(int); int add(SO& s, int i); void print(const char *title); }; // ////////////////////////////////////////////////////////////////////////// // this should only be used from within a SymmGaussianBasisSet class PetiteList : public RefCount { private: int natom_; int nshell_; int ng_; int nirrep_; int nblocks_; int c1_; Ref gbs_; Ref ints_; char *p1_; // p1[n] is 1 if shell n is in the group P1 int **atom_map_; // atom_map[n][g] is the atom that symop g maps atom n // into int **shell_map_; // shell_map[n][g] is the shell that symop g maps shell n // into char *lamij_; // see Dupuis & King, IJQC 11,613,(1977) int *nbf_in_ir_; void init(); public: PetiteList(const Ref&, const Ref&); ~PetiteList(); Ref basis() { return gbs_; } Ref integral() { return ints_; } Ref clone() { return new PetiteList(gbs_, ints_); } int nirrep() const { return nirrep_; } int order() const { return ng_; } int atom_map(int n, int g) const { return (c1_) ? n : atom_map_[n][g]; } int shell_map(int n, int g) const { return (c1_) ? n : shell_map_[n][g]; } int lambda(int ij) const { return (c1_) ? 1 : (int) lamij_[ij]; } int lambda(int i, int j) const { return (c1_) ? 1 : (int) lamij_[ij_offset(i,j)]; } int in_p1(int n) const { return (c1_) ? 1 : (int) p1_[n]; } int in_p2(int ij) const { return (c1_) ? 1 : (int) lamij_[ij]; } /// Same as previous, except for it takes i and j separately int in_p2(int i, int j) const { return (c1_) ? 1 : (int) lamij_[ij_offset(i,j)]; } int in_p4(int ij, int kl, int i, int j, int k, int l) const; /// Same as previous, except for doesn't assume ij > kl and recomputes them int in_p4(int i, int j, int k, int l) const; int nfunction(int i) const { return (c1_) ? gbs_->nbasis() : nbf_in_ir_[i]; } int nblocks() const { return nblocks_; } void print(std::ostream& =ExEnv::out0(), int verbose=1); // these return blocked dimensions RefSCDimension AO_basisdim(); RefSCDimension SO_basisdim(); // return the basis function rotation matrix R(g) RefSCMatrix r(int g); // return information about the transformation from AOs to SOs SO_block * aotoso_info(); RefSCMatrix aotoso(); RefSCMatrix sotoao(); // given a skeleton matrix, form the symmetrized matrix in the SO basis void symmetrize(const RefSymmSCMatrix& skel, const RefSymmSCMatrix& sym); // transform a matrix from AO->SO or SO->AO. // this can take either a blocked or non-blocked AO basis matrix. RefSymmSCMatrix to_SO_basis(const RefSymmSCMatrix&); // this returns a non-blocked AO basis matrix. RefSymmSCMatrix to_AO_basis(const RefSymmSCMatrix&); // these two are just for eigenvectors // returns non-blocked AO basis eigenvectors RefSCMatrix evecs_to_AO_basis(const RefSCMatrix&); // returns blocked SO basis eigenvectors RefSCMatrix evecs_to_SO_basis(const RefSCMatrix&); }; inline int PetiteList::in_p4(int ij, int kl, int i, int j, int k, int l) const { if (c1_) return 1; sc_int_least64_t ijkl = i_offset64(ij)+kl; int nijkl=1; for (int g=1; g < ng_; g++) { int gij = ij_offset(shell_map_[i][g],shell_map_[j][g]); int gkl = ij_offset(shell_map_[k][g],shell_map_[l][g]); sc_int_least64_t gijkl = ij_offset64(gij,gkl); if (gijkl > ijkl) return 0; else if (gijkl == ijkl) nijkl++; } return ng_/nijkl; } inline int PetiteList::in_p4(int i, int j, int k, int l) const { if (c1_) return 1; int ij = ij_offset(i,j); int kl = ij_offset(k,l); sc_int_least64_t ijkl = ij_offset64(ij,kl); int nijkl=1; for (int g=1; g < ng_; g++) { int gij = ij_offset(shell_map_[i][g],shell_map_[j][g]); int gkl = ij_offset(shell_map_[k][g],shell_map_[l][g]); sc_int_least64_t gijkl = ij_offset64(gij,gkl); if (gijkl > ijkl) return 0; else if (gijkl == ijkl) nijkl++; } return ng_/nijkl; } } #endif // Local Variables: // mode: c++ // c-file-style: "ETS" // End: