21#ifndef _libint2_src_bin_libint_compderivgauss_h_
22#define _libint2_src_bin_libint_compderivgauss_h_
24#include <generic_rr.h>
38 std::set<std::pair<unsigned int, bool> > template_instances_;
42 void add(
unsigned int L,
bool vectorize);
62template <
class IntType,
int part, FunctionPosition where,
63 int trans_inv_part = -1, FunctionPosition trans_inv_where = InBra>
66 CR_DerivGauss<IntType, part, where, trans_inv_part, trans_inv_where>,
67 typename IntType::BasisFunctionType, IntType> {
69 static constexpr auto trans_inv_oper =
70 not IntType::OperType::Properties::odep;
73 static constexpr auto using_trans_inv =
74 trans_inv_oper && (part == trans_inv_part) && (where == trans_inv_where);
78 typedef typename IntType::BasisFunctionType BasisFunctionType;
79 typedef IntType TargetType;
87 static constexpr auto max_nchildren =
88 using_trans_inv ? (IntType::num_bf - 1) : 2u;
98 using ParentType::target_;
99 using ParentType::RecurrenceRelation::expr_;
100 using ParentType::RecurrenceRelation::nflops_;
104 CR_DerivGauss(
const std::shared_ptr<TargetType>&,
unsigned int dir);
106 static std::string descr() {
return "CR_DerivGauss"; }
111 std::string generate_label()
const override {
112 typedef typename TargetType::AuxIndexType
mType;
113 static std::shared_ptr<mType> aux0(
new mType(0u));
114 std::ostringstream os;
115 os << descr() <<
"P" << part <<
to_string(where)
116 << genintegralset_label(target_->bra(), target_->ket(), aux0,
121#if LIBINT_ENABLE_GENERIC_CODE
124 const std::shared_ptr<CompilationParameters>& cparams)
const override;
126 std::string generic_header()
const override;
128 std::string generic_instance(
129 const std::shared_ptr<CodeContext>& context,
130 const std::shared_ptr<CodeSymbols>& args)
const override;
134template <
class IntType,
int part, FunctionPosition where,
int trans_inv_part,
135 FunctionPosition trans_inv_where>
136CR_DerivGauss<IntType, part, where, trans_inv_part, trans_inv_where>::
137 CR_DerivGauss(
const std::shared_ptr<TargetType>& Tint,
unsigned int dir)
138 : ParentType(Tint, dir) {
139 using namespace libint2::algebra;
140 using namespace libint2::prefactor;
142 typedef BasisFunctionType F;
143 const F& _1 = unit<F>(
144 is_simple() ? dir : 0);
146 const typename IntType::AuxQuantaType& aux = Tint->aux();
147 const typename IntType::OperType& oper = Tint->oper();
153 if (where == InBra && Tint->bra(part, 0).deriv().d(dir) == 0)
return;
154 if (where == InKet && Tint->ket(part, 0).deriv().d(dir) == 0)
return;
159 if (not using_trans_inv) {
160 if (where == InBra && Tint->bra(part, 0).contracted())
return;
161 if (where == InKet && Tint->ket(part, 0).contracted())
return;
164 typedef typename IntType::BraType IBraType;
165 typedef typename IntType::KetType IKetType;
166 IBraType* bra =
new IBraType(Tint->bra());
167 IKetType* ket =
new IKetType(Tint->ket());
169 if (not using_trans_inv) {
171 if (where == InBra) {
172 F a(bra->member(part, 0));
175 F ap1(bra->member(part, 0) + _1);
176 ap1.deriv().dec(dir);
177 bra->set_member(ap1, part, 0);
178 auto int_ap1 = this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
179 bra->set_member(a, part, 0);
181 std::ostringstream oss;
182 oss <<
"two_alpha" << part <<
"_bra";
183 expr_ = Scalar(oss.str()) * int_ap1;
188 F am1(bra->member(part, 0) - _1);
190 am1.deriv().dec(dir);
191 bra->set_member(am1, part, 0);
193 this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
194 bra->set_member(a, part, 0);
196 expr_ -= Scalar(a[dir]) * int_am1;
203 if (where == InKet) {
204 F a(ket->member(part, 0));
207 F ap1(ket->member(part, 0) + _1);
208 ap1.deriv().dec(dir);
209 ket->set_member(ap1, part, 0);
210 auto int_ap1 = this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
211 ket->set_member(a, part, 0);
213 std::ostringstream oss;
214 oss <<
"two_alpha" << part <<
"_ket";
215 expr_ = Scalar(oss.str()) * int_ap1;
220 F am1(ket->member(part, 0) - _1);
222 am1.deriv().dec(dir);
223 ket->set_member(am1, part, 0);
225 this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
226 ket->set_member(a, part, 0);
228 expr_ -= Scalar(a[dir]) * int_am1;
237 if (where == InBra) bra->member(part, 0).deriv().dec(dir);
238 if (where == InKet) ket->member(part, 0).deriv().dec(dir);
241 for (
int p = 0; p != IntType::num_particles; ++p) {
242 if (p != trans_inv_part || trans_inv_where != InBra) {
243 F a(bra->member(p, 0));
244 if (not a.is_unit()) {
247 bra->set_member(da, p, 0);
249 this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
250 bra->set_member(a, p, 0);
252 std::ostringstream oss;
254 expr_ = Scalar(-1) * int_da;
262 if (p != trans_inv_part || trans_inv_where != InKet) {
263 F a(ket->member(p, 0));
264 if (not a.is_unit()) {
267 ket->set_member(da, p, 0);
269 this->
add_child(IntType::Instance(*bra, *ket, aux, oper));
270 ket->set_member(a, p, 0);
272 std::ostringstream oss;
274 expr_ = Scalar(-1) * int_da;
288#if LIBINT_ENABLE_GENERIC_CODE
289template <
class IntType,
int part, FunctionPosition where,
int trans_inv_part,
290 FunctionPosition trans_inv_where>
292 has_generic(
const std::shared_ptr<CompilationParameters>& cparams)
const {
294 if (using_trans_inv)
return false;
299 const unsigned int max_opt_am = cparams->max_am_opt();
300 unsigned int am_total = 0;
301 unsigned int nfunctions = 0;
302 const unsigned int np = IntType::OperType::Properties::np;
303 for (
unsigned int p = 0; p < np; p++) {
304 unsigned int nbra = target_->bra().num_members(p);
305 for (
unsigned int i = 0; i < nbra; i++) {
306 am_total += target_->bra(p, i).norm();
309 unsigned int nket = target_->ket().num_members(p);
310 for (
unsigned int i = 0; i < nket; i++) {
311 am_total += target_->ket(p, i).norm();
315 if (am_total > max_opt_am * nfunctions)
return true;
321template <
class IntType,
int part, FunctionPosition where,
int trans_inv_part,
322 FunctionPosition trans_inv_where>
323std::string
CR_DerivGauss<IntType, part, where, trans_inv_part,
324 trans_inv_where>::generic_header()
const {
325 return std::string(
"GenericGaussDeriv.h");
328template <
class IntType,
int part, FunctionPosition where,
int trans_inv_part,
329 FunctionPosition trans_inv_where>
333 const std::shared_ptr<CodeSymbols>& args)
const {
334 std::ostringstream oss;
336 oss <<
"using namespace libint2;" << std::endl;
338 BasisFunctionType sh(where == InBra ? target_->bra(part, 0)
339 : target_->ket(part, 0));
341 const unsigned int L = sh.norm();
342 const bool vectorize =
343 (context->cparams()->max_vector_length() == 1) ?
false : true;
344 oss <<
"libint2::GenericGaussDeriv<" << L <<
","
345 << (vectorize ?
"true" :
"false") <<
">::compute(inteval";
347 oss <<
"," << args->symbol(0);
348 const unsigned int nargs = args->n();
349 for (
unsigned int a = 1; a < nargs; a++) {
350 oss <<
"," << args->symbol(a);
353 if (nargs == 2) oss <<
",0";
356 unsigned int hsr = 1;
357 unsigned int lsr = 1;
358 const unsigned int np = IntType::OperType::Properties::np;
363 for (
int p = 0; p < static_cast<int>(np); p++) {
364 unsigned int nbra = target_->bra().num_members(p);
366 for (
unsigned int i = 0; i < nbra; i++) {
367 SubIterator* iter = target_->bra().member_subiter(p, i);
368 if (p < part || (p == part && where == InKet)) hsr *= iter->
num_iter();
370 if (p > part) lsr *= iter->
num_iter();
373 unsigned int nket = target_->ket().num_members(p);
375 for (
unsigned int i = 0; i < nket; i++) {
376 SubIterator* iter = target_->ket().member_subiter(p, i);
377 if (p < part) hsr *= iter->
num_iter();
379 if (p > part || (p == part && where == InBra)) lsr *= iter->
num_iter();
383 oss <<
"," << hsr <<
"," << lsr;
386 oss <<
"," << this->dir();
389 oss <<
",inteval->two_alpha" << part <<
"_"
390 << (where == InBra ?
"bra" :
"ket");
394 CR_DerivGauss_GenericInstantiator::instance().add(L, vectorize);
Definition comp_deriv_gauss.h:30
Compute relation for (geometric) derivative Gaussian ints of generic type IntType .
Definition comp_deriv_gauss.h:67
static bool directional()
always directional! Cartesian derivatives are applied in a particular direction
Definition comp_deriv_gauss.h:94
RRImpl must inherit GenericRecurrenceRelation<RRImpl>
Definition generic_rr.h:47
bool is_simple() const override
Implementation of RecurrenceRelation::is_simple()
Definition generic_rr.h:81
const std::shared_ptr< DGVertex > & add_child(const std::shared_ptr< DGVertex > &child)
add child
Definition generic_rr.h:109
static std::shared_ptr< RRImpl > Instance(const std::shared_ptr< TargetType > &Tint, unsigned int dir)
Return an instance if applicable, or a null pointer otherwise.
Definition generic_rr.h:55
Iterator provides a base class for all object iterator classes.
Definition iter.h:43
virtual unsigned int num_iter() const =0
Returns a number of iterations (number of elements in a set over which to iterate).
these objects help to construct BraketPairs
Definition src/bin/libint/braket.h:275
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition bfset.h:96
DefaultQuantumNumbers< unsignedint, 1 >::Result mType
mType is the type that describes the auxiliary index of standard 2-body repulsion integrals
Definition quanta.h:395
std::string to_string(const T &x)
Converts x to its string representation.
Definition entity.h:121
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition bfset.h:906