Octopus
sturm_liouville_oct_m Module Reference

General Sturm-Liouville solver for equations of the form \( \nabla \cdot (\rho \nabla v) = \text{rhs} \). More...

Detailed Description

General Sturm-Liouville solver for equations of the form \( \nabla \cdot (\rho \nabla v) = \text{rhs} \).

This module provides a general solver that can be called from any context (e.g. FBE exchange or other force-based approaches). It solves the Sturm-Liouville equation for a fixed right hand side and a given weight function \( \rho \). In the force based context \( \rho \) is the density, but this module is agnostic to the actual meaning of \( \rho \).

For force based functionals the right hand side is typically the divergence of a force density \( - \nabla \cdot \vec{F} \), INCLUDING the negative sign. This is solved by the subroutine sturm_liouville_solve_from_div.

The operator \( A v = \nabla \cdot (\rho \nabla v) \) is re-express as \( A v = \frac{1}{2} \left[ \nabla^2(\rho v) - v \nabla^2 \rho + \rho \nabla^2 v \right] \), because \div(\grad(f)) is not equal to \lapl(f) with finite differences. It is solved with a preconditioned QMR algorithm.

Data Types

type  sturm_liouville_t
 

Functions/Subroutines

subroutine, public sturm_liouville_init (this, namespace, gr, space, max_iter, thr, inverse_tol)
 Initialize the Sturm-Liouville solver. More...
 
subroutine, public sturm_liouville_end (this)
 Finalize the Sturm-Liouville solver. More...
 
subroutine, public sturm_liouville_solve_poisson (this, psolver, namespace, f, v, with_inverse_density, rho)
 Solves \( \nabla^2 v = \nabla \cdot \frac{\vec{F}}{\rho} \) Initial guess for the Sturm-Liouville solver: Poisson solution. More...
 
subroutine, public sturm_liouville_solve (this, namespace, rho, rhs, v)
 Solve the Sturm-Liouville equation with a scalar right-hand side. More...
 
subroutine, public sturm_liouville_solve_from_div (this, namespace, rho, f, v, psolver)
 Solve the Sturm-Liouville equation from a divergence. More...
 
subroutine sl_operator (x, hx, userdata)
 Computes \( Ax = \nabla \cdot (\rho \nabla x) \). More...
 
subroutine jacobi_preconditioner (x, hx, userdata)
 Jacobi preconditioner: approximates \( (\nabla \cdot [\rho \nabla])^{-1} \). More...
 

Function/Subroutine Documentation

◆ sturm_liouville_init()

subroutine, public sturm_liouville_oct_m::sturm_liouville_init ( type(sturm_liouville_t), intent(inout)  this,
type(namespace_t), intent(in)  namespace,
type(grid_t), intent(in), target  gr,
type(space_t), intent(in)  space,
integer, intent(in), optional  max_iter,
real(real64), intent(in), optional  thr,
real(real64), intent(in), optional  inverse_tol 
)

Initialize the Sturm-Liouville solver.

Sets up the Laplacian stencil needed for the preconditioner. Must be called before sturm_liouville_solve.

Definition at line 186 of file sturm_liouville.F90.

◆ sturm_liouville_end()

subroutine, public sturm_liouville_oct_m::sturm_liouville_end ( type(sturm_liouville_t), intent(inout)  this)

Finalize the Sturm-Liouville solver.

Definition at line 227 of file sturm_liouville.F90.

◆ sturm_liouville_solve_poisson()

subroutine, public sturm_liouville_oct_m::sturm_liouville_solve_poisson ( type(sturm_liouville_t), intent(inout), target  this,
type(poisson_t), intent(in)  psolver,
type(namespace_t), intent(in)  namespace,
real(real64), dimension(:,:), intent(in)  f,
real(real64), dimension(:), intent(inout)  v,
logical, intent(in), optional  with_inverse_density,
real(real64), dimension(:), intent(in), optional, target  rho 
)

