References
IFGF.ACOUSTIC_SIZE_THRESHOLD — Constantconst ACOUSTIC_SIZE_THRESHOLDBoxes with a size larger than ACOUSTIC_SIZE_THRESHOLD times the wavelength are considered "high-frequency", and their cone-domain size will be refined.
IFGF.SAME_POINT_TOLERANCE — Constantconst SAME_POINT_TOLERANCE = 1e-12For singular kernels, two points are considered the same if their distance is less than SAME_POINT_TOLERANCE.
IFGF.AbstractPDE — Typeabstract type AbstractPDE{N}A partial differential equation in dimension N. AbstractPDE types are used to define PDEKernels.
IFGF.AbstractSplitter — Typeabstract type AbstractSplitterAn AbstractSplitter is used to split a ClusterTree. The interface requires the following methods:
should_split(clt,splitter): return aBooldetermining if theClusterTreeshould be further dividedsplit!(clt,splitter): perform the splitting of theClusterTreehandling the necessary data sorting.
See DyadicSplitter for an example of an implementation.
IFGF.AdmissibilityCondition — Typestruct AdmissibilityConditionFunctor used to determine if the interaction between a target and a source can be approximated using an interpolation scheme.
A target and source are admissible under this admissiblility condition if the target box lies farther than r*η away, where r is the radius of the source box and η >= 1 is an adjustable parameter. In dimension N, the default choice is η = √N.
IFGF.ClusterTree — Typemutable struct ClusterTree{T,S,D}Tree structure used to cluster elements of type V = eltype(T) into containers of type S. The method center(::V)::SVector is required for the clustering algorithms. An additional data field of type D can be associated with each node to store node-specific information (it defaults to D=Nothing).
Fields:
_elements::T: vector containing the sorted elements.container::S: container for the elements in the current node.index_range::UnitRange{Int}: indices of elements contained in the current node.loc2glob::Vector{Int}: permutation from the local indexing system to the original (global) indexing system used as input in the construction of the tree.children::Vector{ClusterTree{N,T,D}}parent::ClusterTree{N,T,D}data::D: generic data field of typeD.
IFGF.ClusterTree — MethodClusterTree(elements,splitter;[copy_elements=true])
ClusterTree{D}(points,splitter;[copy_elements=true])Construct a ClusterTree from the given elements using the splitting strategy encoded in splitter. If copy_elements is set to false, the elements argument are directly stored in the ClusterTree and are permuted during the tree construction.
IFGF.ConeDomainSize — Typestruct ConeDomainSizeUse ConeDomainSize(k,ds) to create a function that computes the appropriate meshsize for a given ClusterTree based on the wavenumber k and the reference meshsize ds.
Calling f(node) will return the meshsize for the given node, where f is a ConeDomainSize object.
IFGF.DyadicMaxDepthSplitter — Typestruct DyadicMaxDepthSplitter <: AbstractSplitterSimilar to DyadicSplitter, but splits nodes until a maximum depth is reached.
See also: AbstractSplitter
IFGF.DyadicMinimalSplitter — Typestruct DyadicMinimalSplitter <: AbstractSplitterSimilar to DyadicSplitter, but the boundin boxes are shrank to the minimal axis-aligned boxes at the end.
See also: AbstractSplitter
IFGF.DyadicSplitter — Typestruct DyadicSplitter <: AbstractSplitterUsed to split an N dimensional ClusterTree into 2^N children until at most nmax points are contained in node.
See also: AbstractSplitter
IFGF.Helmholtz — Typestruct Helmholtz{N, T}Helmholtz equation in N dimension: Δu + k²u= 0. k is the wavenumber of numeric type T.
IFGF.HyperRectangle — Typestruct HyperRectangle{N,T}Axis-aligned hyperrectangle in N dimensions given by low_corner::SVector{N,T} and high_corner::SVector{N,T}. By default, T is Float64.
IFGF.HyperRectangle — MethodHyperRectangle(lc,hc)Construct an axis-aligned hyperrectangle with low-corner lc and high-corner hc.
It is recommended that lc and hc be of type SVector or Tuple to avoid type instabilities.
julia> IFGF.HyperRectangle((0.0, 0.0), (1.0, 2.0))
IFGF.HyperRectangle{2, Float64}([0.0, 0.0], [1.0, 2.0])IFGF.IFGFOp — Typestruct IFGFOp{T} <: AbstractMatrix{T}High-level structure representing a linear operator with elements of type T and i,j entry given by K(X[i],Y[j]), where K is the underlying kernel function, and X and Y are the elements of the target_tree and source_tree, respectively.
Fields:
kernel: underlying kernel functiontarget_tree: tree structure used for clustering the target pointssource_tree: tree structure used for clustering the source pointsp::NTuple: number of chebyshev poins per dimension used in the interpolation of far interactionsh::NTuple: meshsize in parameter (per dimension) of the largest cones
IFGF.Laplace — Typestruct Laplace{N}Laplace equation in N dimension: Δu = 0.
IFGF.MulBuffer — Typestruct MulBuffer{T}Low-level structure used to hold the interpolation coefficients and values of the current and next level cone interpolants.
The type paramter T is the type of the interpolant.
IFGF.PDEKernel — Typeabstract type PDEKernel{Op}A kernel function associated a Green function (or derivatives of) a partial differential equation.
IFGF.SourceTree — Typeconst SourceTree{T,S,D}Type alias for a ClusterTree with a data field D of type SourceTreeData.
IFGF.SourceTreeData — Typemutable struct SourceTreeData{N,T,S}Struct used to store data associated with a node of the SourceTree. The parametric type N represents the ambient dimension, T represents the primitive type used to represent the points (e.g. Float32 or Float64 for single/double precision), and S is the type of node in the near and far field.
Fields:
msh: uniform cartesian mesh of the interpolation space, indexable by aCartesianIndexconedatadict: dictionary mapping a cone tagI::CartesianIndexto the index range of the interpolation points owned by that conefarlist: nodes on the target tree that can be evaluated through interpolationnearlist: nodes on the target tree that must be evaluated by a direct sum.
IFGF.Stokes — Typestruct Stokes{N}Stokes equation in N dimension.
IFGF.TargetTree — Typeconst TargetTree{T,S,D}Type alias for a ClusterTree with a data field D of type TargetTreeData.
IFGF.TargetTreeData — Typestruct TargetTreeDataStruct used to store data associated with a node of the TargetTree. Currently there is nothing there, but maybe one day there will be a downward pass in the target tree, and it will need some fields to store data.
IFGF.UniformCartesianMesh — Typestruct UniformCartesianMesh{N,T} <: AbstractMesh{N,T}An N-dimensional cartesian grid given as the tensor-product of N one-dimensional LinRange{T} grids.
Iterating over a UniformCartesianMesh generates the elements which compose the mesh; i.e. the HyperRectangle cells.
IFGF.UniformCartesianMesh — MethodUniformCartesianMesh(domain::HyperRectangle,sz::NTuple)
UniformCartesianMesh(domain::HyperRectangle;step::NTuple)Construct a uniform UniformCartesianMesh with sz[d] elements along dimension d. If the kwarg step is passed, construct a UniformCartesianMesh with elements of approximate size step.
Base.split — Methodsplit(rec::HyperRectangle[, axis::Int, place])Split a hyperrectangle in two along the axis direction at the position place. Returns a tuple with the two resulting hyperrectangles.
When no place is given, defaults to splitting in the middle of the axis.
When no axis and no place are given, defaults to splitting along the largest axis.
Base.union — Methodunion(r1::HyperRectangle,r2::HyperRectangle)Smallest HyperRectangle that contains both r1 and r2.
IFGF._addnewcone! — Method_addnewcone!(node::SourceTree,I::CartesianIndex[, lock])If node does not contain cone I, add it to the conedict. Does not set the indices of the interpolation data owned by the cone.
If lock is passed, the operation is thread-safe.
IFGF._binary_split! — Method_binary_split!(cluster::ClusterTree,dir,pos;parentcluster=cluster)
_binary_split!(cluster::ClusterTree,f;parentcluster=cluster)Split a ClusterTree into two, sorting all elements in the process. For each resulting child assign child.parent=parentcluster.
Passing a dir and pos arguments splits the container of node along direction dir at position pos, then sorts all points into the resulting left/right nodes.
If passed a predicate f, each point is sorted according to whether f(x) returns true (point sorted on the left node) or false (point sorted on the right node). At the end a minimal HyperRectangle containing all left/right points is created.
IFGF._compute_cone_list! — Method_compute_cone_list!(partition, p, ds_func)For each node in partition, compute the cones which are necessary to cover both the target points on its farlist as well as the interpolation points on its parent's cones. p denotes the number of interpolation points per dimension, and ds_func(node) gives the meshsize of the domain in interpolation-space for node.
IFGF._compute_interaction_list! — Method_compute_interaction_list!(source, target, adm)For each node in source, compute its nearlist and farlist. The nearlist contains all nodes in target for which the interaction must be computed using the direct summation. The farlist includes all nodes in target_tree for which an accurate interpolant in available in the source node.
The adm function is called through adm(target,source) to determine if target is in the farlist of source. When that is not the case we recurse on their children unless both are a leaves, in which case target is added to the nearlist of source.
IFGF._density_type_from_kernel_type — Method_density_type_from_kernel_type(T)Helper function to compute the expected density V type associated with a kernel type T. For T<:Number, simply return T. For T<:SMatrix, return an SVector with elements of the type eltype(T) and of length size(T,2) so that multiplying an element of type T with an element of type V makes sense.
IFGF._forward_map! — Function_forward_map!(out, L, c, v, grad)Execute the plan of _plan_forward_map and store the result in out.
IFGF._init_msh! — Method_init_msh!(node,domain,ds)Create a uniform cartesian mesh of the interpolation domain of node with element spacing ds.
IFGF._plan_forward_map — Method_plan_forward_map(pde, targets, sources, c, v, grad; kwargs...)Assemble the IFGFOp for the forward map given by the sum
\[u(\boldsymbol{x}_i) = \sum_{j=1}^N G(\boldsymbol{x}_i - \boldsymbol{y}_j) c_j + \gamma_{1,\boldsymbol{y}} G(\boldsymbol{x}_i - \boldsymbol{y}_j) v_j,\]
where $G$ is a Green's function of the PDE, $\gamma_{1,\boldsymbol{y}}$ its generalized Neumann trace respect to the $\boldsymbol{y}$ variable, $c_j$ denotes the value of x[j], and $v_j$ denotes the value of v[j]. If grad=true, the gradient of the expression is computed instead. Either c or v can be nothing, in which case the corresponding term is skipped in the sum.
This function handles the logic needed to determine the appropriate kernel function, as well values of p (number of interpolation points) and h (cone meshsize), and then forwards the keyword arguments to assemble_ifgf.
IFGF._unsafe_wrap_vector_of_sarray — Method_unsafe_wrap_vector_of_sarray(A::Array)Wrap the memory in A so that its first n-1 dimensions are interpreted as an SArray, returning a Vector{<:SArray} type.
This function uses unsafe_wrap, and therefore is unsafe for the same reasons unsafe_wrap is.
IFGF.assemble_ifgf — Methodassemble_ifgf(K, X, Y; tol, nmax=250)
assemble_ifgf(K, X, Y; p, h, nmax=250)Construct an approximation of the matrix [K(x,y) for x ∈ X, y ∈ Y] using the interpolated factored Green function method. The parameter tol specifies the desired (relative) error in Frobenius norm of the approximation, and nmax gives the maximum number of points in a leaf of the dyadic trees used.
The kernel K must implement wavenumber(::typeof(K)) --> Number to return the kernel's (typical) wavenumber; for non-oscillatory kernels this is zero.
When tol is passed, the number of interpolation points per dimension, p, and the meshsize h is estimated based on some heuristic. If you know in advance a good value of p and h for you function K and desired tolerance, it is suggested you pass that as a keyword argument instead.
IFGF.bounding_box — Functionbounding_box(els[, cube=false])Compute a HyperRectangle that contains the center of all elements in els. If cube==true, the result is a square/cube instead.
Works for any type that implements center.
IFGF.cart2interp — Methodcart2interp(x,c,h)
cart2interp(x,source::SourceTree)Map cartesian coordinates x into interpolation coordinates s centered at c and scaled by h. Interpolation coordinates are similar to hyperspherical coordinates (e.g. polar in two-dimensions and spherical in three-dimensions), except that the radial coordinates is replaced by s=h/r.
If passed a SourceTree, use its center and radius as c and h respectively.
IFGF.center — Methodcenter(Ω)Center of the smallest ball containing Ω.
IFGF.centered_factor — Methodcentered_factor(K,x,Y::SourceTree)Return a representative scalar value of K(x,y) for y ∈ Y. This is used to help the interpolation of I(x) = ∑ᵢ K(x,yᵢ) where yᵢ ∈ Y and points x in the far field of Y. Defaults to K(x,yc) where yc is the center of Y.
IFGF.cheb_error_estimate — Methodcheb_error_estimate(coefs::AbstractArray{T,N},dim)Given an N dimensional array of coefficients , estimate the relative error commited by the Chebyshev interpolant along dimension dim.
IFGF.chebeval — Methodchebeval(coefs,x,rec[,sz])Evaluate the Chebyshev polynomial defined on rec with coefficients given by coefs at the point x. If the size of coefs is known statically, its size can be passed as a Val using the sz argument.
IFGF.chebnodes — Methodchebnodes(n,[domain])
chebnodes(p::NTuple,[domain])
chebnodes(::Val{P},[domain])Return the n Chebyshev nodes of the second kind on the interval [-1,1].
If passed a tuple p, return the tensor product of one-dimensinal nodes of size p.
If passed a Val{P}, statically compute the tensor product nodes.
Finally, passing a domain::HyperRectangle shifts the interpolation nodes to it.
lb = (0.,0.)
ub = (3.,2.)
domain = HyperRectangle(lb,ub)
chebnodes((10,5),domain) # generate `10×5` Chebyshev nodes on the `[0,3]×[0,2]` rectangle.IFGF.chebtransform_fftw! — Methodchebtransform_fftw!(vals::AbstractArray[, plan])Given a function values on the chebnodes(p), where p=size(vals), compute the Chebyshev coefficients in-place. The underlying implementation uses the FFTW library. A pre-computed plan::FFTW.FFTWPlan should be passed for efficiency.
IFGF.chebtransform_native! — Functionchebtransform_native!(vals)Compute the Chebyshev coefficients given the values of a function on the Chebyshev nodes of the second kind (i.e. the extrema of the Chebyshev polynomials Tₙ). The result is written in-place.
IFGF.cone_index — Methodcone_index(x::SVector,tree::SourceTree)Given a point x in cartesian coordinates, return the index I of the cone in source to which x belongs, as well as its parametric coordinate s.
See also: cart2interp
IFGF.container — Methodcontainer(clt::ClusterTree)Return the object enclosing all the elements of the clt.
IFGF.container_type — Methodcontainer_type(clt::ClusterTree)Type used to enclose the elements of clt.
IFGF.coords — Methodcoords(x)Return an SVector with the cartesian coordinates associated to a geometrical object x.
IFGF.decrement_index — Functiondecrement_index(I::CartesianIndex,k[,n=1])Equivalent to increment_index(I,k,-n)
IFGF.depth — Functiondepth(tree,acc=0)Recursive function to compute the depth of node in a a tree-like structure.
Overload this function if your structure has a more efficient way to compute depth (e.g. if it stores it in a field).
IFGF.diameter — Methoddiameter(Ω)Largest distance between x and y for x,y ∈ Ω.
IFGF.distance — Methoddistance(X::ClusterTree, Y::ClusterTree)Distance between the containers of X and Y.
IFGF.distance — Methoddistance(Ω₁,Ω₂)Minimal Euclidean distance between a point x ∈ Ω₁ and y ∈ Ω₂.
IFGF.distance — Methoddistance(x::SVector,r::HyperRectangle)The (minimal) Euclidean distance between the point x and any point y ∈ r.
IFGF.element_index — Methodelement_index(s::SVector,m::UniformCartesianMesh)Given a point s ∈ m, return the index I of the element in m containing s.
IFGF.element_index_for_point — Methodelement_index_for_point(p::SVector,m::UniformCartesianMesh)Given a point p, return the index I of the element in m containing p.
IFGF.element_type — Methodelement_type(clt::ClusterTree)Type of elements sorted in clt.
IFGF.elements — Methodelements(clt::ClusterTree)Iterable list of the elements inside clt.
IFGF.float_type — Methodfloat_type(x)Floating type used to represent the underlying structure (e.g. Float32, Float64).
IFGF.glob2loc — Methodglob2loc(clt::ClusterTree)The inverse of loc2glob(clt).
IFGF.helmholtz3d — Methodhelmholtz3d(k, targets, sources; charges = nothing, dipvecs = nothing, grad =
false, kwargs...)Compute the sum
\[u(\boldsymbol{x}_i) = \sum_{j=1}^n \frac{c_j e^{i k || \boldsymbol{x}_i - \boldsymbol{y}_j ||}}{|| \boldsymbol{x}_i - \boldsymbol{y}_j ||} + \nabla_{\boldsymbol{y}}^\top \left( \frac{e^{i k || \boldsymbol{x}_i - \boldsymbol{y}_j ||}}{|| \boldsymbol{x}_i - \boldsymbol{y}_j ||} \right) v_j,\]
where $c_j$ are the charges and v_j are the dipvecs.
Input:
k: the wavenumber.targets::Matrix{T}:3 x nmatrix of target points.sources::Matrix{T}:3 x mmatrix of source points.charges::Vector{Complex{T}}: vector ofncharges.dipvecs::Matrix{Complex{T}}:3 x mmatrix of dipole vectors.grad::Bool: iftrue, the gradient is computed insteadkwargs...: additional keyword arguments passed toassemble_ifgf.
Output
u: the potential at the target points ifgrad=false, or the gradient as a3 x nmatrix ifgrad=true.
IFGF.increment_index — Functionincrement_index(I::CartesianIndex,k[,n=1])Increment I by n along the dimension k. This is equivalent to I += n*eₖ, where eₖ is a vector with with 1 at the k-th coordinate and zeros elsewhere.
IFGF.index_range — Methodindex_range(clt::ClusterTree)Indices of elements in root_elements(clt) which lie inside clt.
IFGF.interp2cart — Methodinterp2cart(s,xc,h)
interp2cart(s,source::SourceTree)Map interpolation coordinate s into the corresponding cartesian coordinates.
Interpolation coordinates are similar to polar (in 2d) or spherical (in 3d) coordinates centered at the xc, except that the radial coordinate r is replaced by s = h/r.
If passed a SourceTree as second argument, call interp2cart(s,xc,h) with xc the center of the SourceTree and h its radius.
IFGF.interpolation_domain — Methodinterpolation_domain(source::SourceTree)Compute the domain (as a HyperRectangle) in interpolation space for which source must provide a covering through its cone interpolants.
IFGF.inv_centered_factor — Methodinv_centered_factor(K,x,Y)Inverse of centered_factor.
IFGF.laplace3d! — Methodlaplace3d!(out, L::IFGFOp; charges = nothing, dipvecs = nothing, grad =
false)In-place version of laplace3d.
IFGF.laplace3d — Methodlaplace3d(targets, sources; charges = nothing, dipvecs = nothing, grad =
false, kwargs...)Compute the sum
\[u(\boldsymbol{x}_i) = \sum_{j=1}^n \frac{c_j}{|| \boldsymbol{x}_i - \boldsymbol{y}_j ||} - \frac{(\boldsymbol{x}_i - \boldsymbol{y}_j)^\top v_j}{|| \boldsymbol{x}_i - \boldsymbol{y}_j ||^3} ,\]
where $c_j$ are the charges and v_j are the dipvecs.
Input:
targets::Matrix{T}:3 x nmatrix of target points.sources::Matrix{T}:3 x mmatrix of source points.charges::Vector{T}: vector ofncharges.dipvecs::Matrix{T}:3 x mmatrix of dipole vectors.grad::Bool: iftrue, the gradient is computed insteadkwargs...: additional keyword arguments passed toassemble_ifgf(e.g.tol)
Output
u: the potential at the target points ifgrad=false, or the gradient as a3 x nmatrix ifgrad=true.
IFGF.loc2glob — Methodloc2glob(clt::ClusterTree)The permutation from the (local) indexing system of the elements of the clt to the (global) indexes used upon the construction of the tree.
IFGF.near_interaction! — Methodnear_interaction!(C,K,X,Y,σ,I,J)Compute C[i] <-- C[i] + ∑ⱼ K(X[i],Y[j])*σ[j] for i ∈ I, j ∈ J. The default implementation simply does a double loop over all i ∈ I and j ∈ J: override this method for the type of your own custom kernel K if you have a fast way of computing the full product in-place (e.g. using SIMD instructions).
IFGF.partition_by_depth — Methodpartition_by_depth(tree)Given a tree, return a partition vector whose i-th entry stores all the nodes in tree with depth=i-1. Empty nodes are not added to the partition.
IFGF.plan_laplace3d — Methodplan_laplace3d(targets, sources; charges = nothing, dipvecs = nothing, grad =
false, kwargs...)Similar to laplace3d, but returns a plan in the form of an IFGFOpobject instead of the result. Callinglaplace3dwithplan` as the first argument will then compute the result.
IFGF.radius — Methodradius(Ω)Half the diameter.
IFGF.real_and_imag — Methodreal_and_imag(v)Return a view over the real and imaginary parts of a complex vector v.
julia> v = [1.0 + 2.0im, 3.0 + 4.0im];
julia> vr,vi = IFGF.real_and_imag(v)
([1.0, 3.0], [2.0, 4.0])IFGF.return_type — Methodreturn_type(f[,args...])The type returned by f(args...), where args is a tuple of types. Falls back to Base.promote_op by default.
A functors of type T with a known return type should extend return_type(::T,args...) to avoid relying on promote_op.
IFGF.root_elements — Methodroot_elements(clt::ClusterTree)The elements contained in the root of the tree to which clt belongs.
IFGF.section — Methodsection(rec::HyperRectangle{D},ax)Return the dimension D-1 HyperRectangle obtained by deleting the coordinates at the ax dimension.
IFGF.share_interp_data — Functionshare_interp_data(mode=true)If set to true, neighboring cone interpolants will share their interpolation data (which are, in this case, computed only once).
IFGF.should_split — Methodshould_split(clt::ClusterTree, depth, splitter::AbstractSplitter)Determine whether or not a ClusterTree should be further divided.
IFGF.split! — Methodsplit!(clt::ClusterTree,splitter::AbstractSplitter)Divide clt using the strategy implemented by splitter. This function is reponsible of assigning the children and parent fields, as well as of permuting the data of clt.
IFGF.stokes3d — Methodstokes3d(targets, sources; stoklet = nothing, strslet = nothing, strsvec =
nothing, grad = false, kwargs...)Compute the sum
\[u(\boldsymbol{x}_i) = \sum_{j=1}^n \left( \frac{I}{d} + \frac{\boldsymbol{r}_{ij}\boldsymbol{r}_{ij}^\top}{2d_{ij}^3} \right) \boldsymbol{\sigma}_j + \frac{3(\boldsymbol{\nu}_j \cdot \boldsymbol{r}_{ij})(\boldsymbol{\mu}_j\cdot\boldsymbol{r}_{ij}) \boldsymbol{r}_{ij}}{d_{ij}^5},\]
where $\boldsymbol{r}_{ij} = |\boldsymbol{x}_i - \boldsymbol{y}_j|$, $d_{ij} = |\boldsymbol{r_{ij}}|$, $\boldsymbol{\sigma}_j$ are the Stokeslet strengths, $\boldsymbol{\mu}_j$ are the stresslet strengths, and $\boldsymbol{\nu}_j$ are the stresslet orientations.
Input:
targets::Matrix{T}:3 x nmatrix of target points.sources::Matrix{T}:3 x mmatrix of source points.stoklet::Matrix{T}:3 × nmatrix of stokesletsstrslet::Matrix{T}:6 x mmatrix of stresslet densities (indices1:3) and orientations (indices4:6)grad::Bool: iftrue, the gradient is computed insteadkwargs...: additional keyword arguments passed toassemble_ifgf.
Output
u:3 x nmatrix giving the velocity at the target points ifgrad=false, or3 x 3 × nmatrix representing the gradient ofuifgrad=true.
IFGF.svector — Methodsvector(f,n)Create an SVector of length n, computing each element as f(i), where i ∈ 1:n.
IFGF.transfer_factor — Methodtransfer_factor(K,x,Y::SourceTree)Ratio between the centered factor of Y and the centered factor of its parent.
IFGF.use_fftw — Functionuse_fftw(mode=true)Use the FFTW library for computing the Chebyshev transform.
IFGF.use_minimal_conedomain — Functionuse_minimal_conedomain(mode=true)If set to true, the minimal domain for the cone interpolants will be used by calling interpolation_domain during the contruction of the active cones.
While setting this to true reduces the memory footprint by creating fewer cones, it also increases the time to assemble the IFGFOperator.
IFGF.usethreads — Functionusethreads(mode=true)Enable/disable thread usage globally for the IFGF module.
IFGF.wavenumber — Functionwavenumber(K::Function)For oscillatory kernels, return the characteristic wavenumber (i.e 2π divided by he wavelength). For non-oscillatory kernels, return 0.
LinearAlgebra.mul! — Methodmul!(y,A::IFGFOp,x,a,b;global_index=true)Setting global_index=false uses the internal indexing system of the IFGFOp, and therefore does not permute the vectors x and y to perform the multiplication.