Octopus
test_kmeans_clustering.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
19#include "global.h"
20
22 use, intrinsic :: iso_fortran_env
24 use debug_oct_m
26 use global_oct_m
29 use lcao_oct_m, only: lcao_run
31 use mpi_oct_m, only: mpi_world
37
39
40 implicit none
41 private
42 public :: test_weighted_kmeans
43
44contains
45
47 subroutine write_xyz(namespace, fname, position, species)
48 type(namespace_t), intent(in) :: namespace
49 character(len=*), intent(in) :: fname
50 real(real64), intent(in) :: position(:, :)
51 character(len=*), intent(in) :: species(:)
52
53 integer :: iunit, iatom
54
55 iunit = io_open(trim(fname)//'.xyz', namespace, action='write', position='asis')
56
57 if (mpi_world%is_root()) then
58 write(iunit, '(i6)') size(position, 2)
59 write(iunit, *)
60
61 do iatom = 1, size(position, 2)
62 write(iunit, '(A, 1X, 3(F11.6, 1X))') trim(species(iatom)), position(:, iatom) / unit_angstrom%factor
63 end do
64 endif
65
66 call io_close(iunit)
67
68 end subroutine write_xyz
69
74 subroutine test_weighted_kmeans(namespace)
75 type(namespace_t), intent(in) :: namespace
76
77 type(electrons_t), pointer :: sys
78 integer :: ierr
79
80 ! Kmeans
81 integer :: n_centroids
82 real(real64) :: inertia
83 integer(int64), allocatable :: seeds(:)
84 real(real64), allocatable :: centroids(:, :)
85 character(len=1), allocatable :: dummy_species(:)
86
87 push_sub(test_weighted_kmeans)
88
89 ! Set up a system of electrons
90 call calc_mode_par%set_parallelization(p_strategy_states, default=.false.)
91 ! If this is false, the code will crash in v_ks_calc
92 sys => electrons_t(namespace, generate_epot=.true.)
93 call sys%init_parallelization(mpi_world)
94 call states_elec_allocate_wfns(sys%st, sys%gr)
95
96 ! Guess at density using lcao
97 call lcao_run(namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, &
98 sys%st, sys%ks, sys%hm, lmm_r = lmm_r_single_atom)
99
100 call io_mkdir(static_dir)
101
102 ! Output the density: reference xc_vxc_inc.F90
103 ! Where the second dim of rho is the spin channel
104 call dio_function_output(option__outputformat__cube, static_dir, 'rho', namespace, sys%space, sys%gr, &
105 sys%st%rho(:, 1), unit_one, ierr, pos=sys%ions%pos, atoms=sys%ions%atom)
106
107 ! Test with a small number of centroids
108 n_centroids = 20
109
110 allocate(dummy_species(n_centroids), source='A')
111 ! Random seed fixed for test reproducibility
112 allocate(seeds(1), source=int(101, int64))
113 safe_allocate(centroids(1:sys%space%dim, 1:n_centroids))
115 call sample_initial_centroids(sys%gr, centroids, seed_value=seeds(1))
116 call write_xyz(namespace, static_dir // "initial_centroids", centroids, dummy_species)
117
118 call weighted_kmeans(sys%space, sys%gr, sys%st%rho(1:sys%gr%np, 1), centroids, inertia=inertia)
119 write(message(1), '(a, f18.12)') "test_weighted_kmeans: inertia", inertia
120 call messages_info(1)
121
122 dummy_species = 'B'
123 call write_xyz(namespace, static_dir // "final_centroids", centroids, dummy_species)
124
125 ! Free data
126 deallocate(seeds)
127 deallocate(dummy_species)
128 safe_deallocate_a(centroids)
129 call states_elec_deallocate_wfns(sys%st)
130 safe_deallocate_p(sys)
131
132 pop_sub(test_weighted_kmeans)
133
134 end subroutine test_weighted_kmeans
135
137
138!! Local Variables:
139!! mode: f90
140!! coding: utf-8
141!! End:
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
real(real64), parameter, public lmm_r_single_atom
Default local magnetic moments sphere radius for an isolated system.
Definition: global.F90:216
character(len= *), parameter, public static_dir
Definition: global.F90:252
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
Definition: io.F90:114
subroutine, public io_close(iunit, grp)
Definition: io.F90:418
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:311
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:352
subroutine, public weighted_kmeans(space, mesh, weight, centroids, n_iter, centroid_tol, discretize, inertia)
Weighted K-means clustering.
subroutine, public sample_initial_centroids(mesh, centroids, seed_value)
Sample initial centroids from the full mesh.
subroutine, public lcao_run(namespace, space, gr, ions, ext_partners, st, ks, hm, st_start, lmm_r)
Definition: lcao.F90:796
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
subroutine write_xyz(namespace, fname, position, species)
Simplified xyz output for finite systems.
subroutine, public test_weighted_kmeans(namespace)
Test weighted kmeans algorithm for a finite system.
This module defines the unit system, used for input and output.
type(unit_t), public unit_angstrom
For XYZ files.
type(unit_t), public unit_one
some special units required for particular quantities
Class describing the electron system.
Definition: electrons.F90:218
int true(void)