1 /*
2  *  Copyright (C) 2004-2021 Edward F. Valeev
3  *
4  *  This file is part of Libint.
5  *
6  *  Libint is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  Libint is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with Libint.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 #include <stdexcept>
25 #include <cassert>
26 #include <rr.h>
27 #include <integral.h>
28 #include <iter.h>
29 #include <algebra.h>
30 
31 #ifndef _libint2_src_bin_libint_intsettoints_h_
32 #define _libint2_src_bin_libint_intsettoints_h_
33 
34 namespace libint2 {
35 
36   /** IntegralSet_to_Integrals_base is dummy class used for dynamic casts only
37    */
38   class IntegralSet_to_Integrals_base {
39   protected:
~IntegralSet_to_Integrals_base()40     virtual ~IntegralSet_to_Integrals_base() {}
41   };
42 
43   /** IntegralSet_to_Integrals converts I, a set of integrals, to individual integrals. Although this is
44   technically not a recurrence relation, it can be treated as one.
45   */
46   template <class I>
47   class IntegralSet_to_Integrals : public RecurrenceRelation,
48     public IntegralSet_to_Integrals_base {
49   public:
50     typedef I TargetType;
51     typedef typename I::iter_type ChildType;
52     /// The type of expressions in which RecurrenceRelations result.
53     typedef RecurrenceRelation::ExprType ExprType;
54 
55     IntegralSet_to_Integrals(const SafePtr<I>&);
~IntegralSet_to_Integrals()56     virtual ~IntegralSet_to_Integrals() {}
57 
58     /// Return an instance if applicable, or a null pointer otherwise
Instance(const SafePtr<TargetType> & Tint,unsigned int dir)59     static SafePtr<IntegralSet_to_Integrals<I>> Instance(const SafePtr<TargetType>& Tint, unsigned int dir) {
60       assert(dir == 0);
61       // attempt to construct
62       SafePtr<IntegralSet_to_Integrals<I>> this_ptr(new IntegralSet_to_Integrals<I>(Tint));
63       // if succeeded (nchildren > 0) do post-construction
64       assert(this_ptr->num_children() != 0);
65       return this_ptr;
66     }
directional()67     static bool directional() { return false; }
68 
69 
70     /// Implementation of RecurrenceRelation::num_children()
num_children()71     unsigned int num_children() const override { return children_.size(); }
72     /// target() returns pointer to target
target()73     SafePtr<TargetType> target() const { return target_; };
74     /// child(i) returns pointer i-th child
75     SafePtr<ChildType> child(unsigned int i) const;
76     /// Implementation of RecurrenceRelation's target()
rr_target()77     SafePtr<DGVertex> rr_target() const override { return static_pointer_cast<DGVertex,TargetType>(target()); }
78     /// Implementation of RecurrenceRelation's child()
rr_child(unsigned int i)79     SafePtr<DGVertex> rr_child(unsigned int i) const override { return static_pointer_cast<DGVertex,ChildType>(child(i)); }
80     /// Implementation of RecurrenceRelation::is_simple()
is_simple()81     bool is_simple() const override {
82       return true;
83     }
84     /// Reimplementation of RecurrenceRelation::invariant_type()
invariant_type()85     bool invariant_type() const override {
86       // Converts from one BFSet to another!
87       return false;
88     }
89 
90   private:
91     SafePtr<TargetType> target_;
92     std::vector< SafePtr<ChildType> > children_;
93 
94     /// Implementation of RecurrenceRelation::generate_label()
generate_label()95     std::string generate_label() const override {
96       return "IntegralSet_to_Integrals";
97       //throw std::runtime_error("IntegralSet_to_Integrals::label() -- code for this RR is never generated, so this function should never be used");
98     }
99     /// Reimplementation of RecurrenceRelation::spfunction_call()
spfunction_call(const SafePtr<CodeContext> & context,const SafePtr<ImplicitDimensions> & dims)100     std::string spfunction_call(const SafePtr<CodeContext>& context,
101                                 const SafePtr<ImplicitDimensions>& dims) const override
102     {
103       throw std::logic_error("IntegralSet_to_Integrals::spfunction_call -- should not call this function");
104     }
105 
106   };
107 
108 
109   template <class I>
IntegralSet_to_Integrals(const SafePtr<I> & Tint)110     IntegralSet_to_Integrals<I>::IntegralSet_to_Integrals(const SafePtr<I>& Tint) :
111     target_(Tint)
112     {
113       target_ = Tint;
114 
115       // Construct a subiterator for I
116       SubIteratorBase<I> siter(Tint);
117 
118       // Set children pointers
119       for(siter.init(); siter; ++siter)
120         children_.push_back(siter.elem());
121     };
122 
123   template <class I>
124     SafePtr<typename I::iter_type>
child(unsigned int i)125     IntegralSet_to_Integrals<I>::child(unsigned int i) const
126     {
127       return children_.at(i);
128     };
129 
130 
131 };
132 
133 #endif
134 
135