Octopus
mesh_cube_parallel_map.F90
Go to the documentation of this file.
1!! Copyright (C) 2012-2014 M. Oliveira, J. Alberdi-Rodriguez
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use cube_oct_m
23 use debug_oct_m
24 use global_oct_m
25 use index_oct_m
26 use mesh_oct_m
29 use mpi_oct_m
34
35 implicit none
36
37 private
38 public :: &
42
44 ! Components are public by default
45 logical :: initialized = .false.
46
47 ! Mesh to cube:
48 type(partition_transfer_t) :: m2c
49 integer :: m2c_nsend
50 integer :: m2c_nrec
51 integer, allocatable :: m2c_mf_order(:)
54 integer, allocatable :: m2c_cf_order(:,:)
57
58 ! Cube to mesh:
59 type(partition_transfer_t) :: c2m
60 integer :: c2m_nsend
61 integer :: c2m_nrec
62 integer, allocatable :: c2m_cf_order(:,:)
65 integer, allocatable :: c2m_mf_order(:)
69
70contains
71
72 ! ---------------------------------------------------------
73 subroutine mesh_cube_parallel_map_init(this, mesh, cube)
74 type(mesh_cube_parallel_map_t), intent(out) :: this
75 type(mesh_t), intent(in) :: mesh
76 type(cube_t), intent(in) :: cube
77
78 integer :: ip, ixyz(3), lxyz(3), ipos, cube_np
79 integer :: ix, iy, iz
80 integer, allocatable :: cube_part_local(:)
81 integer(int64), allocatable :: global_index(:)
82 integer(int64), allocatable :: mf_order(:), cf_order(:)
83 integer(int64) :: ipg
84 type(dimensions_t), allocatable :: part(:)
85
86
88 call profiling_in("MC_PAR_INIT")
89
90 !Get the cube partition on the mesh and the number of local cube points that are also on the mesh
91 safe_allocate(part(1:cube%mpi_grp%size))
92 call cube_partition(cube, part)
93
94 ! Mesh to cube
95 ! We will work only with the local mesh points and we need to know the global index of those points.
96 safe_allocate(cube_part_local(1:mesh%np))
97 safe_allocate(global_index(1:mesh%np))
98 do ip = 1, mesh%np
99 global_index(ip) = mesh_local2global(mesh, ip)
100 call mesh_local_index_to_coords(mesh, ip, ixyz)
101 ixyz = ixyz + cube%center
102 cube_part_local(ip) = cube_point_to_process(ixyz, part)
103 end do
104
105 ! Init partition transfer
106 call partition_transfer_init(this%m2c, mesh%np, global_index, mesh%mpi_grp, &
107 cube%mpi_grp, cube_part_local, &
108 this%m2c_nsend, this%m2c_nrec, mf_order, cf_order)
109 ! Convert ordering of mesh and cube points from global mesh index to local mesh and cube indices
110 safe_allocate(this%m2c_mf_order(1:this%m2c_nsend))
111 safe_allocate(this%m2c_cf_order(1:this%m2c_nrec, 1:3))
112
113 ! Initialize all to 0, to detect possible errors
114 this%m2c_mf_order = 0
115
116 do ip = 1, this%m2c_nsend
117 this%m2c_mf_order(ip) = mesh_global2local(mesh, mf_order(ip))
118 if (this%m2c_mf_order(ip) == 0) then
119 write(message(1),'(a,i4,a,i4)') "Error in mesh_cube_parallel_map_init (m2c): mesh point ", &
120 mf_order(ip), " is not stored in partition ", mesh%pv%partno
121 call messages_fatal(1)
122 end if
123 end do
124
125 do ip = 1, this%m2c_nrec
126 call mesh_global_index_to_coords(mesh, cf_order(ip), ixyz)
127 ixyz = ixyz + cube%center
128
129 if (.not. cube_global2local(cube, ixyz, lxyz)) then
130 write(message(1),'(a,3i4,a,i4)') "Error in mesh_cube_parallel_map_init (m2c): cube point ", &
131 lxyz(1:3), " is not stored in partition ", cube%mpi_grp%rank + 1
132 call messages_fatal(1)
133 end if
134
135 this%m2c_cf_order(ip, 1:3) = lxyz(1:3)
136 end do
137 safe_deallocate_a(mf_order)
138 safe_deallocate_a(cf_order)
139 safe_deallocate_a(cube_part_local)
140 safe_deallocate_a(global_index)
143 ! Cube to mesh
144 assert(product(i4_to_i8(cube%rs_n)) < huge(0_int32))
145 cube_np = product(cube%rs_n)
146
147 ! We will work only with the local cube points and we need to know the global index of those points.
148 safe_allocate(cube_part_local(1:cube_np))
149 safe_allocate(global_index(1:cube_np))
150 ipos = 0
151 do iz = part(cube%mpi_grp%rank+1)%start_xyz(3), part(cube%mpi_grp%rank+1)%end_xyz(3)
152 do iy = part(cube%mpi_grp%rank+1)%start_xyz(2), part(cube%mpi_grp%rank+1)%end_xyz(2)
153 do ix = part(cube%mpi_grp%rank+1)%start_xyz(1), part(cube%mpi_grp%rank+1)%end_xyz(1)
154 ixyz(1) = ix
155 ixyz(2) = iy
156 ixyz(3) = iz
157 ixyz = ixyz - cube%center
159 ! do not map boundary points
160 if (ipg > 0 .and. ipg <= mesh%np_global) then
161 ipos = ipos + 1
162 global_index(ipos) = ipg
163 end if
164 end do
165 end do
166 end do
167 cube_np = ipos
168
169 if (mesh%parallel_in_domains) then
170 call partition_get_partition_number(mesh%partition, cube_np, global_index, cube_part_local)
171 else
172 cube_part_local = 1
173 end if
174
175 safe_deallocate_a(part)
176
177 ! Init partition transfer
178 call partition_transfer_init(this%c2m, cube_np, global_index, cube%mpi_grp, &
179 mesh%mpi_grp, cube_part_local, &
180 this%c2m_nsend, this%c2m_nrec, cf_order, mf_order)
181
182 ! Convert ordering of mesh and cube points from global mesh index to local mesh and cube indices
183 safe_allocate(this%c2m_cf_order(1:this%c2m_nsend, 1:3))
184 safe_allocate(this%c2m_mf_order(1:this%c2m_nrec))
185 do ip = 1, this%c2m_nsend
186 call mesh_global_index_to_coords(mesh, cf_order(ip), ixyz)
187 ixyz = ixyz + cube%center
188
189 if (.not. cube_global2local(cube, ixyz, lxyz)) then
190 write(message(1),'(a,3i4,a,i4)') "Error in mesh_cube_parallel_map_init (c2m): cube point ", &
191 lxyz(1:3), " is not stored in partition ", cube%mpi_grp%rank + 1
192 call messages_fatal(1)
193 end if
194 this%c2m_cf_order(ip, 1:3) = lxyz(1:3)
195 end do
196 do ip = 1, this%c2m_nrec
197 this%c2m_mf_order(ip) = mesh_global2local(mesh, mf_order(ip))
198 if (this%c2m_mf_order(ip) == 0) then
199 write(message(1),'(a,i3,a,i3)') "Error in mesh_cube_parallel_map_init (c2m): mesh point ", &
200 mf_order(ip), " is not stored in partition ", mesh%pv%partno
201 call messages_fatal(1)
202 end if
203 end do
204
205 safe_deallocate_a(mf_order)
206 safe_deallocate_a(cf_order)
207 safe_deallocate_a(cube_part_local)
208 safe_deallocate_a(global_index)
209
210 this%initialized = .true.
211
212 call profiling_out("MC_PAR_INIT")
214 end subroutine mesh_cube_parallel_map_init
215
216 ! ---------------------------------------------------------
217 subroutine mesh_cube_parallel_map_end(this)
218 type(mesh_cube_parallel_map_t), intent(inout) :: this
219
221
222 if (this%initialized) then
223 safe_deallocate_a(this%m2c_mf_order)
224 safe_deallocate_a(this%m2c_cf_order)
225 safe_deallocate_a(this%c2m_mf_order)
226 safe_deallocate_a(this%c2m_cf_order)
227 call partition_transfer_end(this%m2c)
228 call partition_transfer_end(this%c2m)
229 this%initialized = .false.
230 end if
231
233 end subroutine mesh_cube_parallel_map_end
234
236
237!! Local Variables:
238!! mode: f90
239!! coding: utf-8
240!! End:
logical function, public cube_global2local(cube, ixyz, lxyz)
True if global coordinates belong to this process. On output lxyz contains the local coordinates.
Definition: cube.F90:506
subroutine, public cube_partition(cube, part)
Definition: cube.F90:727
integer pure function, public cube_point_to_process(xyz, part)
Definition: cube.F90:679
This module implements the index, used for the mesh points.
Definition: index.F90:122
subroutine, public mesh_cube_parallel_map_end(this)
subroutine, public mesh_cube_parallel_map_init(this, mesh, cube)
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public mesh_global_index_to_coords(mesh, ipg, ix)
Given a global point index, this function returns the set of integer coordinates of the point.
Definition: mesh.F90:925
integer(int64) function, public mesh_global_index_from_coords(mesh, ix)
This function returns the true global index of the point for a given vector of integer coordinates.
Definition: mesh.F90:916
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:947
integer function, public mesh_global2local(mesh, ipg)
This function returns the local mesh index for a given global index.
Definition: mesh.F90:967
integer(int64) function, public mesh_local2global(mesh, ip)
This function returns the global mesh index for a given local index.
Definition: mesh.F90:959
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
Some general things and nomenclature:
Definition: par_vec.F90:171
subroutine, public partition_transfer_init(this, np, global_index, mpi_grp_in, mpi_grp_out, part_out, nsend, nrec, order_in, order_out, inverse)
initialize the partition transfer object
subroutine, public partition_transfer_end(this)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
int true(void)