Line data Source code
1 : !!****p* ABINIT/mrgdv
2 : !! NAME
3 : !! mrgdv
4 : !!
5 : !! FUNCTION
6 : !! This program merges DFPT potentials for different q-vectors and perturbations.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2004-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public Licence, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
14 : !!
15 : !! NOTES
16 : !! DVDB file format:
17 : !! version (integer)
18 : !! number of potentials (integer)
19 : !! for each potential:
20 : !! Abinit header with info on the perturbation and the FFT mesh
21 : !! potential on the FFT mesh
22 : !!
23 : !! SOURCE
24 :
25 : #if defined HAVE_CONFIG_H
26 : #include "config.h"
27 : #endif
28 :
29 : #include "abi_common.h"
30 :
31 34 : program mrgdv
32 :
33 34 : use defs_basis
34 : use m_xmpi
35 : use m_errors
36 : use m_abicore
37 :
38 : use m_build_info, only : abinit_version
39 : use m_specialmsg, only : specialmsg_getcount, herald
40 : use m_fstrings, only : sjoin, itoa, ltoa
41 : use m_io_tools, only : file_exists, prompt
42 : use m_argparse, only : get_arg, get_arg_list
43 : use m_fftcore, only : ngfft_seq
44 : use m_dvdb, only : dvdb_t, dvdb_merge_files, dvdb_test_v1complete, dvdb_test_ftinterp, dvdb_test_v1rsym, &
45 : dvdb_test_symcheck, dvdb_test_symcheck_native
46 :
47 : implicit none
48 :
49 : !Local variables-------------------------------
50 : !scalars
51 : integer,parameter :: gpu_option0 = 0
52 : integer :: ii, nargs, nfiles, comm, prtvol, my_rank, lenr, dvdb_add_lr, rspace_cell, symv1scf, npert_miss, abimem_level
53 : integer :: isym, itimrev
54 : real(dp) :: dvdb_qdamp, abimem_limit_mb
55 : character(len=24) :: codename
56 : character(len=500) :: command, arg, msg
57 : character(len=fnlen) :: dvdb_filepath, dump_file, ddb_filepath
58 2788 : type(dvdb_t) :: dvdb
59 : !arrays
60 : integer :: ngqpt(3), coarse_ngqpt(3), ngfftf(18), qptopt, g0q(3)
61 : real(dp) :: qpt_source(3), qpt_target(3)
62 34 : character(len=fnlen),allocatable :: v1files(:)
63 : ! *************************************************************************
64 :
65 : ! Change communicator for I/O (mandatory!)
66 34 : call abi_io_redirect(new_io_comm=xmpi_world)
67 :
68 : ! Initialize MPI
69 34 : call xmpi_init()
70 34 : comm = xmpi_world
71 34 : my_rank = xmpi_comm_rank(comm)
72 :
73 : ! Initialize memory profiling if it is activated
74 : ! if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
75 : ! note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
76 34 : ABI_CHECK(get_arg("abimem-level", abimem_level, msg, default=0) == 0, msg)
77 34 : ABI_CHECK(get_arg("abimem-limit-mb", abimem_limit_mb, msg, default=20.0_dp) == 0, msg)
78 : #ifdef HAVE_MEM_PROFILING
79 : call abimem_init(abimem_level, limit_mb=abimem_limit_mb)
80 : #endif
81 :
82 : ! write greating,read the file names, etc.
83 34 : codename='MRGDV'//repeat(' ',18)
84 34 : call herald(codename, abinit_version, std_out)
85 :
86 34 : ABI_CHECK(xmpi_comm_size(comm) == 1, "Not programmed for parallel execution")
87 34 : ABI_CHECK(get_arg("prtvol", prtvol, msg, default=0) == 0, msg)
88 :
89 34 : nargs = command_argument_count()
90 :
91 34 : if (nargs == 0) then
92 : ! We are reading from stdin
93 : ! Prepend prompt with `-` to bypass bug in intel18-19
94 34 : call prompt("Enter name of output file:", dvdb_filepath)
95 34 : call prompt("Enter total number of DFPT POT files:", nfiles)
96 34 : ABI_MALLOC(v1files, (nfiles))
97 592 : do ii=1,nfiles
98 592 : call prompt(sjoin("Enter name of POT file", itoa(ii), ":"), v1files(ii))
99 : end do
100 34 : call dvdb_merge_files(nfiles, v1files, dvdb_filepath, prtvol)
101 68 : ABI_FREE(v1files)
102 :
103 : else
104 : ! Command line options.
105 0 : do ii=1,command_argument_count()
106 0 : call get_command_argument(ii, arg)
107 0 : if (arg == "-v" .or. arg == "--version") then
108 0 : write(std_out,"(a)") trim(abinit_version); goto 100
109 :
110 0 : else if (arg == "-h" .or. arg == "--help") then
111 : ! Document the options.
112 0 : write(std_out,*)"-v, --version Show version number and exit."
113 0 : write(std_out,*)"merge out_DVDB POT1 POT2 Merge list of POT files, produce out_DVDB file."
114 0 : write(std_out,*)"info out_DVDB Print information on DVDB file"
115 0 : write(std_out,*)"-h, --help Show this help and exit."
116 0 : write(std_out,*)" "
117 0 : write(std_out,*)"=== Options for developers ==="
118 0 : write(std_out,*)" "
119 0 : write(std_out,*)"test_v1complete FILE [--symv1scf 1] [--potfile foo.nc]"
120 0 : write(std_out,*)" Test symmetrization of DFPT potentials with symv1scf option"
121 0 : write(std_out,*)" Assume DVDB with all 3*natom perturbations for each q (use prep_gkk)."
122 0 : write(std_out,*)"test_v1rsym [--symv1scf] Test symmetries of DFPT potentials in real space."
123 0 : write(std_out,*)"test_ftinterp in_DVDB --ngqpt 4 4 4 [--ddb-path] [--dvdb-add-lr 0] [--qdamp -1]"
124 0 : write(std_out,*)" [--symv1scf] [--coarse-ngqpt 2 2 2] [--potfile foo.nc]"
125 0 : write(std_out,*)" Test Fourier interpolation of DFPT potentials."
126 0 : write(std_out,*)" --potfile: dump ab-initio and interpolated V1(r) to netcdf for plotting."
127 0 : write(std_out,*)"test_symcheck in_DVDB --ngqpt 4 4 4 --qpt 0.1 0.2 0.3 [--ddb-path]"
128 0 : write(std_out,*)" [--dvdb-add-lr 0] [--qdamp -1] [--symv1scf] [--rspace_cell 1]"
129 0 : write(std_out,*)" [--potfile foo.nc]"
130 0 : write(std_out,*)" Test cross-q-point symmetry consistency of the FT interpolation:"
131 0 : write(std_out,*)" interpolate at --qpt and at S.qpt for every symmetry S, compare"
132 0 : write(std_out,*)" against v1phq_rotate's own prediction from --qpt alone."
133 0 : write(std_out,*)" --potfile: dump target/predicted V1(r) to netcdf for plotting."
134 0 : write(std_out,*)"test_symcheck_native in_DVDB --sym-dvdb other_DVDB --qpt_source 0.25 0 0"
135 0 : write(std_out,*)" --qpt_target -0.25 0 0 [--isym 2] [--itimrev 1] [--g0q 0 0 0]"
136 0 : write(std_out,*)" Like test_symcheck but on TWO LITERAL, already-present q-points"
137 0 : write(std_out,*)" (no Fourier interpolation at all): tests v1phq_rotate alone."
138 0 : write(std_out,*)" --sym-dvdb supplies the crystal's TRUE symmetry table (in_DVDB's"
139 0 : write(std_out,*)" own is typically nsym=1, e.g. if built to force literal, per-q"
140 0 : write(std_out,*)" independent computation of every perturbation)."
141 0 : write(std_out,*)"downsample in_DVDB out_DVDB [n1, n2, n3] Produce new DVDB with q-subsmesh"
142 0 : goto 100
143 : end if
144 : end do
145 :
146 0 : call get_command_argument(1, command)
147 :
148 0 : select case (command)
149 : case ("merge")
150 : ! Get name of output database and list of v1 files.
151 0 : ABI_CHECK(nargs > 1, "Additional arguments are missing")
152 0 : call get_command_argument(2, dvdb_filepath)
153 0 : if (file_exists(dvdb_filepath)) then
154 0 : ABI_ERROR(sjoin("Cannot overwrite existing file:", dvdb_filepath))
155 : end if
156 :
157 0 : nfiles = nargs - 2
158 0 : ABI_MALLOC(v1files, (nfiles))
159 0 : do ii=1,nfiles
160 0 : call get_command_argument(ii+2, v1files(ii))
161 : end do
162 :
163 : ! Merge POT files.
164 0 : call dvdb_merge_files(nfiles, v1files, dvdb_filepath, prtvol)
165 0 : ABI_FREE(v1files)
166 :
167 : case ("info")
168 : ! Get name of output database and list of v1 files.
169 0 : ABI_CHECK(nargs > 1, "Additional arguments are missing")
170 0 : call get_command_argument(2, dvdb_filepath)
171 :
172 0 : call dvdb%init(dvdb_filepath, gpu_option0, comm)
173 0 : if (prtvol > 0) call dvdb%print([std_out], "", prtvol=prtvol)
174 0 : call dvdb%list_perts([-1, -1, -1], npert_miss)
175 0 : call dvdb%free()
176 :
177 : case ("test_v1comp", "test_v1complete")
178 0 : call wrtout(std_out," Testing symmetries (assuming overcomplete DVDB, pass extra argument to dump v1(r)) to file")
179 0 : call get_command_argument(2, dvdb_filepath)
180 0 : ABI_CHECK(get_arg("symv1scf", symv1scf, msg, default=0) == 0, msg)
181 0 : ABI_CHECK(get_arg("potfile", dump_file, msg, default="") == 0, msg)
182 0 : call dvdb_test_v1complete(dvdb_filepath, symv1scf, dump_file, comm)
183 :
184 : case ("test_v1rsym")
185 0 : call wrtout(std_out," Testing symmetries of V1(r) in real space.")
186 0 : call get_command_argument(2, dvdb_filepath)
187 0 : ABI_CHECK(get_arg("symv1scf", symv1scf, msg, default=0) == 0, msg)
188 0 : call dvdb_test_v1rsym(dvdb_filepath, symv1scf, comm)
189 :
190 : case ("test_ftinterp")
191 0 : call get_command_argument(2, dvdb_filepath)
192 0 : ABI_CHECK(get_arg_list("ngqpt", ngqpt, lenr, msg, default=2, want_len=3) == 0, msg)
193 0 : ABI_CHECK(get_arg("ddb-path", ddb_filepath, msg, default="") == 0, msg)
194 0 : ABI_CHECK(get_arg("rspace_cell", rspace_cell, msg, default=0) == 0, msg)
195 0 : ABI_CHECK(get_arg("symv1scf", symv1scf, msg, default=0) == 0, msg)
196 0 : ABI_CHECK(get_arg("dvdb-add-lr", dvdb_add_lr, msg, default=1) == 0, msg)
197 0 : ABI_CHECK(get_arg("qdamp", dvdb_qdamp, msg, default=0.1_dp) == 0, msg)
198 0 : ABI_CHECK(get_arg_list("coarse-ngqpt", coarse_ngqpt, lenr, msg, default=0, want_len=3) == 0, msg)
199 0 : ABI_CHECK(get_arg("potfile", dump_file, msg, default="") == 0, msg)
200 : call dvdb_test_ftinterp(dvdb_filepath, rspace_cell, symv1scf, ngqpt, dvdb_add_lr, dvdb_qdamp, &
201 0 : ddb_filepath, prtvol, coarse_ngqpt, dump_file, comm)
202 :
203 : case ("test_symcheck")
204 0 : call get_command_argument(2, dvdb_filepath)
205 0 : ABI_CHECK(get_arg_list("ngqpt", ngqpt, lenr, msg, want_len=3) == 0, msg)
206 0 : ABI_CHECK(get_arg_list("qpt", qpt_source, lenr, msg, want_len=3) == 0, msg)
207 0 : ABI_CHECK(get_arg("ddb-path", ddb_filepath, msg, default="") == 0, msg)
208 0 : ABI_CHECK(get_arg("rspace_cell", rspace_cell, msg, default=0) == 0, msg)
209 0 : ABI_CHECK(get_arg("symv1scf", symv1scf, msg, default=0) == 0, msg)
210 0 : ABI_CHECK(get_arg("dvdb-add-lr", dvdb_add_lr, msg, default=1) == 0, msg)
211 0 : ABI_CHECK(get_arg("qdamp", dvdb_qdamp, msg, default=0.1_dp) == 0, msg)
212 0 : ABI_CHECK(get_arg("potfile", dump_file, msg, default="") == 0, msg)
213 : call dvdb_test_symcheck(dvdb_filepath, rspace_cell, symv1scf, ngqpt, dvdb_add_lr, dvdb_qdamp, &
214 0 : ddb_filepath, prtvol, qpt_source, dump_file, comm)
215 :
216 : case ("test_symcheck_native")
217 0 : call get_command_argument(2, dvdb_filepath)
218 0 : ABI_CHECK(get_arg("sym-dvdb", ddb_filepath, msg, default="") == 0, msg)
219 0 : ABI_CHECK(get_arg_list("qpt_source", qpt_source, lenr, msg, want_len=3) == 0, msg)
220 0 : ABI_CHECK(get_arg_list("qpt_target", qpt_target, lenr, msg, want_len=3) == 0, msg)
221 0 : ABI_CHECK(get_arg("isym", isym, msg, default=1) == 0, msg)
222 0 : ABI_CHECK(get_arg("itimrev", itimrev, msg, default=1) == 0, msg)
223 0 : ABI_CHECK(get_arg_list("g0q", g0q, lenr, msg, default=0, want_len=3) == 0, msg)
224 0 : call dvdb_test_symcheck_native(dvdb_filepath, ddb_filepath, qpt_source, qpt_target, isym, itimrev, g0q, comm)
225 :
226 : case ("downsample")
227 0 : call get_command_argument(2, dvdb_filepath)
228 0 : call get_command_argument(3, dump_file)
229 0 : ABI_CHECK(get_arg_list("ngqpt", ngqpt, lenr, msg, want_len=3) == 0, msg)
230 0 : ABI_CHECK(get_arg("qptopt", qptopt, msg, default=1) == 0, msg)
231 0 : write(std_out,"(a)")sjoin(" Downsampling q-mesh with ngqpt:", ltoa(ngqpt))
232 0 : write(std_out,"(a)")sjoin(" qptopt:", itoa(qptopt))
233 0 : write(std_out,"(a)")trim(dvdb_filepath), " --> ", trim(dump_file)
234 :
235 0 : call dvdb%init(dvdb_filepath, gpu_option0, xmpi_comm_self)
236 0 : call ngfft_seq(ngfftf, dvdb%ngfft3_v1(:, 1))
237 0 : call dvdb%open_read(ngfftf, xmpi_comm_self)
238 0 : if (prtvol > 0) call dvdb%print([std_out], "", prtvol)
239 0 : call dvdb%list_perts([-1,-1,-1], npert_miss, unit=std_out)
240 0 : call dvdb%qdownsample(dump_file, qptopt, ngqpt, comm)
241 0 : call dvdb%free()
242 :
243 : case default
244 0 : ABI_ERROR(sjoin("Unknown command:", command))
245 : end select
246 :
247 : end if
248 :
249 34 : call wrtout(std_out," Done")
250 34 : call abinit_doctor("__mrgdv")
251 :
252 34 : 100 call xmpi_end()
253 :
254 0 : end program mrgdv
255 : !!***
|