evaleev / libint

Libint: high-performance library for computing Gaussian integrals in quantum mechanics
Other
218 stars 96 forks source link

shell2bf does not work after BasisSet is sorted. #245

Closed FreemanTheMaverick closed 2 years ago

FreemanTheMaverick commented 2 years ago

Hi. I sorted the libint2::Shells in a libint2::BasisSet by the symmetrically equivalent sets they belong to.

libint2::BasisSet SortObsBySet(libint2::BasisSet obs,EigenMatrix shellsetindices){ // Sorting the shells by their equivalent sets. Eigen::Matrix shellsetindices contains the equivalent shell set that each shell belongs to. For example, [0,2,2,1] means the four shells belong to the 0^th, 2^nd, 2^nd and 1^st sets respectively.
        int maxi=-1;int maxj=-1; // The indices of the maximun value. Useless.
        int nshells=obs.size();
        int nsets=shellsetindices.maxCoeff(&maxi,&maxj)+1; // The number of equivalent shell sets. Since indices start from 0, nsets equals the maximum index of those equivalent sets plus one.
        libint2::BasisSet sortedobs; // A new libint2::BasisSet.
        for (int iset=0;iset<nsets;iset++){ // Looping over all equivalent shell sets.
                for (int ishell=0;ishell<nshells;ishell++){ // Looping over all shells.
                        if (shellsetindices(ishell)==iset) // If the current set and the set of the current shell coincide, putting the shell into a new libint2::BasisSet.
                                sortedobs.push_back(obs[ishell]);
                }
        }
        return sortedobs;
}

But after this, it seems that shell2bf does not function normally. That is, a segment error appears by the end of the main function.

int main(......){
......
        libint2::BasisSet obs(argv[2],atoms);
......
        std::copy(begin(obs), end(obs),std::ostream_iterator<libint2::Shell>(std::cout, "\n"));
        auto shell2bf1=obs.shell2bf();
        std::cout<<shell2bf1[0]<<std::endl; // Not sorted. Everything is fine.

        obs=SortObsBySet(obs,shellsetindices); // Sorting.

        std::copy(begin(obs), end(obs),std::ostream_iterator<libint2::Shell>(std::cout, "\n"));
        auto shell2bf=obs.shell2bf();
        std::cout<<shell2bf[0]<<std::endl; // Sorted. Segment error appears here.
......
}

I will appreciate it if anyone tells me how to deal with this problem.

evaleev commented 2 years ago

@FreemanTheMaverick BasisSet should not be treated as a mutable sequence of vectors. For now you need to manipulate a vector of shells before making a BasisSet. I created https://github.com/evaleev/libint/pull/246 to make uses like yours not possible in the future.

FreemanTheMaverick commented 2 years ago

@FreemanTheMaverick BasisSet should not be treated as a mutable sequence of vectors. For now you need to manipulate a vector of shells before making a BasisSet. I created #246 to make uses like yours not possible in the future.

Thank you for your reply. Then how may I convert a vector of Shells into a valid BasisSet?

FreemanTheMaverick commented 2 years ago

@FreemanTheMaverick BasisSet should not be treated as a mutable sequence of vectors. For now you need to manipulate a vector of shells before making a BasisSet. I created #246 to make uses like yours not possible in the future.

Thank you very much.