# Integrands

The design of AutoBZCore.jl uses multiple dispatch to provide multiple interfaces for user integrands that allow various optimizations to be compatible with a common interface for solvers. Unfortunately, not all algorithms support all integrands, since the underlying libraries must support the same interface.

# Functions

A user can pass an integrand of the form f(x,p) in the same way as in Integrals.jl

# ParameterIntegrand

AutoBZCore.ParameterIntegrandType
ParameterIntegrand(f, args...; kwargs...)

Represent an integrand with a partial collection of parameters p. When the ParameterIntegrand is invoked with one argument, e.g. int(x), it evaluates f(x, p...; kwargs...). However when invoked with two arguments, as in an IntegralProblem, e.g. int(x, p2), it evaluates the union of parameters f(x, p..., p2...; kwargs...). This allows for convenient parametrization of the integrand.

# InplaceIntegrand

AutoBZCore.InplaceIntegrandType
InplaceIntegrand(f!, result::AbstractArray)

Constructor for a InplaceIntegrand accepting an integrand of the form f!(y,x,p). The caller also provides an output array needed to store the result of the quadrature. Intermediate y arrays are allocated during the calculation, and the final result is may or may not be written to result, so use the IntegralSolution immediately after the calculation to read the result, and don't expect it to persist if the same integrand is used for another calculation.

# BatchIntegrand

AutoBZCore.BatchIntegrandType
BatchIntegrand(f!, y::AbstractArray, x::AbstractVector, max_batch=typemax(Int))

Constructor for a BatchIntegrand accepting an integrand of the form f!(y,x,p) = y .= f!.(x, Ref(p)) that can evaluate the integrand at multiple quadrature nodes using, for example, threads, the GPU, or distributed-memory. The max_batch keyword is a soft limit on the number of nodes passed to the integrand. The buffers y,x must both be resize!-able since the number of evaluation points may vary between calls to f!.

# FourierIntegrand

AutoBZCore.FourierIntegrandType
FourierIntegrand(f, w::FourierWorkspace, args...; kws...)

Constructs an integrand of the form f(FourierValue(x,w(x)), args...; kws...) where the Fourier series in w is evaluated efficiently, i.e. one dimension at a time, with compatible algorithms. f should accept parameters as arguments and keywords, similar to a ParameterIntegrand although the first argument to f will always be a FourierValue.

FourierIntegrand(f, s::AbstractFourierSeries, args...; kws...)

Outer constructor for FourierIntegrand that wraps the Fourier series s into a single-threaded FourierWorkspace.

# NestedBatchIntegrand

AutoBZCore.NestedBatchIntegrandType
NestedBatchIntegrand(f::Tuple, y::AbstractVector, x::AbstractVector, max_batch::Integer)

An integrand type intended for multi-threaded evaluation of NestedQuad. The caller provides a tuple f of worker functions that can evaluate the same integrand on different threads, so as to avoid race conditions. These workers can also be NestedBatchIntegrands depending on if the user wants to parallelize the integration at multiple levels of nesting. The other arguments are the same as for BatchIntegrand.