65 integer,
parameter,
public :: &
71 type(transfer_table_t) :: tt
72 type(mesh_t),
pointer :: mesh => null()
73 type(derivatives_t),
pointer :: der => null()
78 integer,
public :: n_levels
79 type(multigrid_level_t),
allocatable,
public :: level(:)
82 integer,
allocatable :: sp(:)
83 integer,
allocatable :: ep(:)
84 integer,
allocatable :: ep_part(:)
91 subroutine multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
92 type(multigrid_t),
target,
intent(out) :: mgrid
93 type(namespace_t),
intent(in) :: namespace
94 class(space_t),
intent(in) :: space
95 class(mesh_t),
target,
intent(in) :: mesh
96 type(derivatives_t),
target,
intent(in) :: der
97 type(stencil_t),
intent(in) :: stencil
98 type(multicomm_t),
intent(in) :: mc
99 integer,
optional,
intent(in) :: nlevels
101 integer :: i, n_levels, np, order
105 if (.not.
present(nlevels))
then
124 write(
message(1),
'(a,i1,a)')
"Set number of multigrid levels to ", n_levels,
". This ignores the value of MultigridLevels."
137 call parse_variable(namespace,
'MultigridDerivativesOrder', 1, order)
140 order = max(2, order)
144 if (n_levels <= 0)
then
145 n_levels = n_levels - 3
150 n_levels = n_levels + 1
153 n_levels = n_levels - 1
156 mgrid%n_levels = n_levels
158 safe_allocate(mgrid%level(0:n_levels))
160 mgrid%level(0)%mesh => mesh
161 mgrid%level(0)%der => der
163 mgrid%level(0)%tt%n_fine = mesh%np
164 safe_allocate(mgrid%level(0)%tt%fine_i(1:mesh%np))
166 write(
message(1),
'(a,i3)')
"Multigrid levels:", n_levels + 1
169 do i = 1, mgrid%n_levels
170 safe_allocate(mgrid%level(i)%mesh)
171 safe_allocate(mgrid%level(i)%der)
173 call multigrid_mesh_half(space, namespace, mgrid%level(i-1)%mesh, mgrid%level(i)%mesh, stencil)
175 call derivatives_init(mgrid%level(i)%der, namespace, space, mesh%coord_system, order=order)
177 call mesh_init_stage_3(mgrid%level(i)%mesh, namespace, space, stencil, mc, parent = mgrid%level(i - 1)%mesh)
181 call derivatives_build(mgrid%level(i)%der, namespace, space, mgrid%level(i)%mesh)
185 mgrid%level(i)%der%finer => mgrid%level(i - 1)%der
186 mgrid%level(i - 1)%der%coarser => mgrid%level(i)%der
187 mgrid%level(i)%der%to_finer => mgrid%level(i)%tt
188 mgrid%level(i - 1)%der%to_coarser => mgrid%level(i)%tt
191 safe_allocate(mgrid%sp(0:mgrid%n_levels))
192 safe_allocate(mgrid%ep(0:mgrid%n_levels))
193 safe_allocate(mgrid%ep_part(0:mgrid%n_levels))
196 do i = 0, mgrid%n_levels
197 mgrid%sp(i) = 1 + mgrid%tp
198 mgrid%ep(i) = mgrid%tp + mgrid%level(i)%mesh%np
199 mgrid%tp = mgrid%tp + mgrid%level(i)%mesh%np_part
200 mgrid%ep_part(i) = mgrid%tp
210 class(
space_t),
intent(in) :: space
211 type(
mesh_t),
intent(in) :: fine, coarse
213 integer :: i, i1, i2, i4, i8, pt
214 integer :: x(space%dim), mod2(space%dim), idx(space%dim)
219 assert(space%dim == 3)
221 tt%n_coarse = coarse%np
222 safe_allocate(tt%to_coarse(1:tt%n_coarse))
225 do i = 1, tt%n_coarse
233 safe_allocate(tt%fine_i(1:tt%n_fine))
247 tt%n_fine1 = tt%n_fine1 + 1
250 tt%n_fine2 = tt%n_fine2 + 1
253 tt%n_fine4 = tt%n_fine4 + 1
256 tt%n_fine8 = tt%n_fine8 + 1
261 assert(tt%n_fine1 + tt%n_fine2 + tt%n_fine4 + tt%n_fine8 == tt%n_fine)
263 safe_allocate(tt%to_fine1(1, 1:tt%n_fine1))
264 safe_allocate(tt%to_fine2(1:2, 1:tt%n_fine2))
265 safe_allocate(tt%to_fine4(1:4, 1:tt%n_fine4))
266 safe_allocate(tt%to_fine8(1:8, 1:tt%n_fine8))
312 assert(i1 == tt%n_fine1 .and. i2 == tt%n_fine2 .and. i4 == tt%n_fine4 .and. i8 == tt%n_fine8)
323 class(
space_t),
intent(in) :: space
325 type(
mesh_t),
target,
intent(in) :: mesh_in
326 type(
mesh_t),
intent(inout) :: mesh_out
333 mesh_out%box => mesh_in%box
334 mesh_out%idx%dim = mesh_in%idx%dim
335 mesh_out%use_curvilinear = mesh_in%use_curvilinear
336 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
337 mesh_out%coord_system => mesh_in%coord_system
339 safe_allocate(mesh_out%spacing(1:space%dim))
340 mesh_out%spacing(:) = 2*mesh_in%spacing(:)
343 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
344 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))/2
345 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))/2
346 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
348 mesh_out%idx%stride(1) = 1
349 do idim = 2, mesh_out%idx%dim + 1
350 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
351 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
361 class(
space_t),
intent(in) :: space
363 type(
mesh_t),
target,
intent(in) :: mesh_in
364 type(
mesh_t),
intent(inout) :: mesh_out
370 mesh_out%box => mesh_in%box
371 mesh_out%idx%dim = mesh_in%idx%dim
372 mesh_out%use_curvilinear = mesh_in%use_curvilinear
373 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
374 mesh_out%coord_system => mesh_in%coord_system
376 safe_allocate(mesh_out%spacing(1:space%dim))
377 mesh_out%spacing(:) =
m_half*mesh_in%spacing(:)
380 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
381 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))*2
382 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))*2
390 do idim = space%periodic_dim + 1, space%dim
391 mesh_out%idx%nr(1, idim) = mesh_out%idx%nr(1, idim) - 1
392 mesh_out%idx%nr(2, idim) = mesh_out%idx%nr(2, idim) + 1
394 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
396 mesh_out%idx%stride(1) = 1
397 do idim = 2, space%dim+1
398 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
399 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
416 safe_deallocate_a(mgrid%sp)
417 safe_deallocate_a(mgrid%ep)
418 safe_deallocate_a(mgrid%ep_part)
420 safe_deallocate_a(mgrid%level(0)%tt%fine_i)
422 do i = 1, mgrid%n_levels
423 level => mgrid%level(i)
427 safe_deallocate_p(level%mesh)
428 safe_deallocate_p(level%der)
430 safe_deallocate_a(level%tt%to_coarse)
431 safe_deallocate_a(level%tt%to_fine1)
432 safe_deallocate_a(level%tt%to_fine2)
433 safe_deallocate_a(level%tt%to_fine4)
434 safe_deallocate_a(level%tt%to_fine8)
435 safe_deallocate_a(level%tt%fine_i)
438 safe_deallocate_a(mgrid%level)
449 next_der => base_der%coarser
454 next_der => next_der%coarser
455 if (.not.
associated(next_der))
exit
462 integer,
intent(in) :: dim
463 real(real64),
intent(inout) :: weight(:)
464 integer,
intent(inout) :: shift(:,:)
466 integer :: nn, di, dj, dk, dd
470 assert(ubound(weight, dim=1) == 3**dim)
471 assert(ubound(shift, dim=1) == dim)
472 assert(ubound(shift, dim=2) == 3**dim)
497 dd = abs(di)+abs(dj)+abs(dk)
514#include "multigrid_inc.F90"
517#include "complex.F90"
518#include "multigrid_inc.F90"
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
Module implementing boundary conditions in Octopus.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public derivatives_build(der, namespace, space, mesh, qvector, regenerate, verbose)
build the derivatives object:
subroutine, public derivatives_init(der, namespace, space, coord_system, order)
subroutine, public derivatives_end(der)
integer, parameter, public der_stargeneral
real(real64), parameter, public m_half
This module implements the index, used for the mesh points.
subroutine, public index_init(idx, dim)
This subroutine allocates memory and initializes some components.
This module is intended to contain "only mathematical" functions and procedures.
This module contains subroutines, related to the initialization of the mesh.
subroutine, public mesh_init_stage_3(mesh, namespace, space, stencil, mc, parent, regenerate)
When running parallel in domains, stencil and np_stencil are needed to compute the ghost points....
subroutine, public mesh_init_stage_2(mesh, namespace, space, box, stencil, regenerate)
This subroutine creates the global array of spatial indices and the inverse mapping.
This module defines the meshes, which are used in Octopus.
integer function, public mesh_local_index_from_coords(mesh, ix)
This function returns the local index of the point for a given vector of integer coordinates.
subroutine, public mesh_write_info(this, iunit, namespace)
subroutine, public mesh_local_index_to_coords(mesh, ip, ix)
Given a local point index, this function returns the set of integer coordinates of the point.
recursive subroutine, public mesh_end(this)
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
This module handles the communicators for the various parallelization strategies.
subroutine, public multigrid_mesh_double(space, namespace, mesh_in, mesh_out, stencil)
subroutine, public dmultigrid_fine2coarse_batch(tt, fine_der, coarse_mesh, fineb, coarseb, method_p)
subroutine, public dmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, set_bc)
integer function, public multigrid_number_of_levels(base_der)
subroutine, public multigrid_end(mgrid)
subroutine, public dmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
integer, parameter, public fullweight
subroutine, public zmultigrid_fine2coarse_batch(tt, fine_der, coarse_mesh, fineb, coarseb, method_p)
subroutine, public zmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, set_bc)
subroutine, public multigrid_mesh_half(space, namespace, mesh_in, mesh_out, stencil)
Creates a mesh that has twice the spacing betwen the points than the in mesh. This is used in the mul...
subroutine, public multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
subroutine, public zmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
subroutine, public dmultigrid_coarse2fine_batch(tt, coarse_der, fine_mesh, coarseb, fineb)
subroutine multigrid_build_stencil(dim, weight, shift)
subroutine, public multigrid_get_transfer_tables(tt, space, fine, coarse)
creates the lookup tables to go between the coarse and fine meshes
subroutine, public zmultigrid_coarse2fine_batch(tt, coarse_der, fine_mesh, coarseb, fineb)
Some general things and nomenclature:
This module defines stencils used in Octopus.
class representing derivatives
Describes mesh distribution to nodes.
The class representing the stencil, which is used for non-local mesh operations.