LCOV - code coverage report
Current view: top level - src/98_main - mrgdv.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 19.5 % 133 26
Test Date: 2026-09-21 19:39:32 Functions: 100.0 % 2 2

            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              : !!***
        

Generated by: LCOV version 2.3-1