Octopus
multigrid.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch, X. Andrade
2!! Copyright (C) 2021 S. Ohlmann
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module multigrid_oct_m
23 use batch_oct_m
26 use debug_oct_m
28 use global_oct_m
29 use index_oct_m
30 use math_oct_m
31 use mesh_oct_m
34 use mpi_oct_m
37 use parser_oct_m
39 use space_oct_m
43
44 implicit none
45
46 private
47 public :: &
64
65 integer, parameter, public :: &
66 INJECTION = 1, &
67 fullweight = 2
68
70 ! Components are public by default
71 type(transfer_table_t) :: tt
72 type(mesh_t), pointer :: mesh => null()
73 type(derivatives_t), pointer :: der => null()
74 end type multigrid_level_t
75
76 type multigrid_t
77 private
78 integer, public :: n_levels
79 type(multigrid_level_t), allocatable, public :: level(:)
80
81 integer :: tp
82 integer, allocatable :: sp(:)
83 integer, allocatable :: ep(:)
84 integer, allocatable :: ep_part(:)
85 end type multigrid_t
86
87
88contains
89
90 ! ---------------------------------------------------------
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
100
101 integer :: i, n_levels, np, order
102
103 push_sub(multigrid_init)
104
105 if (.not. present(nlevels)) then
106 !%Variable MultigridLevels
107 !%Type integer
108 !%Default 4
109 !%Section Mesh
110 !%Description
111 !% Number of levels in the grid hierarchy used for multigrid. Positive
112 !% numbers indicate an absolute number of levels, negative
113 !% numbers are subtracted from the maximum number of levels possible.
114 !%Option max_levels 0
115 !% Calculate the optimal number of levels for the grid.
116 !%End
118 call parse_variable(namespace, 'MultigridLevels', 4, n_levels)
119
120 ! default:
121 order = der%order
122 else
123 n_levels = nlevels
124 write(message(1), '(a,i1,a)') "Set number of multigrid levels to ", n_levels, ". This ignores the value of MultigridLevels."
125 call messages_info(1, namespace=namespace)
126
127 !%Variable MultigridDerivativesOrder
128 !%Type integer
129 !%Default 1
130 !%Section Mesh::Derivatives
131 !%Description
132 !% This variable gives the discretization order for the approximation of
133 !% the differential operators on the different levels of the multigrid.
134 !% For more details, see the variable DerivativesOrder.
135 !% For star-general stencils, the minimum is set to 2.
136 !%End
137 call parse_variable(namespace, 'MultigridDerivativesOrder', 1, order)
138 ! set order to a minimum of 2 for general star stencil, fails otherwise
139 if (der%stencil_type == der_stargeneral) then
140 order = max(2, order)
141 end if
142 end if
143
144 ! require at least one cell per direction on the coarsest grid and adapt n_levels if needed
145 if (any(mesh%idx%ll < 2**n_levels)) then
146 message(1) = "Grid too small for the multigrid solver. Reducing the number of levels."
147 call messages_warning(1)
148 do i = n_levels, 1, -1
149 if (all(mesh%idx%ll >= 2**i)) then
150 n_levels = i
151 exit
152 end if
153 end do
154 end if
155
156 if (n_levels <= 0) then
157 n_levels = n_levels - 3
158 np = mesh%np
159
160 do while (np > 1)
161 np = np / 8
162 n_levels = n_levels + 1
163 end do
164 else
165 n_levels = n_levels - 1
166 end if
168 mgrid%n_levels = n_levels
169
170 safe_allocate(mgrid%level(0:n_levels))
172 mgrid%level(0)%mesh => mesh
173 mgrid%level(0)%der => der
175 mgrid%level(0)%tt%n_fine = mesh%np
176 safe_allocate(mgrid%level(0)%tt%fine_i(1:mesh%np))
178 write(message(1), '(a,i3)') "Multigrid levels:", n_levels + 1
179 call messages_info(1, namespace=namespace)
180
181 do i = 1, mgrid%n_levels
182 safe_allocate(mgrid%level(i)%mesh)
183 safe_allocate(mgrid%level(i)%der)
184
185 call multigrid_mesh_half(space, namespace, mgrid%level(i-1)%mesh, mgrid%level(i)%mesh, stencil, mc%base_grp)
187 call derivatives_init(mgrid%level(i)%der, namespace, space, mesh%coord_system, order=order)
188
189 call mesh_init_stage_3(mgrid%level(i)%mesh, namespace, space, stencil, mc, parent = mgrid%level(i - 1)%mesh)
190
191 call multigrid_get_transfer_tables(mgrid%level(i)%tt, space, mgrid%level(i-1)%mesh, mgrid%level(i)%mesh)
192
193 call derivatives_build(mgrid%level(i)%der, namespace, space, mgrid%level(i)%mesh)
194
195 call mesh_write_info(mgrid%level(i)%mesh, namespace=namespace)
196
197 mgrid%level(i)%der%finer => mgrid%level(i - 1)%der
198 mgrid%level(i - 1)%der%coarser => mgrid%level(i)%der
199 mgrid%level(i)%der%to_finer => mgrid%level(i)%tt
200 mgrid%level(i - 1)%der%to_coarser => mgrid%level(i)%tt
201 end do
202
203 safe_allocate(mgrid%sp(0:mgrid%n_levels))
204 safe_allocate(mgrid%ep(0:mgrid%n_levels))
205 safe_allocate(mgrid%ep_part(0:mgrid%n_levels))
206
207 mgrid%tp = 0
208 do i = 0, mgrid%n_levels
209 mgrid%sp(i) = 1 + mgrid%tp
210 mgrid%ep(i) = mgrid%tp + mgrid%level(i)%mesh%np
211 mgrid%tp = mgrid%tp + mgrid%level(i)%mesh%np_part
212 mgrid%ep_part(i) = mgrid%tp
213 end do
214
215 pop_sub(multigrid_init)
216 end subroutine multigrid_init
217
218 ! ---------------------------------------------------------
220 subroutine multigrid_get_transfer_tables(tt, space, fine, coarse)
221 type(transfer_table_t), intent(inout) :: tt
222 class(space_t), intent(in) :: space
223 type(mesh_t), intent(in) :: fine, coarse
224
225 integer :: i, i1, i2, i4, i8, pt
226 integer :: x(space%dim), mod2(space%dim), idx(space%dim)
227
229
230 ! Currently this routine only works for 3D
231 assert(space%dim == 3)
232
233 tt%n_coarse = coarse%np
234 safe_allocate(tt%to_coarse(1:tt%n_coarse))
235
236 ! GENERATE THE TABLE TO MAP FROM THE FINE TO THE COARSE GRID
237 do i = 1, tt%n_coarse
238 ! locate the equivalent fine grid point
239 call mesh_local_index_to_coords(coarse, i, idx)
240 tt%to_coarse(i) = mesh_local_index_from_coords(fine, 2*idx)
241 end do
242
243 ! count
244 tt%n_fine = fine%np
245 safe_allocate(tt%fine_i(1:tt%n_fine))
246
247 tt%n_fine1 = 0
248 tt%n_fine2 = 0
249 tt%n_fine4 = 0
250 tt%n_fine8 = 0
251 do i = 1, tt%n_fine
252 call mesh_local_index_to_coords(fine, i, idx)
253 mod2 = mod(idx, 2)
254
255 pt = sum(abs(mod2))
256
257 select case (pt)
258 case (0)
259 tt%n_fine1 = tt%n_fine1 + 1
260 tt%fine_i(i) = 1
261 case (1)
262 tt%n_fine2 = tt%n_fine2 + 1
263 tt%fine_i(i) = 2
264 case (2)
265 tt%n_fine4 = tt%n_fine4 + 1
266 tt%fine_i(i) = 4
267 case (3)
268 tt%n_fine8 = tt%n_fine8 + 1
269 tt%fine_i(i) = 8
270 end select
271 end do
272
273 assert(tt%n_fine1 + tt%n_fine2 + tt%n_fine4 + tt%n_fine8 == tt%n_fine)
274
275 safe_allocate(tt%to_fine1(1, 1:tt%n_fine1))
276 safe_allocate(tt%to_fine2(1:2, 1:tt%n_fine2))
277 safe_allocate(tt%to_fine4(1:4, 1:tt%n_fine4))
278 safe_allocate(tt%to_fine8(1:8, 1:tt%n_fine8))
279
280 ! and now build the tables
281 i1 = 0
282 i2 = 0
283 i4 = 0
284 i8 = 0
285 do i = 1, fine%np
286 call mesh_local_index_to_coords(fine, i, idx)
287 x = idx/2
288 mod2 = mod(idx, 2)
289
290 pt = sum(abs(mod2))
291
292 select case (pt)
293 case (0)
294 i1 = i1 + 1
295 tt%to_fine1(1, i1) = mesh_local_index_from_coords(coarse, x)
296
297 case (1)
298 i2 = i2 + 1
299 tt%to_fine2(1, i2) = mesh_local_index_from_coords(coarse, x)
300 tt%to_fine2(2, i2) = mesh_local_index_from_coords(coarse, x + mod2)
301
302 case (2)
303 i4 = i4 + 1
304 tt%to_fine4(1, i4) = mesh_local_index_from_coords(coarse, [x(1) , x(2) + mod2(2), x(3) + mod2(3)])
305 tt%to_fine4(2, i4) = mesh_local_index_from_coords(coarse, [x(1) + mod2(1), x(2) , x(3) + mod2(3)])
306 tt%to_fine4(3, i4) = mesh_local_index_from_coords(coarse, [x(1) + mod2(1), x(2) + mod2(2), x(3) ])
307 tt%to_fine4(4, i4) = mesh_local_index_from_coords(coarse, x + mod2)
308
309 case (3)
310 i8 = i8 + 1
311 tt%to_fine8(1, i8) = mesh_local_index_from_coords(coarse, x)
312 tt%to_fine8(2, i8) = mesh_local_index_from_coords(coarse, [x(1) + mod2(1), x(2) , x(3) ])
313 tt%to_fine8(3, i8) = mesh_local_index_from_coords(coarse, [x(1) , x(2) + mod2(2), x(3) ])
314 tt%to_fine8(4, i8) = mesh_local_index_from_coords(coarse, [x(1) , x(2) , x(3) + mod2(3)])
315 tt%to_fine8(5, i8) = mesh_local_index_from_coords(coarse, [x(1) , x(2) + mod2(2), x(3) + mod2(3)])
316 tt%to_fine8(6, i8) = mesh_local_index_from_coords(coarse, [x(1) + mod2(1), x(2) , x(3) + mod2(3)])
317 tt%to_fine8(7, i8) = mesh_local_index_from_coords(coarse, [x(1) + mod2(1), x(2) + mod2(2), x(3) ])
318 tt%to_fine8(8, i8) = mesh_local_index_from_coords(coarse, x + mod2)
319
320 end select
321
322 end do
323
324 assert(i1 == tt%n_fine1 .and. i2 == tt%n_fine2 .and. i4 == tt%n_fine4 .and. i8 == tt%n_fine8)
325
326
328 end subroutine multigrid_get_transfer_tables
329
330 !---------------------------------------------------------------------------------
333 !---------------------------------------------------------------------------------
334 subroutine multigrid_mesh_half(space, namespace, mesh_in, mesh_out, stencil, grp)
335 class(space_t), intent(in) :: space
336 type(namespace_t), intent(in) :: namespace
337 type(mesh_t), target, intent(in) :: mesh_in
338 type(mesh_t), intent(inout) :: mesh_out
339 type(stencil_t), intent(in) :: stencil
340 type(mpi_grp_t), intent(in) :: grp
341
342 integer :: idim
343
344 push_sub(multigrid_mesh_half)
345
346 mesh_out%box => mesh_in%box
347 mesh_out%idx%dim = mesh_in%idx%dim
348 mesh_out%use_curvilinear = mesh_in%use_curvilinear
349 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
350 mesh_out%coord_system => mesh_in%coord_system
351
352 safe_allocate(mesh_out%spacing(1:space%dim))
353 mesh_out%spacing(:) = 2*mesh_in%spacing(:)
354
355 call index_init(mesh_out%idx, space%dim)
356 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
357 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))/2
358 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))/2
359 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
360
361 mesh_out%idx%stride(1) = 1
362 do idim = 2, mesh_out%idx%dim + 1
363 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
364 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
365 end do
366
367 call mesh_init_stage_2(mesh_out, namespace, space, mesh_out%box, stencil, grp)
368
369 pop_sub(multigrid_mesh_half)
370 end subroutine multigrid_mesh_half
371
372 !---------------------------------------------------------------------------------
373 subroutine multigrid_mesh_double(space, namespace, mesh_in, mesh_out, stencil, grp)
374 class(space_t), intent(in) :: space
375 type(namespace_t), intent(in) :: namespace
376 type(mesh_t), target, intent(in) :: mesh_in
377 type(mesh_t), intent(inout) :: mesh_out
378 type(stencil_t), intent(in) :: stencil
379 type(mpi_grp_t), intent(in) :: grp
380
381 integer :: idim
382 push_sub(multigrid_mesh_double)
383
384 mesh_out%box => mesh_in%box
385 mesh_out%idx%dim = mesh_in%idx%dim
386 mesh_out%use_curvilinear = mesh_in%use_curvilinear
387 mesh_out%masked_periodic_boundaries = mesh_in%masked_periodic_boundaries
388 mesh_out%coord_system => mesh_in%coord_system
389
390 safe_allocate(mesh_out%spacing(1:space%dim))
391 mesh_out%spacing(:) = m_half*mesh_in%spacing(:)
392
393 call index_init(mesh_out%idx, space%dim)
394 mesh_out%idx%enlarge(:) = mesh_in%idx%enlarge(:)
395 mesh_out%idx%nr(1,:) = (mesh_in%idx%nr(1,:)+mesh_in%idx%enlarge(:))*2
396 mesh_out%idx%nr(2,:) = (mesh_in%idx%nr(2,:)-mesh_in%idx%enlarge(:))*2
397 ! We need to make the possible number of grid points larger by one for
398 ! the non-periodic dimensions because the spacing is only half of the
399 ! original mesh and thus we could get points in the new boundary
400 ! that are still inside the simulation box.
401 ! For the periodic dimensions, we are anyway commensurate with the size
402 ! of the box, so we are still commensurate when taking twice the number
403 ! of points.
404 do idim = space%periodic_dim + 1, space%dim
405 mesh_out%idx%nr(1, idim) = mesh_out%idx%nr(1, idim) - 1
406 mesh_out%idx%nr(2, idim) = mesh_out%idx%nr(2, idim) + 1
407 end do
408 mesh_out%idx%ll(:) = mesh_out%idx%nr(2, :) - mesh_out%idx%nr(1, :) + 1
409
410 mesh_out%idx%stride(1) = 1
411 do idim = 2, space%dim+1
412 mesh_out%idx%stride(idim) = mesh_out%idx%stride(idim-1) * &
413 (mesh_out%idx%ll(idim-1) + 2*mesh_out%idx%enlarge(idim-1))
414 end do
415
416 call mesh_init_stage_2(mesh_out, namespace, space, mesh_out%box, stencil, grp)
417
418 pop_sub(multigrid_mesh_double)
419 end subroutine multigrid_mesh_double
420
421 ! ---------------------------------------------------------
422 subroutine multigrid_end(mgrid)
423 type(multigrid_t), target, intent(inout) :: mgrid
424
425 integer :: i
426 type(multigrid_level_t), pointer :: level
427
428 push_sub(multigrid_end)
430 safe_deallocate_a(mgrid%sp)
431 safe_deallocate_a(mgrid%ep)
432 safe_deallocate_a(mgrid%ep_part)
433
434 safe_deallocate_a(mgrid%level(0)%tt%fine_i)
435
436 do i = 1, mgrid%n_levels
437 level => mgrid%level(i)
438
439 call derivatives_end(level%der)
440 call mesh_end(level%mesh)
441 safe_deallocate_p(level%mesh)
442 safe_deallocate_p(level%der)
443
444 safe_deallocate_a(level%tt%to_coarse)
445 safe_deallocate_a(level%tt%to_fine1)
446 safe_deallocate_a(level%tt%to_fine2)
447 safe_deallocate_a(level%tt%to_fine4)
448 safe_deallocate_a(level%tt%to_fine8)
449 safe_deallocate_a(level%tt%fine_i)
450 end do
451
452 safe_deallocate_a(mgrid%level)
453
454 pop_sub(multigrid_end)
455 end subroutine multigrid_end
456
457 !---------------------------------------------------------------------------------
458 integer function multigrid_number_of_levels(base_der) result(number)
459 type(derivatives_t), target, intent(in) :: base_der
460
461 type(derivatives_t), pointer :: next_der
462
463 next_der => base_der%coarser
464
465 number = 0
466 next_der => base_der%coarser
467 do while (associated(next_der))
468 number = number + 1
469 next_der => next_der%coarser
470 end do
471
472 end function multigrid_number_of_levels
473
474 !---------------------------------------------------------------------------------
475 subroutine multigrid_build_stencil(dim, weight, shift)
476 integer, intent(in) :: dim
477 real(real64), intent(inout) :: weight(:)
478 integer, intent(inout) :: shift(:,:)
479
480 integer :: nn, di, dj, dk, dd
481
483
484 assert(ubound(weight, dim=1) == 3**dim)
485 assert(ubound(shift, dim=1) == dim)
486 assert(ubound(shift, dim=2) == 3**dim)
487
488 nn = 0
489 select case(dim)
490 case(1)
491 do di = -1, 1
492 dd = abs(di)
493 nn = nn + 1
494 weight(nn) = m_half**dd
495 shift(1,nn) = di
496 end do
497 case(2)
498 do di = -1, 1
499 do dj = -1, 1
500 dd = abs(di)+abs(dj)
501 nn = nn + 1
502 weight(nn) = m_half**dd
503 shift(1,nn) = di
504 shift(2,nn) = dj
505 end do
506 end do
507 case(3)
508 do di = -1, 1
509 do dj = -1, 1
510 do dk = -1, 1
511 dd = abs(di)+abs(dj)+abs(dk)
512 nn = nn + 1
513 weight(nn) = m_half**dd
514 shift(1,nn) = di
515 shift(2,nn) = dj
516 shift(3,nn) = dk
517 end do
518 end do
519 end do
520 end select
521
523 end subroutine multigrid_build_stencil
524
525
526#include "undef.F90"
527#include "real.F90"
528#include "multigrid_inc.F90"
529
530#include "undef.F90"
531#include "complex.F90"
532#include "multigrid_inc.F90"
533
534end module multigrid_oct_m
535
536!! Local Variables:
537!! mode: f90
538!! coding: utf-8
539!! End:
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
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
Definition: global.F90:206
This module implements the index, used for the mesh points.
Definition: index.F90:124
subroutine, public index_init(idx, dim)
This subroutine allocates memory and initializes some components.
Definition: index.F90:220
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module contains subroutines, related to the initialization of the mesh.
Definition: mesh_init.F90:119
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....
Definition: mesh_init.F90:531
subroutine, public mesh_init_stage_2(mesh, namespace, space, box, stencil, grp, regenerate)
This subroutine creates the global array of spatial indices and the inverse mapping.
Definition: mesh_init.F90:292
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
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.
Definition: mesh.F90:938
subroutine, public mesh_write_info(this, iunit, namespace)
Definition: mesh.F90:310
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.
Definition: mesh.F90:950
recursive subroutine, public mesh_end(this)
Definition: mesh.F90:686
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public dmultigrid_fine2coarse_batch(tt, fine_der, coarse_mesh, fineb, coarseb, method_p)
Definition: multigrid.F90:988
subroutine, public dmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, set_bc)
Definition: multigrid.F90:690
integer function, public multigrid_number_of_levels(base_der)
Definition: multigrid.F90:554
subroutine, public multigrid_end(mgrid)
Definition: multigrid.F90:518
subroutine, public dmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
Definition: multigrid.F90:769
subroutine, public multigrid_mesh_double(space, namespace, mesh_in, mesh_out, stencil, grp)
Definition: multigrid.F90:469
integer, parameter, public fullweight
Definition: multigrid.F90:160
subroutine, public zmultigrid_fine2coarse_batch(tt, fine_der, coarse_mesh, fineb, coarseb, method_p)
Definition: multigrid.F90:1498
subroutine, public multigrid_mesh_half(space, namespace, mesh_in, mesh_out, stencil, grp)
Creates a mesh that has twice the spacing betwen the points than the in mesh. This is used in the mul...
Definition: multigrid.F90:430
subroutine, public zmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, set_bc)
Definition: multigrid.F90:1200
subroutine, public multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
Definition: multigrid.F90:187
subroutine, public zmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
Definition: multigrid.F90:1279
subroutine, public dmultigrid_coarse2fine_batch(tt, coarse_der, fine_mesh, coarseb, fineb)
Definition: multigrid.F90:884
subroutine multigrid_build_stencil(dim, weight, shift)
Definition: multigrid.F90:571
subroutine, public multigrid_get_transfer_tables(tt, space, fine, coarse)
creates the lookup tables to go between the coarse and fine meshes
Definition: multigrid.F90:316
subroutine, public zmultigrid_coarse2fine_batch(tt, coarse_der, fine_mesh, coarseb, fineb)
Definition: multigrid.F90:1394
Some general things and nomenclature:
Definition: par_vec.F90:173
This module defines stencils used in Octopus.
Definition: stencil.F90:137
class representing derivatives
Describes mesh distribution to nodes.
Definition: mesh.F90:187
This is defined even when running serial.
Definition: mpi.F90:144
The class representing the stencil, which is used for non-local mesh operations.
Definition: stencil.F90:165