Octopus
mesh_cube_map.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
23 use accel_oct_m
24 use debug_oct_m
25 use global_oct_m
26 use index_oct_m
27 use mesh_oct_m
30 use types_oct_m
31
32 implicit none
33
34 private
35 public :: &
39
41 ! Components are public by default
42 integer :: nmap
43 integer, allocatable :: map(:, :)
44 type(accel_mem_t) :: map_buffer
45 logical :: is_trivial = .false.
50 end type mesh_cube_map_t
51
52 integer, public, parameter :: MCM_POINT = 4, mcm_count = 5
53
54contains
55
56 ! ---------------------------------------------------------
57
58 subroutine mesh_cube_map_init(this, mesh, np)
59 type(mesh_cube_map_t), intent(out) :: this
60 class(mesh_t), intent(in) :: mesh
61 integer, intent(in) :: np
62
63 integer :: i1(1:3), i2(1:3)
64 integer :: step
65 integer :: ip
66 integer :: im, n1, n2, n3, expected_y, expected_z
67
68 push_sub(mesh_cube_map_init)
69
70 if (mesh%idx%dim <= 3) then
71 do step = 1, 2
72 if (step == 2) then
73 safe_allocate(this%map(1:5, 1:this%nmap))
74 end if
75
76 this%nmap = 0
77 i2 = 0
78 do ip = 1, np
79
80 i1 = 0
81 call mesh_local_index_to_coords(mesh, ip, i1)
82
83 if (any(i1(2:3) /= i2(2:3)) .or. i1(1) /= i2(1) + 1 .or. ip == 1) then
84 this%nmap = this%nmap + 1
85 if (step == 2) then
86 this%map(1:3, this%nmap) = i1(1:3)
87 this%map(mesh%idx%dim + 1:3, this%nmap) = 0
88 this%map(mcm_point, this%nmap) = ip
89 this%map(mcm_count, this%nmap) = 1
90 end if
91 else
92 if (step == 2) this%map(mcm_count, this%nmap) = this%map(mcm_count, this%nmap) + 1
93 end if
94 i2 = i1
95 end do
96 end do
97
98 ! Check whether the mesh ordering matches an X-fastest identity over the
99 ! full inner dimensions (mesh%idx%ll). When true, the scatter degenerates
100 ! to a flat memcopy and callers can short-circuit through a cheap path.
101 this%is_trivial = .false.
102 if (mesh%idx%dim == 3 .and. np == product(mesh%idx%ll(1:mesh%idx%dim)) &
103 .and. this%nmap > 0) then
104 n1 = mesh%idx%ll(1)
105 n2 = mesh%idx%ll(2)
106 n3 = mesh%idx%ll(3)
107 if (this%nmap == n2 * n3) then
108 ! Use segment 1 as the reference origin and verify every other
109 ! segment follows the X-fastest, Y-medium, Z-slowest pattern.
110 this%is_trivial = .true.
111 do im = 1, this%nmap
112 expected_y = this%map(2, 1) + mod(im - 1, n2)
113 expected_z = this%map(3, 1) + (im - 1) / n2
114 if (this%map(mcm_count, im) /= n1 .or. &
115 this%map(mcm_point, im) /= (im - 1) * n1 + 1 .or. &
116 this%map(1, im) /= this%map(1, 1) .or. &
117 this%map(2, im) /= expected_y .or. &
118 this%map(3, im) /= expected_z) then
119 this%is_trivial = .false.
120 exit
121 end if
122 end do
123 end if
124 end if
125
126 if (accel_is_enabled()) then
127 call accel_create_buffer(this%map_buffer, accel_mem_read_only, type_integer, this%nmap*5)
128 call accel_write_buffer(this%map_buffer, 5, this%nmap, this%map)
129 end if
130
131 end if
132
133 pop_sub(mesh_cube_map_init)
134 end subroutine mesh_cube_map_init
136 ! ---------------------------------------------------------
138 subroutine mesh_cube_map_end(this)
139 type(mesh_cube_map_t), intent(inout) :: this
141 push_sub(mesh_cube_map_end)
142
143 if (allocated(this%map)) then
144
145 safe_deallocate_a(this%map)
146
147 if (accel_is_enabled()) call accel_free_buffer(this%map_buffer)
148
149 end if
150
151 pop_sub(mesh_cube_map_end)
152 end subroutine mesh_cube_map_end
154 ! ---------------------------------------------------------
155
156end module mesh_cube_map_oct_m
157
158!! Local Variables:
159!! mode: f90
160!! coding: utf-8
161!! End:
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:1005
pure logical function, public accel_is_enabled()
Definition: accel.F90:402
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
This module implements the index, used for the mesh points.
Definition: index.F90:124
subroutine, public mesh_cube_map_end(this)
integer, parameter, public mcm_count
subroutine, public mesh_cube_map_init(this, mesh, np)
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
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
type(type_t), public type_integer
Definition: types.F90:137
int true(void)