64 integer,
parameter,
public :: &
70 type(transfer_table_t) :: tt
71 type(mesh_t),
pointer :: mesh => null()
72 type(derivatives_t),
pointer :: der => null()
77 integer,
public :: n_levels
78 type(multigrid_level_t),
allocatable,
public :: level(:)
81 integer,
allocatable :: sp(:)
82 integer,
allocatable :: ep(:)
83 integer,
allocatable :: ep_part(:)
90 subroutine multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
91 type(multigrid_t),
target,
intent(out) :: mgrid
92 type(namespace_t),
intent(in) :: namespace
93 class(space_t),
intent(in) :: space
94 class(mesh_t),
target,
intent(in) :: mesh
95 type(derivatives_t),
target,
intent(in) :: der
96 type(stencil_t),
intent(in) :: stencil
97 type(multicomm_t),
intent(in) :: mc
98 integer,
optional,
intent(in) :: nlevels
100 integer :: i, n_levels, np, order
104 if (.not.
present(nlevels))
then
123 write(
message(1),
'(a,i1,a)')
"Set number of multigrid levels to ", n_levels,
". This ignores the value of MultigridLevels."
136 call parse_variable(namespace,
'MultigridDerivativesOrder', 1, order)
139 order = max(2, order)
143 if (n_levels <= 0)
then
144 n_levels = n_levels - 3
149 n_levels = n_levels + 1
152 n_levels = n_levels - 1
155 mgrid%n_levels = n_levels
157 safe_allocate(mgrid%level(0:n_levels))
159 mgrid%level(0)%mesh => mesh
160 mgrid%level(0)%der => der
162 mgrid%level(0)%tt%n_fine = mesh%np
163 safe_allocate(mgrid%level(0)%tt%fine_i(1:mesh%np))
165 write(
message(1),
'(a,i3)')
"Multigrid levels:", n_levels + 1
168 do i = 1, mgrid%n_levels
169 safe_allocate(mgrid%level(i)%mesh)
170 safe_allocate(mgrid%level(i)%der)
172 call multigrid_mesh_half(space, namespace, mgrid%level(i-1)%mesh, mgrid%level(i)%mesh, stencil)
174 call derivatives_init(mgrid%level(i)%der, namespace, space, mesh%coord_system, order=order)
176 call mesh_init_stage_3(mgrid%level(i)%mesh, namespace, space, stencil, mc, parent = mgrid%level(i - 1)%mesh)
180 call derivatives_build(mgrid%level(i)%der, namespace, space, mgrid%level(i)%mesh)
184 mgrid%level(i)%der%finer => mgrid%level(i - 1)%der
185 mgrid%level(i - 1)%der%coarser => mgrid%level(i)%der
186 mgrid%level(i)%der%to_finer => mgrid%level(i)%tt
187 mgrid%level(i - 1)%der%to_coarser => mgrid%level(i)%tt
190 safe_allocate(mgrid%sp(0:mgrid%n_levels))
191 safe_allocate(mgrid%ep(0:mgrid%n_levels))
192 safe_allocate(mgrid%ep_part(0:mgrid%n_levels))
195 do i = 0, mgrid%n_levels
196 mgrid%sp(i) = 1 + mgrid%tp
197 mgrid%ep(i) = mgrid%tp + mgrid%level(i)%mesh%np
198 mgrid%tp = mgrid%tp + mgrid%level(i)%mesh%np_part
199 mgrid%ep_part(i) = mgrid%tp
209 class(
space_t),
intent(in) :: space
210 type(
mesh_t),
intent(in) :: fine, coarse
212 integer :: i, i1, i2, i4, i8, pt
213 integer :: x(space%dim), mod2(space%dim), idx(space%dim)
218 assert(space%dim == 3)
220 tt%n_coarse = coarse%np
221 safe_allocate(tt%to_coarse(1:tt%n_coarse))
224 do i = 1, tt%n_coarse
232 safe_allocate(tt%fine_i(1:tt%n_fine))
246 tt%n_fine1 = tt%n_fine1 + 1
249 tt%n_fine2 = tt%n_fine2 + 1
252 tt%n_fine4 = tt%n_fine4 + 1
255 tt%n_fine8 = tt%n_fine8 + 1
260 assert(tt%n_fine1 + tt%n_fine2 + tt%n_fine4 + tt%n_fine8 == tt%n_fine)
262 safe_allocate(tt%to_fine1(1, 1:tt%n_fine1))
263 safe_allocate(tt%to_fine2(1:2, 1:tt%n_fine2))
264 safe_allocate(tt%to_fine4(1:4, 1:tt%n_fine4))
265 safe_allocate(tt%to_fine8(1:8, 1:tt%n_fine8))
311 assert(i1 == tt%n_fine1 .and. i2 == tt%n_fine2 .and. i4 == tt%n_fine4 .and. i8 == tt%n_fine8)
322 class(
space_t),
intent(in) :: space
324 type(
mesh_t),
target,
intent(in) :: mesh_in
325 type(
mesh_t),
intent(inout) :: mesh_out
332 mesh_out%box => mesh_in%box
333 mesh_out%idx%dim = mesh_in%idx%dim
334 mesh_out%use_curvilinear = mesh_in%use_curvilinear
335 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
336 mesh_out%coord_system => mesh_in%coord_system
338 safe_allocate(mesh_out%spacing(1:space%dim))
339 mesh_out%spacing(:) = 2*mesh_in%spacing(:)
342 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
343 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))/2
344 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))/2
345 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
347 mesh_out%idx%stride(1) = 1
348 do idim = 2, mesh_out%idx%dim + 1
349 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
350 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
360 class(
space_t),
intent(in) :: space
362 type(
mesh_t),
target,
intent(in) :: mesh_in
363 type(
mesh_t),
intent(inout) :: mesh_out
369 mesh_out%box => mesh_in%box
370 mesh_out%idx%dim = mesh_in%idx%dim
371 mesh_out%use_curvilinear = mesh_in%use_curvilinear
372 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
373 mesh_out%coord_system => mesh_in%coord_system
375 safe_allocate(mesh_out%spacing(1:space%dim))
376 mesh_out%spacing(:) =
m_half*mesh_in%spacing(:)
379 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
380 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))*2
381 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))*2
389 do idim = space%periodic_dim + 1, space%dim
390 mesh_out%idx%nr(1, idim) = mesh_out%idx%nr(1, idim) - 1
391 mesh_out%idx%nr(2, idim) = mesh_out%idx%nr(2, idim) + 1
393 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
395 mesh_out%idx%stride(1) = 1
396 do idim = 2, space%dim+1
397 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
398 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
415 safe_deallocate_a(mgrid%sp)
416 safe_deallocate_a(mgrid%ep)
417 safe_deallocate_a(mgrid%ep_part)
419 safe_deallocate_a(mgrid%level(0)%tt%fine_i)
421 do i = 1, mgrid%n_levels
422 level => mgrid%level(i)
426 safe_deallocate_p(level%mesh)
427 safe_deallocate_p(level%der)
429 safe_deallocate_a(level%tt%to_coarse)
430 safe_deallocate_a(level%tt%to_fine1)
431 safe_deallocate_a(level%tt%to_fine2)
432 safe_deallocate_a(level%tt%to_fine4)
433 safe_deallocate_a(level%tt%to_fine8)
434 safe_deallocate_a(level%tt%fine_i)
437 safe_deallocate_a(mgrid%level)
448 next_der => base_der%coarser
453 next_der => next_der%coarser
454 if (.not.
associated(next_der))
exit
462#include "multigrid_inc.F90"
465#include "complex.F90"
466#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 zmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, order, set_bc)
subroutine, public dmultigrid_fine2coarse_batch(tt, fine_der, coarse_mesh, fineb, coarseb, method_p)
subroutine, public zmultigrid_coarse2fine_batch(tt, coarse_der, fine_mesh, coarseb, fineb, order)
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 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, order)
subroutine, public dmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, order, set_bc)
subroutine, public multigrid_get_transfer_tables(tt, space, fine, coarse)
creates the lookup tables to go between the coarse and fine meshes
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.