71 type(grid_t),
pointer,
public :: gr => null()
72 real(real64),
pointer :: rho(:) => null()
73 real(real64),
allocatable :: diag_preconditioner(:)
74 real(real64),
allocatable :: lapl_rho(:)
75 real(real64),
allocatable :: diag_lapl(:)
76 real(real64),
allocatable :: sl_tmp_prod(:)
77 real(real64),
allocatable :: sl_tmp_lapl(:)
78 integer :: max_iter = 500
79 real(real64) :: threshold = 1e-7_real64
81 logical :: initialized = .false.
92 type(sturm_liouville_t),
intent(inout) :: this
93 type(namespace_t),
intent(in) :: namespace
94 type(grid_t),
target,
intent(in) :: gr
95 type(space_t),
intent(in) :: space
96 integer,
optional,
intent(in) :: max_iter
97 real(real64),
optional,
intent(in) :: thr
98 real(real64),
optional,
intent(in) :: inverse_tol
100 character(len=80) :: name
101 type(nl_operator_t) :: op(1)
104 assert(.not. this%initialized)
107 if (
present(max_iter)) this%max_iter = max_iter
108 if (
present(thr)) this%threshold = thr
109 if (gr%box%dim == 1) this%inverse_tol = 1e-20_real64
110 if (
present(inverse_tol)) this%inverse_tol = inverse_tol
113 name =
'SL preconditioner'
115 safe_allocate(this%diag_lapl(1:op(1)%np))
119 safe_allocate(this%lapl_rho(1:this%gr%np))
120 safe_allocate(this%sl_tmp_prod(1:this%gr%np_part))
121 safe_allocate(this%sl_tmp_lapl(1:this%gr%np))
122 safe_allocate(this%diag_preconditioner(1:this%gr%np))
124 this%initialized = .
true.
133 type(sturm_liouville_t),
intent(inout) :: this
137 safe_deallocate_a(this%diag_lapl)
138 safe_deallocate_a(this%diag_preconditioner)
139 safe_deallocate_a(this%lapl_rho)
140 safe_deallocate_a(this%sl_tmp_prod)
141 safe_deallocate_a(this%sl_tmp_lapl)
144 this%initialized = .false.
153 type(sturm_liouville_t),
target,
intent(inout) :: this
154 type(poisson_t),
intent(in) :: psolver
155 type(namespace_t),
intent(in) :: namespace
156 real(real64),
intent(in) :: f(:,:)
157 real(real64),
intent(inout) :: v(:)
158 logical,
optional,
intent(in) :: with_inverse_density
159 real(real64),
optional,
target,
intent(in) :: rho(:)
161 real(real64),
allocatable :: poisson_rhs(:), tmp_f(:, :)
163 integer :: iter, ip, idm
166 assert(this%initialized)
169 if (
present(rho)) this%rho => rho
171 safe_allocate(tmp_f(1:this%gr%np_part, 1:this%gr%box%dim))
174 assert(
associated(this%rho))
175 do ip = 1, this%gr%np
176 do idm = 1, this%gr%box%dim
177 tmp_f(ip, idm) = f(ip, idm) / (safe_tol(this%rho(ip), this%inverse_tol))
181 call lalg_copy(this%gr%np, this%gr%box%dim, f, tmp_f)
185 safe_allocate(poisson_rhs(1:this%gr%np))
187 safe_deallocate_a(tmp_f)
192 select case(this%gr%box%dim)
204 this%threshold, userdata=[c_loc(this%gr%der)])
205 write(
message(1),
'(a,i6,a)')
"Info: CG converged with ", iter,
" iterations."
206 write(
message(2),
'(a,e14.6)')
"Info: The residue is ", res
213 safe_deallocate_a(poisson_rhs)
228 real(real64),
contiguous,
target,
intent(in) :: rho(:)
229 real(real64),
contiguous,
intent(in) :: rhs(:)
230 real(real64),
contiguous,
intent(inout) :: v(:)
237 assert(this%initialized)
238 assert(ubound(rho, dim=1) >= this%gr%np_part)
239 assert(ubound(rhs, dim=1) >= this%gr%np)
240 assert(ubound(v, dim=1) >= this%gr%np)
247 do ip = 1, this%gr%np
248 this%diag_preconditioner(ip) = 1 / (safe_tol(this%rho(ip)* this%diag_lapl(ip), this%inverse_tol))
254 threshold = this%threshold, showprogress = .false.)
256 write(
message(1),
'(a, i6, a)')
"Info: Sturm-Liouville solver converged in ", iter,
" iterations."
257 write(
message(2),
'(a, es14.6)')
"Info: The residue is ", res
281 real(real64),
target,
contiguous,
intent(in) :: rho(:)
282 real(real64),
contiguous,
intent(in) ::
f(:,:)
283 real(real64),
contiguous,
intent(inout) :: v(:)
284 type(
poisson_t),
optional,
intent(in) :: psolver
286 real(real64),
allocatable :: rhs(:), neg_f(:,:)
289 assert(this%initialized)
290 assert(ubound(rho, dim=1) >= this%gr%np_part)
291 assert(ubound(
f, dim=1) >= this%gr%np_part)
292 assert(ubound(
f, dim=2) >= this%gr%box%dim)
293 assert(ubound(v, dim=1) >= this%gr%np)
295 safe_allocate(neg_f(1:this%gr%np_part, 1:this%gr%box%dim))
298 if (
present(psolver))
then
302 safe_allocate(rhs(1:this%gr%np))
306 safe_deallocate_a(rhs)
307 safe_deallocate_a(neg_f)
321 real(real64),
contiguous,
intent(in) :: x(:)
322 real(real64),
contiguous,
intent(out) :: hx(:)
323 type(c_ptr),
intent(in) :: userdata(:)
326 real(real64),
allocatable :: v(:), prod(:), lapl_v(:), lapl_product(:)
329 assert(
size(userdata) == 1)
330 assert(c_associated(userdata(1)))
331 call c_f_pointer(userdata(1), sl)
333 safe_allocate(v(1:sl%gr%np_part))
334 safe_allocate(lapl_v(1:sl%gr%np))
338 safe_allocate(prod(1:sl%gr%np_part))
339 safe_allocate(lapl_product(1:sl%gr%np))
340 do ip = 1, sl%gr%np_part
341 prod(ip) = sl%rho(ip) * v(ip)
346 hx(ip) =
m_half * (sl%rho(ip) * lapl_v(ip) - v(ip) * sl%lapl_rho(ip) + lapl_product(ip))
350 safe_deallocate_a(prod)
351 safe_deallocate_a(lapl_v)
352 safe_deallocate_a(lapl_product)
362 real(real64),
contiguous,
intent(in) :: x(:)
363 real(real64),
contiguous,
intent(out) :: hx(:)
364 type(c_ptr),
intent(in) :: userdata(:)
369 assert(
size(userdata) == 1)
370 assert(c_associated(userdata(1)))
371 call c_f_pointer(userdata(1), sl)
375 hx(ip) = x(ip) * sl%diag_preconditioner(ip)
Copies a vector x, to a vector y.
scales a vector by a constant
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public derivatives_get_lapl(this, namespace, op, space, name, order)
subroutine, public dderivatives_lapl(der, ff, op_ff, ghost_update, set_bc, factor)
apply the Laplacian to a mesh function
subroutine, public dderivatives_div(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the divergence operator to a vector of mesh functions
real(real64), parameter, public m_zero
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_fourth
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
Computes and , suitable as an operator callback for iterative solvers (CG, QMR, etc....
subroutine, public dlaplacian_op(x, hx, userdata)
Computes the negative Laplacian operator action: .
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_dotu_aux(f1, f2)
dot product between two vectors (mesh functions) without conjugation
real(real64) function, public dmf_dotp_aux(f1, f2)
dot product between two vectors (mesh functions)
subroutine, public mesh_init_mesh_aux(mesh)
Initialise a pointer to the grid/mesh, that is globally exposed, such that low level mesh operations ...
real(real64) function, public dmf_nrm2_aux(ff)
calculate norm2 of a vector (mesh function)
This module defines the meshes, which are used in Octopus.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module defines non-local operators.
subroutine, public dnl_operator_operate_diag(op, fo)
subroutine, public nl_operator_end(op)
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public dqmr_sym_gen_dotu(np, x, b, op, dotu, nrm2, prec, iter, userdata, residue, threshold, showprogress, converged, use_initial_guess)
for complex symmetric matrices W Chen and B Poirier, J Comput Phys 219, 198-209 (2006)
General Sturm-Liouville solver for equations of the form .
subroutine, public sturm_liouville_solve_from_div(this, namespace, rho, f, v, psolver)
Solve the Sturm-Liouville equation from a divergence.
subroutine, public sturm_liouville_solve(this, namespace, rho, rhs, v)
Solve the Sturm-Liouville equation with a scalar right-hand side.
subroutine sl_operator(x, hx, userdata)
Computes .
subroutine, public sturm_liouville_solve_poisson(this, psolver, namespace, f, v, with_inverse_density, rho)
Solves Initial guess for the Sturm-Liouville solver: Poisson solution.
subroutine, public sturm_liouville_end(this)
Finalize the Sturm-Liouville solver.
subroutine, public sturm_liouville_init(this, namespace, gr, space, max_iter, thr, inverse_tol)
Initialize the Sturm-Liouville solver.
subroutine jacobi_preconditioner(x, hx, userdata)
Jacobi preconditioner: approximates .
static double f(double w, void *p)