78 integer,
allocatable :: imin(:)
79 integer,
allocatable :: imax(:)
80 integer,
allocatable :: ri(:, :)
86 type(stencil_t),
public :: stencil
87 type(mesh_t),
pointer :: mesh => null()
88 integer,
allocatable :: nn(:)
89 integer,
public :: np = 0
91 real(real64),
allocatable,
public :: w(:,:)
93 logical,
public :: const_w = .
true.
95 type(accel_mem_t),
public :: buff_weights
96 type(accel_mem_t),
public :: buff_half_weights
98 character(len=40) :: label
101 integer,
public :: nri = 0
102 integer,
allocatable,
public :: ri(:,:)
103 integer,
allocatable,
public :: rimap(:)
104 integer,
allocatable,
public :: rimap_inv(:)
106 integer :: ninner = 0
107 integer :: nouter = 0
109 type(nl_operator_index_t) :: inner
110 type(nl_operator_index_t) :: outer
112 type(accel_kernel_t) :: kernel
113 type(accel_mem_t) :: buff_imin
114 type(accel_mem_t) :: buff_imax
115 type(accel_mem_t) :: buff_ri
116 type(accel_mem_t) :: buff_map
117 type(accel_mem_t) :: buff_all
118 type(accel_mem_t) :: buff_inner
119 type(accel_mem_t) :: buff_outer
120 type(accel_mem_t) :: buff_stencil
121 type(accel_mem_t) :: buff_ip_to_xyz
122 type(accel_mem_t) :: buff_xyz_to_ip
125 type(nl_operator_t),
public,
pointer :: coarser => null()
129 integer,
parameter :: &
135 integer,
parameter :: &
145 integer,
intent(in) :: opid, type
149 integer :: dfunction_global = -1
150 integer :: zfunction_global = -1
151 integer :: function_opencl
159 type(namespace_t),
intent(in) :: namespace
237 character(len=*),
intent(in) :: label
265 safe_allocate_source_a(opo%nn, opi%nn)
266 safe_allocate_source_a(opo%w, opi%w)
268 opo%const_w = opi%const_w
271 assert(
allocated(opi%ri))
273 safe_allocate_source_a(opo%ri, opi%ri)
274 safe_allocate_source_a(opo%rimap, opi%rimap)
275 safe_allocate_source_a(opo%rimap_inv, opi%rimap_inv)
277 if (opi%mesh%parallel_in_domains)
then
278 opo%inner%nri = opi%inner%nri
279 safe_allocate_source_a(opo%inner%imin, opi%inner%imin)
280 safe_allocate_source_a(opo%inner%imax, opi%inner%imax)
281 safe_allocate_source_a(opo%inner%ri, opi%inner%ri)
283 opo%outer%nri = opi%outer%nri
284 safe_allocate_source_a(opo%outer%imin, opi%outer%imin)
285 safe_allocate_source_a(opo%outer%imax, opi%outer%imax)
286 safe_allocate_source_a(opo%outer%ri, opi%outer%ri)
313 class(
space_t),
intent(in) :: space
314 type(
mesh_t),
target,
intent(in) :: mesh
316 integer,
intent(in) :: np
317 logical,
optional,
intent(in) :: const_w
318 logical,
optional,
intent(in) :: regenerate
320 integer :: ii, jj, p1(space%dim), time, current
321 integer,
allocatable :: st1(:), st2(:), st1r(:)
322 integer :: ir, maxp, iinner, iouter
323 logical :: change, force_change
324 character(len=200) :: flags
325 integer,
allocatable :: inner_points(:), outer_points(:), all_points(:)
329 if (mesh%parallel_in_domains .and. .not. const_w)
then
344 safe_allocate(op%w(1:op%stencil%size, 1))
345 message(1) =
'Debug: nl_operator_build: working with constant weights.'
348 safe_allocate(op%w(1:op%stencil%size, 1:op%np))
349 message(1) =
'Debug: nl_operator_build: working with non-constant weights.'
357 safe_allocate(st1(1:op%stencil%size))
358 safe_allocate(st1r(1:op%stencil%size))
359 safe_allocate(st2(1:op%stencil%size))
368 do jj = 1, op%stencil%size
375 st1(1:op%stencil%size) = st1(1:op%stencil%size) - ii
377 change = any(st1 /= st2)
381 force_change = any(st1 + ii > mesh%np) .and. all(st2 + ii - 1 <= mesh%np)
384 if (change .or. force_change)
then
389 if (time == 1) op%nri = op%nri + 1
393 current = current + 1
394 op%ri(1:op%stencil%size, current) = st1(1:op%stencil%size)
398 if (time == 2) op%rimap(ii) = current
404 safe_deallocate_a(op%ri)
405 safe_deallocate_a(op%rimap)
406 safe_deallocate_a(op%rimap_inv)
408 safe_allocate(op%ri(1:op%stencil%size, 1:op%nri))
409 safe_allocate(op%rimap(1:op%np))
410 safe_allocate(op%rimap_inv(1:op%nri + 1))
417 if (mesh%use_curvilinear)
then
418 safe_allocate(op%nn(1:op%nri))
420 op%nn = op%stencil%size
429 op%rimap_inv(op%rimap(jj) + 1) = jj
431 op%rimap_inv(op%nri + 1) = op%np
433 safe_deallocate_a(st1)
434 safe_deallocate_a(st1r)
435 safe_deallocate_a(st2)
437 if (op%mesh%parallel_in_domains)
then
444 maxp = op%rimap_inv(ir + 1) + maxval(op%ri(1:op%stencil%size, ir))
447 op%inner%nri = op%inner%nri + 1
448 assert(op%inner%nri <= op%nri)
451 op%outer%nri = op%outer%nri + 1
452 assert(op%outer%nri <= op%nri)
456 assert(op%inner%nri + op%outer%nri == op%nri)
459 safe_deallocate_a(op%inner%imin)
460 safe_deallocate_a(op%inner%imax)
461 safe_deallocate_a(op%inner%ri)
462 safe_deallocate_a(op%outer%imin)
463 safe_deallocate_a(op%outer%imax)
464 safe_deallocate_a(op%outer%ri)
466 safe_allocate(op%inner%imin(1:op%inner%nri + 1))
467 safe_allocate(op%inner%imax(1:op%inner%nri))
468 safe_allocate(op%inner%ri(1:op%stencil%size, 1:op%inner%nri))
470 safe_allocate(op%outer%imin(1:op%outer%nri + 1))
471 safe_allocate(op%outer%imax(1:op%outer%nri))
472 safe_allocate(op%outer%ri(1:op%stencil%size, 1:op%outer%nri))
478 maxp = op%rimap_inv(ir + 1) + maxval(op%ri(1:op%stencil%size, ir))
482 op%inner%imin(iinner) = op%rimap_inv(ir)
483 op%inner%imax(iinner) = op%rimap_inv(ir + 1)
484 op%inner%ri(1:op%stencil%size, iinner) = op%ri(1:op%stencil%size, ir)
488 op%outer%imin(iouter) = op%rimap_inv(ir)
489 op%outer%imax(iouter) = op%rimap_inv(ir + 1)
490 op%outer%ri(1:op%stencil%size, iouter) = op%ri(1:op%stencil%size, ir)
495 do ir = 1, op%inner%nri
496 do ii = op%inner%imin(ir) + 1, op%inner%imax(ir)
497 assert(all(ii + op%inner%ri(1:op%stencil%size, ir) <= mesh%np))
505 write(flags,
'(i5)') op%stencil%size
506 flags=
'-DNDIM=3 -DSTENCIL_SIZE='//trim(adjustl(flags))
508 if (op%mesh%parallel_in_domains) flags =
'-DINDIRECT '//trim(flags)
510 select case (function_opencl)
521 select case (function_opencl)
533 if (op%mesh%parallel_in_domains)
then
535 safe_allocate(inner_points(1:op%mesh%np))
536 safe_allocate(outer_points(1:op%mesh%np))
537 safe_allocate(all_points(1:op%mesh%np))
542 do ii = 1, op%mesh%np
543 all_points(ii) = ii - 1
544 maxp = ii + maxval(op%ri(1:op%stencil%size, op%rimap(ii)))
545 if (maxp <= op%mesh%np)
then
546 op%ninner = op%ninner + 1
547 inner_points(op%ninner) = ii - 1
549 op%nouter = op%nouter + 1
550 outer_points(op%nouter) = ii - 1
563 safe_deallocate_a(inner_points)
564 safe_deallocate_a(outer_points)
565 safe_deallocate_a(all_points)
579 integer :: istencil, idir
583 write(
message(1),
'(3a)')
'Debug info: Finite difference weights for ', trim(this%label),
'.'
584 write(
message(2),
'(a)')
' Spacing:'
585 do idir = 1, this%mesh%box%dim
586 write(
message(2),
'(a,f16.8)') trim(
message(2)), this%mesh%spacing(idir)
590 do istencil = 1, this%stencil%size
591 select case(this%mesh%box%dim)
593 write(
message(1),
'(a,i3,1i4,f25.10)')
' ', istencil, this%stencil%points(1:1, istencil), this%w(istencil, 1)
595 write(
message(1),
'(a,i3,2i4,f25.10)')
' ', istencil, this%stencil%points(1:2, istencil), this%w(istencil, 1)
597 write(
message(1),
'(a,i3,3i4,f25.10)')
' ', istencil, this%stencil%points(1:3, istencil), this%w(istencil, 1)
616 safe_deallocate_a(op%inner%imin)
617 safe_deallocate_a(op%inner%imax)
618 safe_deallocate_a(op%inner%ri)
619 safe_deallocate_a(op%outer%imin)
620 safe_deallocate_a(op%outer%imax)
621 safe_deallocate_a(op%outer%ri)
623 safe_deallocate_a(op%w)
625 safe_deallocate_a(op%ri)
626 safe_deallocate_a(op%rimap)
627 safe_deallocate_a(op%rimap_inv)
628 safe_deallocate_a(op%nn)
642 select case (function_opencl)
649 if (op%mesh%parallel_in_domains)
then
671 integer,
intent(in) :: is
672 integer,
intent(in) :: ip
674 res = ip + op%ri(is, op%rimap(ip))
685 if (accel_is_enabled() .and. op%const_w)
then
686 call accel_create_buffer(op%buff_weights, accel_mem_read_only, type_float, op%stencil%size)
687 call accel_create_buffer(op%buff_half_weights, accel_mem_read_only, type_float, op%stencil%size)
702 if (accel_is_enabled() .and. op%const_w)
then
703 call accel_write_buffer(op%buff_weights, op%stencil%size, op%w(:, 1))
704 call accel_write_buffer(op%buff_half_weights, op%stencil%size, -m_half*op%w(:, 1))
719 ii = op%rimap_inv(jj + 1) + maxval(op%ri(1:op%stencil%size, jj))
720 np_bc = max(np_bc, ii)
730 type(space_t),
intent(in) :: space
731 class(mesh_t),
intent(in) :: mesh
734 real(real64),
parameter :: tol = 1.0e-14_real64
735 real(real64) :: max_weight, new_w(op%stencil%size)
736 integer :: new_points(space%dim, op%stencil%size)
738 if (.not. op%const_w)
return
742 max_weight = maxval(abs(op%w(:, 1)))
744 do ip = 1, op%stencil%size
745 if (abs(op%w(ip, 1)) > tol * max_weight)
then
747 new_w(size) = op%w(ip, 1)
748 new_points(:,size) = op%stencil%points(:, ip)
753 op%stencil%size =
size
754 safe_deallocate_a(op%stencil%points)
755 safe_allocate(op%stencil%points(space%dim, op%stencil%size))
756 op%stencil%points(:, :) = new_points(:, 1:size)
757 safe_deallocate_a(op%w)
760 op%w(1:
size, 1) = new_w(1:size)
767#include "nl_operator_inc.F90"
770#include "complex.F90"
771#include "nl_operator_inc.F90"
subroutine, public accel_kernel_build(this, file_name, kernel_name, flags)
subroutine, public accel_release_buffer(this, async)
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
integer pure function, public accel_max_workgroup_size()
This module implements batches of mesh functions.
Module implementing boundary conditions in Octopus.
real(real64), parameter, public m_zero
real(real64), parameter, public m_half
This module implements the index, used for the mesh points.
This module is intended to contain "only mathematical" functions and procedures.
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_local_index_to_coords(mesh, ip, ix)
Given a local point index, this function returns the set of integer coordinates of the point.
subroutine, public messages_obsolete_variable(namespace, name, rep)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module handles the communicators for the various parallelization strategies.
This module defines non-local operators.
subroutine, public dnl_operator_operate_diag(op, fo)
subroutine, public nl_operator_init(op, label)
initialize an instance of a non-local operator by setting the label
integer, parameter op_map
integer, parameter op_max
integer, parameter op_vec
subroutine, public dnl_operator_operate_batch(op, fi, fo, ghost_update, profile, points, factor, async)
subroutine nl_operator_clear_gpu_buffers(op)
subroutine, public dnl_operator_operate(op, fi, fo, ghost_update, profile, points)
subroutine, public nl_operator_update_gpu_buffers(op)
subroutine, public nl_operator_global_init(namespace)
initialize global settings for non-local operators
subroutine, public nl_operator_copy(opo, opi)
subroutine, public nl_operator_output_weights(this)
subroutine, public nl_operator_end(op)
integer, parameter, public op_inner
subroutine, public znl_operator_operate(op, fi, fo, ghost_update, profile, points)
subroutine, public nl_operator_remove_zero_weight_points(op, space, mesh)
Removes the zero-weight points for constant weight stencils.
subroutine, public nl_operator_global_end()
integer, parameter, public op_outer
subroutine, public nl_operator_build(space, mesh, op, np, const_w, regenerate)
Creates the nonlocal operators for the stencils used for finite differences.
subroutine, public znl_operator_operate_batch(op, fi, fo, ghost_update, profile, points, factor, async)
integer, parameter op_nomap
integer pure function, public nl_operator_np_zero_bc(op)
subroutine, public znl_operator_operate_diag(op, fo)
integer pure function, public nl_operator_get_index(op, is, ip)
subroutine, public nl_operator_allocate_gpu_buffers(op)
integer, parameter op_min
This module contains interfaces for routines in operate.c.
Some general things and nomenclature:
This module defines stencils used in Octopus.
subroutine, public stencil_end(this)
subroutine, public stencil_copy(input, output)
type(type_t), public type_float
type(type_t), public type_integer
Describes mesh distribution to nodes.
index type for non-local operators
data type for non local operators