LCOV - code coverage report
Current view: top level - src/98_main - anaddb.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.3 % 155 140
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****p*ABINIT/anaddb
       2              : !! NAME
       3              : !! anaddb
       4              : !!
       5              : !! FUNCTION
       6              : !! Main routine for analysis of the interatomic force constants and associated properties.
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 1999-2026 ABINIT group (XG,DCA,JCC,CL,XW,GA,MR)
      10              : !! This file is distributed under the terms of the
      11              : !! GNU General Public License, 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              : !! INPUTS
      16              : !!  (main routine)
      17              : !!
      18              : !! OUTPUT
      19              : !!  (main routine)
      20              : !!
      21              : !! SOURCE
      22              : 
      23              : #if defined HAVE_CONFIG_H
      24              : #include "config.h"
      25              : #endif
      26              : 
      27              : #include "abi_common.h"
      28              : 
      29          162 : program anaddb
      30              : 
      31              :  use, intrinsic :: iso_c_binding
      32          162 :  use defs_basis
      33              :  use m_xmpi
      34              :  use m_xomp
      35              :  use m_abicore
      36              :  use m_errors
      37              :  use m_argparse
      38              :  use m_nctk
      39              :  use netcdf
      40              : 
      41              :  use m_build_info,     only : abinit_version
      42              :  use m_io_tools,       only : open_file, flush_unit
      43              :  use m_fstrings,       only : int2char4, itoa, sjoin, strcat, inupper
      44              :  use m_specialmsg,     only : specialmsg_getcount, herald
      45              :  use m_time,           only : asctime, timein, timab, cwtime, cwtime_report
      46              :  use m_dtfil,          only : isfile
      47              :  use m_crystal,        only : crystal_t
      48              :  use m_ddb,            only : ddb_type, asrq0_t, ddb_lw_copy
      49              :  use m_ddb_hdr,        only : ddb_hdr_type
      50              :  use m_ifc,            only : ifc_type
      51              :  use m_anaddb_dataset, only : anaddb_dataset_type
      52              :  use m_anaddb_driver, only : anaddb_driver_type
      53              :  use m_ddb_interpolate, only : ddb_interpolate
      54              :  use m_elphon,         only : elphon
      55              :  use m_thmeig,         only : thmeig
      56              :  use m_symfind,        only : symanal
      57              :  use m_raman,          only : ramansus, electrooptic
      58              :  use m_ddb_diel,       only : ddb_diel
      59              :  use m_relaxpol,       only : relaxpol
      60              :  use m_ddb_elast,      only : ddb_elast
      61              :  use m_ddb_piezo,      only : ddb_piezo
      62              :  use m_ddb_internalstr, only : ddb_internalstr
      63              :  use m_ddb_flexo,      only : ddb_flexo
      64              :  use m_ddb_magpen,     only : ddb_magpen
      65              :  use m_ddb_omega_interpol, only : ddb_omega_interpol
      66              :  use m_lwf,            only : run_lattice_wannier
      67              :  use m_phonons,        only : mkphbs
      68              :  use m_gruneisen,      only : gruns_anaddb
      69              : 
      70              :  implicit none
      71              : 
      72              : !Local variables-------------------------------
      73              :  integer, parameter:: master = 0
      74              :  integer:: comm, ii, ierr
      75              :  integer:: nproc, my_rank, ana_ncid
      76              :  logical:: iam_master
      77              :  real(dp):: tcpu, tcpui, twall, twalli !,cpu, wall, gflops
      78              :  real(dp)::  tsec(2)
      79              :  integer:: units(2)
      80              :  character(len=10):: procstr
      81              :  character(len=24):: codename, start_datetime
      82              : ! character(len = strlen):: string, raw_string
      83              :  character(len = fnlen):: worker_logfile
      84              :  character(len=500):: msg
      85              :  type(args_t):: args
      86          486 :  type(anaddb_dataset_type):: dtset
      87          162 :  type(anaddb_driver_type):: driver
      88         8424 :  type(crystal_t):: crystal
      89          972 :  type(ifc_type):: Ifc
      90          162 :  type(ddb_type):: ddb
      91          162 :  type(ddb_type):: ddb_lw
      92         8424 :  type(ddb_hdr_type):: ddb_hdr
      93          162 :  type(asrq0_t):: asrq0
      94              : 
      95              : ! ========================================================================== !
      96              : 
      97              : ! Change communicator for I/O (mandatory!)
      98          162 :  call abi_io_redirect(new_io_comm = xmpi_world)
      99              : 
     100              : ! These units are defined in defs_basis
     101          486 :  units = [std_out, ab_out]
     102              : 
     103              : ! Initialize MPI
     104          162 :  call xmpi_init()
     105              : 
     106              : ! MPI variables
     107          162 :  comm = xmpi_world; nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     108          162 :  iam_master = (my_rank == master)
     109              : 
     110              : ! Parse command line arguments.
     111          162 :  args = args_parser(); if (args%exit /= 0) goto 100
     112              : 
     113              : ! Initialize memory profiling if activated at configure time.
     114              : ! if a full report is desired, set the argument of abimem_init to "2" instead of "0" via the command line.
     115              : ! note that the file can easily be multiple GB in size so don't use this option normally
     116              : #ifdef HAVE_MEM_PROFILING
     117              :  call abimem_init(args%abimem_level, limit_mb = args%abimem_limit_mb)
     118              : #endif
     119              : 
     120              : ! Initialisation of the timing
     121          162 :  call timein(tcpui, twalli)
     122              : 
     123          162 :  if (iam_master) then
     124          162 :    codename='ANADDB'//repeat(' ',18)
     125          162 :    call herald(codename, abinit_version, std_out)
     126              :  end if
     127              : 
     128          162 :  start_datetime = asctime()
     129              : 
     130              : ! Zero out all accumulators of time and init timers
     131          162 :  call timab(1, 0, tsec)
     132              : 
     133              : ! Initialise the code: write heading, and read names of files.
     134          162 :  if (iam_master) then
     135          162 :    call dtset%init(args%input_path)
     136              :  end if
     137              : 
     138              : ! Broadcast file names
     139          162 :  call dtset%bcast_files(comm)
     140              : 
     141              : ! make log file for non-master procs
     142          162 :  if (.not. iam_master) then
     143            0 :    call int2char4(my_rank, procstr)
     144            0 :    ABI_CHECK((procstr(1:1)/='#'), 'Bug: string length too short!')
     145            0 :    worker_logfile = trim(dtset%filename_output) // "_LOG_P" // trim(procstr)
     146            0 :    if (open_file(worker_logfile, msg, unit = std_out, form="formatted", action="write") /= 0) then
     147            0 :      ABI_ERROR(msg)
     148              :    end if
     149              :  end if
     150              : 
     151              : ! ========================================================================== !
     152              : ! Read input variables
     153          162 :  call dtset%read_input(comm)
     154              : 
     155          162 :  if (args%dry_run /= 0) then
     156            0 :    call wrtout(std_out, "Dry run mode. Exiting after have read the input")
     157            0 :    call dtset%free()
     158            0 :    goto 100
     159              :  end if
     160              : 
     161              : ! ========================================================================== !
     162              : ! Open output file
     163          162 :  if (iam_master) then
     164          162 :    call isfile(dtset%filename_output, 'new')
     165          162 :    if (open_file(dtset%filename_output, msg, unit=ab_out, form='formatted', status='new') /= 0) then
     166            0 :      ABI_ERROR(msg)
     167              :    end if
     168          162 :    rewind (unit = ab_out)
     169          162 :    call herald(codename, abinit_version, ab_out)
     170              : 
     171              :    ! Echo the inputs to console and main output file
     172          162 :    call dtset%outvars(std_out)
     173          162 :    call dtset%outvars(ab_out)
     174              :  else
     175            0 :    ab_out = dev_null
     176              :  end if
     177              : 
     178              : ! =========================================================================== !
     179              : 
     180              : ! Initialize driver
     181          162 :  call driver%init(dtset)
     182              : 
     183              : ! Read the DDB information and symmetrize partially the DDB
     184          162 :  write(msg, '(a, a)' )' read the DDB information and perform some checks',ch10
     185          162 :  call wrtout(units, msg)
     186              : 
     187          162 :  call ddb%from_file(dtset%filename_ddb, ddb_hdr, crystal, comm, prtvol=dtset%prtvol)
     188              : 
     189              : ! Change the bravais lattice if needed
     190          162 :  call ddb%set_brav(dtset%brav)
     191              :  ! MR: a new ddb is necessary for the longwave quantities due to incompability of it with automatic reshapes
     192              :  ! that ddb%val and ddb%flg experience when passed as arguments of some routines
     193              :  ! Copy the long-wave ddb
     194          162 :  if (ddb_hdr%has_d3E_lw) then
     195           16 :    call ddb_lw_copy(ddb, ddb_lw, ddb_hdr)
     196              :  end if
     197              : 
     198              : ! Acoustic Sum Rule call 
     199          162 :  if (dtset%flexoflag == 1 .and. dtset%asr == 6) then
     200            2 :     call driver%get_dcdq(dtset, ddb, ddb_lw, ddb_hdr)
     201            2 :     write(msg, '(a, a)' )' IFCs derivatives read',ch10
     202            2 :    call wrtout(units, msg)
     203              :  end if
     204              :  ! MR: Second- and third-order total energy derivatives calculated with the
     205              :  ! magnetic penalty (constrained DFPT) are converted to physically relevant ones here.
     206          162 :  if (abs(dtset%magpen) > tol8) then
     207              :    call ddb_magpen(ddb, ddb_lw, dtset%magpen, dtset%mpatpol, &
     208              :  & dtset%mpdir, dtset%mpert, dtset%mpopt,  Crystal%natom, dtset%prtvol, 1, Crystal%ucvol, dtset%timdisp, &
     209            6 :  & Crystal%xred)
     210              : 
     211            6 :    if (dtset%freqflag/=0) then
     212              :      call ddb_omega_interpol(Crystal%amu, ddb, ddb_lw, dtset%eta, dtset%prefix_outdata, &
     213              :    & dtset%magpen, dtset%mpatpol, dtset%mpdir, dtset%mpert, dtset%mpopt,  Crystal%natom, dtset%nfreq, Crystal%ntypat, &
     214            6 :    & dtset%freqflag, dtset%frmax, dtset%frmin, dtset%prtvol, Crystal%typat, Crystal%ucvol, Crystal%xred)
     215              :    end if
     216              : 
     217              :    !Proceed with a normal anaddb run with relaxed- or fixed-spin quantities
     218            6 :    if (dtset%mpopt==1) then
     219            0 :      ddb%val= ddb%val_fs
     220            6 :    else if (dtset%mpopt==2) then
     221       114284 :      ddb%val= ddb%val_rs
     222              :    end if
     223              :  end if
     224              : 
     225              : 
     226              : ! ! TODO: This is to maintain the previous behaviour in which all the arrays were initialized to zero.
     227              : ! ! In the new version asrq0%d2asr is always computed if the Gamma block is present
     228              : ! ! and this causes changes in [v5][t28]
     229              : ! if (.not. (dtset%ifcflag == 0 .or. dtset%instrflag /= 0 .or. dtset%elaflag /= 0)) then
     230              : !   asrq0%d2asr = zero
     231              : !   if (asrq0%asr == 3 .or. asrq0%asr == 4) then
     232              : !     asrq0%singular = zero; asrq0%uinvers = zero; asrq0%vtinvers = zero
     233              : !   end if
     234              : ! end if
     235              : 
     236              : ! Acoustic Sum Rule
     237              : ! In case the interatomic forces are not calculated, the
     238              : ! ASR-correction (asrq0%d2asr) has to be determined here from the Dynamical matrix at Gamma.
     239          162 :  call asrq0%init(ddb, dtset%asr, dtset%rfmeth, crystal, dtset%sys_dim, driver%dcdq, driver%dcdqdq)
     240              : 
     241              : ! Open netcdf output and write basic quantities
     242          162 :  call driver%open_write_nc(ana_ncid, dtset, crystal, comm)
     243              : 
     244              : ! =========================================================================== !
     245              : 
     246              : ! Compute dielectric tensor, Born effective charges, and quadrupoles.
     247          162 :  if (driver%do_electric_tensors) then
     248          152 :    call driver%electric_tensors(dtset, crystal, ddb, ddb_lw, ddb_hdr, ana_ncid, comm)
     249              :  end if
     250              : 
     251              :  ! If low-dimensional systems, convert dielectric tensors if present
     252          162 :  if (dtset%sys_dim>1 .and. dtset%dipdip>0) then
     253            4 :    call driver%convertdim_dielt(crystal%rprimd, dtset%sys_dim,dtset%dielt_thick)
     254              :  end if
     255              : 
     256              : ! Structural response at fixed polarization
     257          162 :  if (dtset%polflag == 1) then
     258            6 :    call driver%structural_response(dtset, crystal, ddb)
     259              :  end if
     260              : 
     261              : ! Compute non-linear optical susceptibilities
     262              : ! and first-order change in the linear dielectric susceptibility
     263          162 :  if (dtset%nlflag > 0) then
     264            8 :    call driver%susceptibilities(dtset, ddb, ana_ncid, comm)
     265              :  end if
     266              : 
     267              : ! Interatomic force constants
     268          162 :  if (driver%do_ifc) then
     269          108 :    call driver%interatomic_force_constants(Ifc, dtset, crystal, ddb, ana_ncid, comm)
     270          108 :    if (dtset%flexoflag /= 1 .and. dtset%asr == 6) then
     271            0 :      write(msg, '(a, a)' )' IFCs derivatives computed from real-space moment',ch10
     272            0 :      call wrtout(units, msg)
     273            0 :      call asrq0%init(ddb, dtset%asr, dtset%rfmeth, crystal, dtset%sys_dim, driver%dcdq, driver%dcdqdq)
     274              :    end if
     275              :  end if
     276              : 
     277              : ! Phonon density of states
     278          162 :  if (driver%do_phonon_dos) then
     279           22 :    call driver%phdos(dtset, crystal, Ifc, comm)
     280              :  end if
     281              : 
     282              : ! Phonon density of states and thermodynamical properties calculation
     283          470 :  if (dtset%ifcflag == 1 .and. any(dtset%thmflag==[1, 2])) then
     284            8 :    call driver%harmonic_thermo(dtset, crystal, Ifc, comm)
     285              :  end if
     286              : 
     287              : ! Phonon band structure
     288          162 :  if (driver%do_phonon_bs) then
     289          130 :    call mkphbs(Ifc, crystal, dtset, ddb, asrq0, dtset%prefix_outdata, comm)
     290              :  end if
     291              : 
     292              : ! DDB interpolation
     293          162 :  if (dtset%prtddb == 1 .and. dtset%ifcflag == 1) then
     294            2 :    call ddb_interpolate(Ifc, crystal, dtset, ddb, ddb_hdr, asrq0, comm)
     295              :  end if
     296              : 
     297              : ! =========================================================================== !
     298              : ! Electron-phonon section
     299              : 
     300          162 :  if (dtset%elphflag == 1) then
     301           30 :    call elphon(dtset, crystal, Ifc, comm)
     302              :  end if
     303              : 
     304              :  ! Thermal supercell calculation
     305         2106 :  if (sum(abs(dtset%thermal_supercell))>0 .and. dtset%ifcflag == 1) then
     306            2 :    call driver%thermal_supercell(dtset, crystal, ifc)
     307              :  end if
     308              : 
     309              : ! Thermal corrections to eigenvalues (old)
     310          162 :  if (dtset%thmflag >= 3 .and. dtset%thmflag <= 8) then
     311           14 :    call thmeig(dtset, ddb, crystal, ab_out, crystal%natom, dtset%mpert, dtset%msize, asrq0%d2asr, comm)
     312              :  end if
     313              : 
     314              : ! =========================================================================== !
     315              : 
     316              : ! Compute the dielectric function and oscillator strength.
     317          162 :  if (driver%do_dielectric_q0) then
     318           54 :    call driver%dielectric_q0(dtset, crystal, ifc, ddb, asrq0, ana_ncid, comm)
     319              :  end if
     320              : 
     321              : ! Non-linear response: electrooptic and Raman (q = Gamma, TO modes only)
     322          162 :  if (dtset%nlflag == 1) then
     323            4 :    call driver%nonlinear_response(dtset, crystal, ana_ncid, comm)
     324              :  end if
     325              : 
     326              : ! Non-analyticity in the dynamical matrix
     327          162 :  if (driver%do_dielectric_nonana) then
     328           48 :    call driver%dielectric_nonana(dtset, crystal, ddb, ana_ncid, comm)
     329              :  end if
     330              : 
     331              : ! =========================================================================== !
     332              : ! Linear response with strain
     333              : 
     334              : ! Internal strain (needed for the other linear response functions)
     335          162 :  if (dtset%instrflag /= 0) then
     336           12 :    call driver%internal_strain(dtset, ddb, asrq0)
     337              :  end if
     338              : 
     339              : ! Elastic tensor
     340          162 :  if (dtset%elaflag /= 0) then
     341           12 :    call driver%elastic_tensor(dtset, crystal, ddb, asrq0, ana_ncid)
     342              :  end if
     343              : 
     344              : ! Piezoelectric tensor
     345          162 :  if (dtset%piezoflag /= 0 .or. dtset%dieflag == 4 .or. dtset%elaflag == 4) then
     346           10 :    call driver%piezoelectric_tensor(dtset, crystal, ddb, ana_ncid)
     347              :  end if
     348              : 
     349              : ! Flexoelectric tensor
     350          162 :  if (dtset%flexoflag /= 0) then
     351            4 :    call driver%flexoelectric_tensor(dtset, crystal, ddb, ddb_lw, ddb_hdr, asrq0)
     352              :  end if
     353              : 
     354              : ! =========================================================================== !
     355              : 
     356              :  ! Gruneisen parameters
     357          162 :  if (dtset%gruns_nddbs /= 0) then
     358            2 :    call gruns_anaddb(dtset, comm)
     359              :  end if
     360              : 
     361              :  ! Lattice Wannier functions
     362          162 :  if (dtset%ifcflag == 1 .and. dtset%lwfflag > 0 ) then
     363            6 :    call driver%lattice_wannier(dtset, crystal, Ifc, comm)
     364              :  endif
     365              : 
     366              :  ! Output phonon frequencies for BoltzTrap
     367          162 :  if (iam_master .and. dtset%ifcflag == 1 .and. dtset%outboltztrap == 1) then
     368            2 :    call ifc%outphbtrap(crystal, dtset%ng2qpt, 1, dtset%q2shft, dtset%prefix_outdata)
     369              :  end if
     370              : 
     371              : ! =========================================================================== !
     372              : ! Close netcdf file
     373          162 :  if (iam_master) then
     374          162 :    NCF_CHECK(nf90_close(ana_ncid))
     375              :  end if
     376              : 
     377              : ! =========================================================================== !
     378              : ! Free memory
     379          162 :  call asrq0%free()
     380          162 :  call ifc%free()
     381          162 :  call crystal%free()
     382          162 :  call ddb%free()
     383          162 :  call ddb_hdr%free()
     384          162 :  call ddb_lw%free()
     385          162 :  call driver%free()
     386          162 :  call dtset%free()
     387              : 
     388              : ! =========================================================================== !
     389              : ! Output timing and memory reports, then close output files
     390              : 
     391          162 :  call timein(tcpu, twall)
     392          162 :  tsec(1)=tcpu-tcpui; tsec(2)=twall-twalli
     393          162 :  write(msg, '(a, i4, a, f13.1, a, f13.1)' )' Proc.',my_rank, ' individual time (sec): cpu=',tsec(1), '  wall=',tsec(2)
     394          162 :  call wrtout(std_out, msg)
     395              : 
     396          162 :  if (iam_master) then
     397          162 :    write(ab_out, '(a, a, a, i4, a, f13.1, a, f13.1)' )'-',ch10, &
     398          324 :     '- Proc.',my_rank, ' individual time (sec): cpu=',tsec(1), '  wall=',tsec(2)
     399              :  end if
     400              : 
     401          162 :  call xmpi_sum(tsec, comm, ierr)
     402              : 
     403          162 :  write(msg, '(a, (80a), a, a, a, f11.3, a, f11.3, a, a, a, a)' ) ch10, &
     404        13284 :   ('=',ii = 1, 80), ch10, ch10, &
     405          162 :    '+Total cpu time',tsec(1), '  and wall time',tsec(2), ' sec',ch10, ch10, &
     406        13446 :    ' anaddb : the run completed successfully.'
     407          162 :  call wrtout(units, msg)
     408              : 
     409          162 :  if (iam_master) then
     410              :    ! Write YAML document with the final summary.
     411              :    ! we use this doc to test whether the calculation is completed.
     412          162 :    write(std_out, "(a)")"--- !FinalSummary"
     413          162 :    write(std_out, "(a)")"program: anaddb"
     414          162 :    write(std_out, "(2a)")"version: ",trim(abinit_version)
     415          162 :    write(std_out, "(2a)")"start_datetime: ",start_datetime
     416          162 :    write(std_out, "(2a)")"end_datetime: ",asctime()
     417          162 :    write(std_out, "(a, f13.1)")"overall_cpu_time: ",tsec(1)
     418          162 :    write(std_out, "(a, f13.1)")"overall_wall_time: ",tsec(2)
     419          162 :    write(std_out, "(a, i0)")"mpi_procs: ",xmpi_comm_size(xmpi_world)
     420          162 :    write(std_out, "(a, i0)")"omp_threads: ",xomp_get_num_threads(open_parallel=.True.)
     421              :    !write(std_out, "(a, i0)")"num_warnings: ",nwarning
     422              :    !write(std_out, "(a, i0)")"num_comments: ",ncomment
     423          162 :    write(std_out, "(a)")"..."
     424          162 :    call flush_unit(std_out)
     425              :  end if
     426              : 
     427              :  ! Write information on file about the memory before ending mpi module, if memory profiling is enabled
     428          162 :  call abinit_doctor(dtset%filename_output)
     429              : 
     430          162 :  call flush_unit(ab_out)
     431          162 :  call flush_unit(std_out)
     432              : 
     433          162 :  if (iam_master) close(ab_out)
     434              : 
     435          162 :  100 call xmpi_end()
     436              : 
     437            0 :  end program anaddb
     438              : !!***
     439              : 
        

Generated by: LCOV version 2.3-1