Solves \( \nabla^2 v = \nabla \cdot \frac{\vec{F}}{\rho} \) Initial guess for the Sturm-Liouville solver: Poisson solution.

Parameters
[in]f(np, dim)
[in,out]v(np)
[in]with_inverse_densityDefault: true
[in]rho(np_part)

Definition at line 247 of file sturm_liouville.F90.

◆ sturm_liouville_solve()

subroutine, public sturm_liouville_oct_m::sturm_liouville_solve ( type(sturm_liouville_t), intent(inout), target  this,
type(namespace_t), intent(in)  namespace,
real(real64), dimension(:), intent(in), target, contiguous  rho,
real(real64), dimension(:), intent(in), contiguous  rhs,
real(real64), dimension(:), intent(inout), contiguous  v 
)

Solve the Sturm-Liouville equation with a scalar right-hand side.

Solves \( \nabla \cdot (\rho \nabla v) = \text{rhs} \)

Parameters
[in]rhoThe weight function \rho, must be defined on grnp_part points
[in]rhsThe right-hand side, defined on grnp points
[in,out]vOn input: initial guess. On output: solution.
[in]rho(np_part)
[in]rhs(np)
[in,out]v(np)

Definition at line 320 of file sturm_liouville.F90.

◆ sturm_liouville_solve_from_div()

subroutine, public sturm_liouville_oct_m::sturm_liouville_solve_from_div ( type(sturm_liouville_t), intent(inout), target  this,
type(namespace_t), intent(in)  namespace,
real(real64), dimension(:), intent(in), target, contiguous  rho,
real(real64), dimension(:,:), intent(in), contiguous  f,
real(real64), dimension(:), intent(inout), contiguous  v,
type(poisson_t), intent(in), optional  psolver 
)

Solve the Sturm-Liouville equation from a divergence.

Given a vector density \(\vec{F}\), computes \(\text{rhs} = -\nabla \cdot \vec{F} \) and then solves \( \nabla \cdot (\rho \nabla v) = -\nabla \cdot \vec{F} \)

Note
Sign convention: the right-hand side is negated
Parameters
[in]rhoThe weight function \rho (np_part)
[in]fThe force density F (np_part, dim)
[in,out]vOutput potential (np)
[in]psolver(Optional) Poisson solution as the initial guess for v
[in]rho(np_part)
[in]f(np_part, dim)
[in,out]v(np)
[in]psolverPoisson solver for the initial guess

Definition at line 373 of file sturm_liouville.F90.

◆ sl_operator()

subroutine sturm_liouville_oct_m::sl_operator ( real(real64), dimension(:), intent(in), contiguous  x,
real(real64), dimension(:), intent(out), contiguous  hx,
type(c_ptr), dimension(:), intent(in)  userdata 
)
private

Computes \( Ax = \nabla \cdot (\rho \nabla x) \).

We use the analytically equivalent self-adjoint form: \( Ax = \frac{1}{2}\left[\nabla^2(\rho x) - x \nabla^2 \rho + \rho \nabla^2 x\right] \). This equivalent form is used, because it only uses Laplace operators and results in a symmetric matrix A. Hence, it is numerically more stable.

Definition at line 415 of file sturm_liouville.F90.

◆ jacobi_preconditioner()

subroutine sturm_liouville_oct_m::jacobi_preconditioner ( real(real64), dimension(:), intent(in), contiguous  x,
real(real64), dimension(:), intent(out), contiguous  hx,
type(c_ptr), dimension(:), intent(in)  userdata 
)
private

Jacobi preconditioner: approximates \( (\nabla \cdot [\rho \nabla])^{-1} \).

We need to approximate \( P^{-1} \). Here, we use the Jacobi approximation and that \( \nabla \cdot [\rho \nabla v] \approx \rho \nabla^2 v \).

Definition at line 456 of file sturm_liouville.F90.