21 use,
intrinsic :: iso_fortran_env
67 real(real64),
allocatable :: positions(:, :)
68 integer :: n_centroids_global
69 integer :: n_centroids
70 integer(int64),
allocatable :: icg_to_ipg(:)
73 integer,
allocatable :: ic_to_icg(:)
74 integer,
allocatable :: ic_to_ip(:)
106 subroutine centroids_init(this, mesh, positions, check_duplicates)
107 class(centroids_t),
intent(out) :: this
108 class(mesh_t),
intent(in ) :: mesh
109 real(real64),
intent(in ) :: positions(:, :)
110 logical,
optional,
intent(in ) :: check_duplicates
115 this%ndim =
size(positions, 1)
116 this%n_centroids_global =
size(positions, 2)
117 safe_allocate_source(this%positions(1:this%ndim, 1:this%n_centroids_global), positions)
128 class(centroids_t),
intent(out) :: this
129 class(mesh_t),
intent(in ) :: mesh
130 character(len=*),
intent(in ) :: fname
131 logical,
optional,
intent(in ) :: check_duplicates
135 this%ndim = mesh%box%dim
148 class(centroids_t),
intent(in) :: this
149 integer :: n_centroids
151 n_centroids = this%n_centroids
158 class(centroids_t),
intent(in) :: this
159 integer :: n_centroids_global
161 n_centroids_global = this%n_centroids_global
178 integer,
intent(in) :: ic
179 integer(int64) :: ipg
182 icg = this%ic_to_icg(ic)
183 ipg = this%icg_to_ipg(icg)
191 integer(int64),
allocatable :: global_mesh_indices(:)
195 allocate(global_mesh_indices(this%n_centroids))
196 do ic = 1, this%n_centroids
197 icg = this%ic_to_icg(ic)
198 global_mesh_indices(ic) = this%icg_to_ipg(icg)
207 integer,
intent(in) :: ic
210 ip = this%ic_to_ip(ic)
218 integer,
allocatable :: mesh_indices(:)
220 allocate(mesh_indices(this%n_centroids), source=this%ic_to_ip)
228 integer,
intent(in) :: ic
231 icg = this%ic_to_icg(ic)
239 integer,
allocatable :: global_centroid_indices(:)
241 allocate(global_centroid_indices(this%n_centroids), source=this%ic_to_icg)
249 class(
mesh_t),
intent(in) :: mesh
250 integer,
intent(in) :: ic
252 real(real64) :: pos(this%ndim)
254 pos(:) = mesh%x(this%ic_to_ip(ic), :)
262 real(real64),
allocatable :: positions(:, :)
264 allocate(positions(this%ndim, this%n_centroids_global), source=this%positions)
274 character(len=*),
intent(in) :: fname
280 write(
message(1),
'(a)')
'Info: Writing interpolation points to file: ' // trim(adjustl(fname))
283 unit =
io_open(trim(adjustl(fname)), action=
'write', grp=grp)
285 if (grp%is_root())
then
286 write(unit, *)
'N centroids', this%n_centroids_global
287 do icg = 1, this%n_centroids_global
288 write(unit, *) this%icg_to_ipg(icg)
302 character(len=*),
intent(in ) :: fname
303 integer,
intent(out) :: n_centroids_global
305 integer(int64),
allocatable,
intent(out) :: icg_to_ipg(:)
308 integer :: icg, iunit
309 character(len=11) :: dummy
313 iunit =
io_open(trim(adjustl(fname)), action=
'read', grp=grp)
315 if (grp%is_root())
then
316 read(iunit, *) dummy, n_centroids_global
317 safe_allocate(icg_to_ipg(1:n_centroids_global))
318 do icg = 1, n_centroids_global
319 read(iunit, *) icg_to_ipg(icg)
325 call grp%bcast(n_centroids_global, 1, mpi_integer, 0)
326 if (.not. grp%is_root()) safe_allocate(icg_to_ipg(1:n_centroids_global))
327 call grp%bcast(icg_to_ipg, n_centroids_global, mpi_integer8, 0)
340 safe_deallocate_a(this%positions)
341 safe_deallocate_a(this%icg_to_ipg)
342 safe_deallocate_a(this%ic_to_icg)
343 safe_deallocate_a(this%ic_to_ip)
366 class(
mesh_t),
intent(in ) :: mesh
368 real(real64) :: chi(this%ndim)
369 integer :: ix(this%ndim)
371 integer(int64) :: ipg
376 safe_allocate(this%icg_to_ipg(1:this%n_centroids_global))
377 do icg = 1, this%n_centroids_global
378 chi = mesh%coord_system%from_cartesian(this%positions(:, icg))
380 ix = nint(chi / mesh%spacing)
382 this%icg_to_ipg(icg) = ipg
393 class(
mesh_t),
intent(in ) :: mesh
396 integer(int64) :: ipg
400 safe_allocate(this%positions(1:this%ndim, 1:this%n_centroids_global))
402 do icg = 1, this%n_centroids_global
403 ipg = this%icg_to_ipg(icg)
421 class(
mesh_t),
intent(in ) :: mesh
422 logical,
intent(in ) :: check_duplicates
426 integer(int64) :: ipg
427 integer,
allocatable :: tmp_ic_to_icg(:), tmp_ic_to_ip(:)
429 integer :: n_centroids_global
439 if (check_duplicates)
then
441 this%n_centroids_global =
size(this%icg_to_ipg)
447 safe_allocate(tmp_ic_to_icg(1:this%n_centroids_global))
448 safe_allocate(tmp_ic_to_ip(1:this%n_centroids_global))
451 do icg = 1, this%n_centroids_global
452 ipg = this%icg_to_ipg(icg)
454 if (ip > 0 .and. ip <= mesh%np)
then
455 this%n_centroids = this%n_centroids + 1
456 tmp_ic_to_icg(this%n_centroids) = icg
457 tmp_ic_to_ip(this%n_centroids) = ip
463 n_centroids_global = this%n_centroids
465 assert(n_centroids_global == this%n_centroids_global)
469 safe_allocate_source(this%ic_to_icg(1:this%n_centroids), tmp_ic_to_icg(1:this%n_centroids))
470 safe_deallocate_a(tmp_ic_to_icg)
472 safe_allocate_source(this%ic_to_ip(1:this%n_centroids), tmp_ic_to_ip(1:this%n_centroids))
473 safe_deallocate_a(tmp_ic_to_ip)
481 integer(int64),
intent(inout),
allocatable :: indices(:)
484 integer :: n_duplicates, cnt, n, i
485 integer(int64),
allocatable :: unique_indices(:)
492 allocate(unique_indices(n))
496 unique_indices(1) = indices(1)
499 if (indices(i) == indices(i+1))
then
500 n_duplicates = n_duplicates + 1
504 unique_indices(cnt) = indices(i+1)
507 safe_deallocate_a(indices)
508 safe_allocate_source(indices(1:cnt), unique_indices(1:cnt))
509 safe_deallocate_a(unique_indices)
511 if (
debug%info .and. n_duplicates > 0)
then
512 write(
message(1),
'(I0)') n_duplicates
513 message(1) = trim(
message(1)) //
" duplicates found after discretisation of centroid positions"
515 message(2) =
" Removed the duplicate/s and resized 'indices' array to " // trim(
message(2))
This is the common interface to a sorting routine. It performs the shell algorithm,...
subroutine centroids_init_from_file(this, mesh, fname, check_duplicates)
Initialise a centroids_t instance from grid points in file.
subroutine centroids_end(this)
Type-bound routine to manually deallocate a centroids instance.
pure integer(int64) function centroids_global_centroid_to_global_mesh_index(this, ic)
Given centroid index ic, return the global mesh index ipg.
subroutine, public centroids_read_all_indices(grp, fname, n_centroids_global, icg_to_ipg)
Read all centroid indices from a file written using centroids_output_all_indices.
subroutine remove_duplicates_int64(indices)
Remove duplicates from an array of integers.
pure integer function, dimension(:), allocatable centroids_get_local_mesh_indices(this)
Return mesh indices ip for all centroids in this domain.
subroutine centroids_finalize(this)
Finalize a centroids instance.
subroutine convert_coordinates_to_global_indices(this, mesh)
Convert coordinates to the mesh global index.
pure integer function, dimension(:), allocatable centroids_local_index_to_global_indices(this)
Return global centroid indices for all centroids in this domain.
pure integer function centroids_local_index_to_global_index(this, ic)
Get the global centroid index, given centroid ic this domain.
subroutine centroids_init(this, mesh, positions, check_duplicates)
Initialise a centroids_t instance.
pure integer(int64) function, dimension(:), allocatable centroids_global_centroid_to_global_mesh_indices(this)
Return global mesh indices for all centroids in this domain.
pure real(real64) function, dimension(this%ndim) centroids_get_local_position(this, mesh, ic)
Get the position of the centroid ic.
subroutine centroids_output_all_indices(this, namespace, grp, fname)
Output all centroid indices, across all domains.
subroutine exact_centroids_init_index_maps(this, mesh, check_duplicates)
Initialise index maps with centroid points that are commensurate with the grid.
subroutine convert_global_indices_to_coordinates(this, mesh)
Convert mesh global index to coordinates.
pure integer function centroids_get_local_mesh_index(this, ic)
Get the mesh index ip of centroid ic in this domain.
pure integer function centroids_get_n_centroids(this)
Number of centroids in local domain.
pure real(real64) function, dimension(:, :), allocatable centroids_get_all_positions(this)
Return a copy of all centroid positions.
pure integer function centroids_get_n_centroids_global(this)
Total number of centroids in system.
type(debug_t), save, public debug
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
This module defines the meshes, which are used in Octopus.
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.
integer function, public mesh_global2local(mesh, ipg)
This function returns the local mesh index for a given global index.
real(real64) function, dimension(1:mesh%box%dim), public mesh_x_global(mesh, ipg)
Given a global point index, this function returns the coordinates of the point.
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module is intended to contain "only mathematical" functions and procedures.
Encapsulate centroid points and their indexing across a domain-decomposed mesh.
Describes mesh distribution to nodes.
This is defined even when running serial.