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.