Octopus
centroids.F90
Go to the documentation of this file.
1!! Copyright (C) 2024 A. Buccheri
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#include "global.h"
19
20module centroids_oct_m
21 use, intrinsic :: iso_fortran_env
22 use comm_oct_m, only: comm_allreduce
23 use debug_oct_m
24 use global_oct_m
25 use mesh_oct_m
27 use mpi_oct_m, only: mpi_comm
29
30 implicit none
31 private
32
33 public :: centroids_t
34
60 type centroids_t
61 private
62 integer :: ndim
63 real(real64), allocatable :: positions(:, :)
64 integer :: n_centroids_global
65 integer :: n_centroids
66 integer(int64), allocatable :: icg_to_ipg(:)
67 ! Kept private, but one could add a getter if required
68 integer, allocatable :: ic_to_icg(:)
69 integer, allocatable :: ic_to_ip(:)
70
71 contains
72 procedure :: init => centroids_init
73 procedure :: npoints => centroids_get_n_centroids
74 procedure :: npoints_global => centroids_get_n_centroids_global
75 procedure :: get_local_position => centroids_get_local_position
76 procedure :: get_all_positions => centroids_get_all_positions
77 ! ic -> ip
78 procedure :: to_local_mesh_index => centroids_get_local_mesh_index
79 procedure :: local_mesh_indices => centroids_get_local_mesh_indices
80 ! ic -> icg
81 procedure :: to_global_index => centroids_local_index_to_global_index
82 procedure :: global_indices => centroids_local_index_to_global_indices
83 ! ic -> ipg
84 procedure :: to_global_mesh_index => centroids_global_centroid_to_global_mesh_index
85 procedure :: global_mesh_indices => centroids_global_centroid_to_global_mesh_indices
86 final :: centroids_finalize
87 end type centroids_t
88
89contains
90
94 subroutine centroids_init(this, mesh, positions)
95 class(centroids_t), intent(out) :: this
96 class(mesh_t), intent(in ) :: mesh
97 real(real64), intent(in ) :: positions(:, :)
98
99 push_sub(centroids_init)
100
101 this%ndim = size(positions, 1)
102 this%n_centroids_global = size(positions, 2)
103 safe_allocate_source(this%positions(1:this%ndim, 1:this%n_centroids_global), positions)
104 call exact_centroids_init_index_maps(this, mesh)
105
106 pop_sub(centroids_init)
107
108 end subroutine centroids_init
109
110
112 pure function centroids_get_n_centroids(this) result(n_centroids)
113 class(centroids_t), intent(in) :: this
114 integer :: n_centroids
115
116 n_centroids = this%n_centroids
117
118 end function centroids_get_n_centroids
119
120
122 pure function centroids_get_n_centroids_global(this) result(n_centroids_global)
123 class(centroids_t), intent(in) :: this
124 integer :: n_centroids_global
125
126 n_centroids_global = this%n_centroids_global
127
129
130
141 pure function centroids_global_centroid_to_global_mesh_index(this, ic) result(ipg)
142 class(centroids_t), intent(in) :: this
143 integer, intent(in) :: ic
144 integer(int64) :: ipg
145 integer :: icg
146
147 icg = this%ic_to_icg(ic)
148 ipg = this%icg_to_ipg(icg)
149
151
152
154 pure function centroids_global_centroid_to_global_mesh_indices(this) result(global_mesh_indices)
155 class(centroids_t), intent(in) :: this
156 integer(int64), allocatable :: global_mesh_indices(:)
158 integer :: ic, icg
160 allocate(global_mesh_indices(this%n_centroids))
161 do ic = 1, this%n_centroids
162 icg = this%ic_to_icg(ic)
163 global_mesh_indices(ic) = this%icg_to_ipg(icg)
164 enddo
170 pure function centroids_get_local_mesh_index(this, ic) result(ip)
171 class(centroids_t), intent(in) :: this
172 integer, intent(in) :: ic
173 integer :: ip
175 ip = this%ic_to_ip(ic)
176
181 pure function centroids_get_local_mesh_indices(this) result(mesh_indices)
182 class(centroids_t), intent(in) :: this
183 integer, allocatable :: mesh_indices(:)
184
185 allocate(mesh_indices(this%n_centroids), source=this%ic_to_ip)
186
188
189
191 pure function centroids_local_index_to_global_index(this, ic) result(icg)
192 class(centroids_t), intent(in) :: this
193 integer, intent(in) :: ic
194 integer :: icg
195
196 icg = this%ic_to_icg(ic)
197
199
200
202 pure function centroids_local_index_to_global_indices(this) result(global_centroid_indices)
203 class(centroids_t), intent(in) :: this
204 integer, allocatable :: global_centroid_indices(:)
206 allocate(global_centroid_indices(this%n_centroids), source=this%ic_to_icg)
207
209
210
212 pure function centroids_get_local_position(this, mesh, ic) result(pos)
213 class(centroids_t), intent(in) :: this
214 class(mesh_t), intent(in) :: mesh
215 integer, intent(in) :: ic
216
217 real(real64) :: pos(this%ndim)
218
219 pos(:) = mesh%x(this%ic_to_ip(ic), :)
220
222
223
225 pure function centroids_get_all_positions(this) result(positions)
226 class(centroids_t), intent(in) :: this
227 real(real64), allocatable :: positions(:, :)
228
229 allocate(positions(this%ndim, this%n_centroids_global), source=this%positions)
230
231 end function centroids_get_all_positions
232
233
235 subroutine centroids_finalize(this)
236 type(centroids_t), intent(inout) :: this
237
238 safe_deallocate_a(this%positions)
239 safe_deallocate_a(this%icg_to_ipg)
240 safe_deallocate_a(this%ic_to_icg)
241
242 end subroutine centroids_finalize
243
244 ! Helper function for initialisation, hence not type-bound or exposed
245
256 subroutine exact_centroids_init_index_maps(this, mesh)
257 type(centroids_t), intent(inout) :: this
258 class(mesh_t), intent(in ) :: mesh
259
260 real(real64) :: chi(this%ndim)
261 integer :: ix(this%ndim)
262 integer :: icg, ip
263 integer(int64) :: ipg
264 integer, allocatable :: tmp_ic_to_icg(:), tmp_ic_to_ip(:)
265#if !defined(NDEBUG)
266 integer :: n_centroids_global
267#endif
268
270
271 safe_allocate(this%icg_to_ipg(1:this%n_centroids_global))
272
273 ! Local to this process
274 this%n_centroids = 0
275 ! Allocated with an upper bound
276 safe_allocate(tmp_ic_to_icg(1:this%n_centroids_global))
277 safe_allocate(tmp_ic_to_ip(1:this%n_centroids_global))
278
279 do icg = 1, this%n_centroids_global
280 chi = mesh%coord_system%from_cartesian(this%positions(:, icg))
281 ! See the definition of mesh_x_global, for example
282 ix = nint(chi / mesh%spacing)
283 ipg = mesh_global_index_from_coords(mesh, ix)
284 this%icg_to_ipg(icg) = ipg
285 ! Domain-specific indices
286 ip = mesh_global2local(mesh, ipg)
287 if (ip > 0 .and. ip <= mesh%np) then
288 this%n_centroids = this%n_centroids + 1
289 tmp_ic_to_icg(this%n_centroids) = icg
290 tmp_ic_to_ip(this%n_centroids) = ip
291 endif
292 enddo
293
294#if !defined(NDEBUG)
295 ! Total number of centroids must be conserved over all domains
296 n_centroids_global = this%n_centroids
297 call comm_allreduce(mesh%mpi_grp, n_centroids_global)
298 assert(n_centroids_global == this%n_centroids_global)
299#endif
300
301 ! Reallocate with correct size
302 safe_allocate_source(this%ic_to_icg(1:this%n_centroids), tmp_ic_to_icg(1:this%n_centroids))
303 safe_deallocate_a(tmp_ic_to_icg)
304
305 safe_allocate_source(this%ic_to_ip(1:this%n_centroids), tmp_ic_to_ip(1:this%n_centroids))
306 safe_deallocate_a(tmp_ic_to_ip)
307
309
311
312end module centroids_oct_m
313
314!! Local Variables:
315!! mode: f90
316!! coding: utf-8
317!! End:
pure integer(int64) function centroids_global_centroid_to_global_mesh_index(this, ic)
Given centroid index ic, return the global mesh index ipg.
Definition: centroids.F90:235
pure integer function, dimension(:), allocatable centroids_get_local_mesh_indices(this)
Return mesh indices ip for all centroids in this domain.
Definition: centroids.F90:275
subroutine centroids_finalize(this)
Finalize a centroids instance.
Definition: centroids.F90:329
pure integer function, dimension(:), allocatable centroids_local_index_to_global_indices(this)
Return global centroid indices for all centroids in this domain.
Definition: centroids.F90:296
subroutine exact_centroids_init_index_maps(this, mesh)
Initialise index maps with centroid points that are commensurate with the grid.
Definition: centroids.F90:350
subroutine centroids_init(this, mesh, positions)
Initialise a centroids_t instance.
Definition: centroids.F90:188
pure integer function centroids_local_index_to_global_index(this, ic)
Get the global centroid index, given centroid ic this domain.
Definition: centroids.F90:285
pure integer(int64) function, dimension(:), allocatable centroids_global_centroid_to_global_mesh_indices(this)
Return global mesh indices for all centroids in this domain.
Definition: centroids.F90:248
pure real(real64) function, dimension(this%ndim) centroids_get_local_position(this, mesh, ic)
Get the position of the centroid ic.
Definition: centroids.F90:306
pure integer function centroids_get_local_mesh_index(this, ic)
Get the mesh index ip of centroid ic in this domain.
Definition: centroids.F90:264
pure integer function centroids_get_n_centroids(this)
Number of centroids in local domain.
Definition: centroids.F90:206
pure real(real64) function, dimension(:, :), allocatable centroids_get_all_positions(this)
Return a copy of all centroid positions.
Definition: centroids.F90:319
pure integer function centroids_get_n_centroids_global(this)
Total number of centroids in system.
Definition: centroids.F90:216
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
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
integer function, public mesh_global2local(mesh, ipg)
This function returns the local mesh index for a given global index.
Definition: mesh.F90:969
Encapsulate centroid points and their indexing across a domain-decomposed mesh.
Definition: centroids.F90:153
Describes mesh distribution to nodes.
Definition: mesh.F90:186