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

            Line data    Source code
       1              : !!****p* ABINIT/aim
       2              : !! NAME
       3              : !! aim
       4              : !!
       5              : !! FUNCTION
       6              : !! Main routine for Bader Atom-In-Molecule analysis.
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2002-2026 ABINIT group (PCasek,FF,XG)
      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              : !! WARNING
      22              : !! ABINIT rules are not yet followed in the present routine.
      23              : !!
      24              : !! SOURCE
      25              : 
      26              : #if defined HAVE_CONFIG_H
      27              : #include "config.h"
      28              : #endif
      29              : 
      30              : #include "abi_common.h"
      31              : 
      32           10 : program aim
      33              : 
      34           10 :  use defs_basis
      35              :  use m_abicore
      36              :  use m_xmpi
      37              :  use m_errors
      38              :  use m_nctk
      39              :  use netcdf
      40              : 
      41              :  use m_build_info,   only : abinit_version
      42              :  use m_time,         only : timein
      43              :  use m_io_tools,     only : open_file, file_exists
      44              :  use m_specialmsg,   only : specialmsg_getcount, herald
      45              :  use m_fstrings,     only : int2char4
      46              :  use m_bader !,      only : adini, drvaim, inpar, defad, aim_shutdown
      47              : 
      48              :  implicit none
      49              : 
      50              : !Arguments -----------------------------------
      51              : 
      52              : !Local variables-------------------------------
      53              :  integer,parameter :: master = 0
      54              :  integer :: fin,ii,ios,iunt,ierr,nfcfile
      55              : ! Allow for maximum of 100 fc files
      56              :  integer,parameter :: natm=500
      57              :  integer :: lenstr,me,nproc,comm
      58              :  real(dp) :: tcpu,tcpui,twall,twalli
      59              :  real(dp) :: tsec(2)
      60              :  character(len=fnlen) :: dnfile,hname,infile,ofile,tmpfilename
      61              :  character(len=strlen) :: instr
      62              :  character(len=10) :: procstr
      63              :  character(len=24) :: codename
      64              :  type(aim_dataset_type) :: aim_dtset
      65              :  character(len=500) :: msg
      66              :  character(len=fnlen) :: fcfile(natm)
      67              : !******************************************************************
      68              : 
      69              : !Change communicator for I/O (mandatory!)
      70           10 :  call abi_io_redirect(new_io_comm=xmpi_world)
      71              : 
      72              : !Initialize MPI
      73           10 :  call xmpi_init()
      74              : 
      75           10 :  comm = xmpi_world
      76              : 
      77           10 :  me=xmpi_comm_rank(comm); nproc=xmpi_comm_size(comm)
      78              : 
      79              : !Initialize memory profiling if it is activated
      80              : !if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
      81              : !note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
      82              : #ifdef HAVE_MEM_PROFILING
      83              :  call abimem_init(0)
      84              : #endif
      85              : 
      86           10 :  call timein(tcpui,twalli)
      87              : 
      88              : !Initialize the code, master only : write heading, and read names of files.
      89           10 :  if (me == master) then
      90           10 :    read(*,'(a)') infile
      91           10 :    infile = trim(infile)
      92           10 :    read(*,'(a)') dnfile
      93           10 :    dnfile = trim(dnfile)
      94           10 :    read(*,'(a)') ofile
      95           10 :    ofile = trim(ofile)
      96           28 :    do ii=1,natm
      97           28 :      iunt=unt+ii
      98           28 :      read(*,'(a)',iostat=ios) fcfile(ii)
      99           28 :      if (ios /=0) exit
     100              :    end do
     101           10 :    nfcfile=ii-1
     102              :  end if
     103              : 
     104              : !Transfer file names to other procs
     105           10 :  call xmpi_bcast (infile, master, comm, ierr)
     106           10 :  call xmpi_bcast (dnfile, master, comm, ierr)
     107           10 :  call xmpi_bcast (ofile, master, comm, ierr)
     108           10 :  call xmpi_bcast (nfcfile, master, comm, ierr)
     109           28 :  do ii=1,nfcfile
     110           28 :    call xmpi_bcast (fcfile(ii), master, comm, ierr)
     111              :  end do
     112              : 
     113              : !Prepare initialization of the log and output files
     114           10 :  fin=len_trim(ofile)
     115           10 :  hname(1:fin)=ofile(1:fin)
     116           10 :  hname(fin+1:fin+1)='.'
     117           10 :  untout=14
     118           10 :  codename='AIM   '//repeat(' ',18)
     119              : 
     120              : !Open main output file and main log file, then print herald at top of files
     121           10 :  if(me==master)then
     122              : 
     123           10 :    hname(fin+2:fin+4)='out'
     124           10 :    if (open_file(hname(1:fin+4),msg,unit=untout,status='unknown',form='formatted') /= 0) then
     125            0 :      ABI_ERROR(msg)
     126              :    end if
     127           10 :    rewind (unit=untout)
     128           10 :    call herald(codename,abinit_version,untout)
     129           10 :    call herald(codename,abinit_version,std_out)
     130              :  end if
     131              : 
     132              : !Open log file for non-master procs, then print herald at top of files
     133           10 :  if (me /= master) then
     134            0 :    call int2char4(me, procstr)
     135            0 :    tmpfilename = hname(1:fin) // "_LOG_P" // trim(procstr)
     136              :    !close(std_out)
     137            0 :    if (open_file(tmpfilename, msg, newunit=std_out, status='unknown',form='formatted') /= 0) then
     138            0 :      ABI_ERROR(msg)
     139              :    end if
     140            0 :    rewind (unit=std_out)
     141            0 :    call herald(codename,abinit_version,std_out)
     142              :  end if
     143              : 
     144           10 :  unt=21 ! WARNING : this number is used to define other unit numbers, in init.f
     145           10 :  unt0=9
     146              : 
     147           10 :  unto=6  ! XG020629 use standard IO unit => easier testing . So, should replace everywhere unto by std_out
     148              : 
     149           10 :  untc=11
     150           10 :  unts=12
     151           10 :  untad=19
     152           10 :  untd=17
     153           10 :  untl=18
     154           10 :  unta=15
     155           10 :  untp=13
     156           10 :  untg=20
     157              : 
     158              : !OPENING OF THE INPUT FILES
     159              : 
     160           10 :  aim_iomode = IO_MODE_FORTRAN
     161           10 :  if(me==master)then
     162           10 :    if (open_file(infile,msg,unit=unt0,status='old',form='formatted') /= 0) then
     163            0 :      ABI_ERROR(msg)
     164              :    end if
     165              : 
     166           10 :    if (file_exists(dnfile)) then
     167            0 :      if (open_file(dnfile,msg,unit=untad,status='old',form='unformatted') /=0) then
     168            0 :        ABI_ERROR(msg)
     169              :      end if
     170              :    else
     171           10 :      if (file_exists(nctk_ncify(dnfile))) then
     172              :        ! Use netcdf-io
     173           10 :        write(std_out,"(3a)")"- File: ",trim(dnfile)," does not exist but found netcdf file with similar name."
     174           10 :        dnfile = nctk_ncify(dnfile)
     175           10 :        aim_iomode = IO_MODE_ETSF
     176           10 :        NCF_CHECK(nctk_open_read(untad, dnfile, xmpi_comm_self))
     177              :      else
     178           10 :        ABI_ERROR('Missing data file: '//TRIM(dnfile))
     179              :      end if
     180              :    end if
     181              : 
     182           28 :    do ii=1,nfcfile
     183           18 :      iunt=unt+ii
     184           28 :      if (open_file(fcfile(ii),msg,unit=iunt,status='old',form='formatted') /= 0) then
     185            0 :        ABI_ERROR(msg)
     186              :      end if
     187              :    end do
     188              :  end if
     189           10 :  call xmpi_bcast(aim_iomode, master, comm, ierr)
     190              : 
     191              : !call dump_config(std_out)
     192              : 
     193              : !READING OF THE MAIN INPUT FILE
     194              : 
     195              : !Setting the input variables to their default values
     196           10 :  call defad(aim_dtset)
     197              : 
     198              : !Reading of the input file -> one string called instr
     199           10 :  if(me==master)then
     200           10 :    call inpar(instr,lenstr)
     201              :  end if
     202           10 :  call xmpi_bcast (lenstr, master, comm, ierr)
     203           10 :  call xmpi_bcast (instr(1:lenstr), master, comm, ierr)
     204              : 
     205              : !Analysis of the input string, setting of input variables in aim_dtset
     206           10 :  call adini(aim_dtset,instr,lenstr)
     207              : 
     208              : !OPENING OF THE OUTPUT FILES
     209           10 :  if(me==master)then
     210              : 
     211           10 :    if (aim_dtset%isurf/=0) hname(fin+2:fin+5)='surf'
     212              : 
     213           10 :    if (aim_dtset%isurf==1) then
     214           10 :      ierr = open_file(hname(1:fin+5),msg,unit=unts,status='unknown',form='formatted')
     215            0 :    elseif (aim_dtset%isurf==-1) then
     216            0 :      ierr = open_file(hname(1:fin+5),msg,unit=unts,status='old',action='read',form='formatted')
     217              :    end if
     218           10 :    if (ierr /= 0) then
     219            0 :      ABI_ERROR(msg)
     220              :    end if
     221              : 
     222           10 :    if (aim_dtset%crit/=0) hname(fin+2:fin+5)='crit'
     223              : 
     224           10 :    if (aim_dtset%crit>0) then
     225           10 :      ierr = open_file(hname(1:fin+5),msg,unit=untc,status='unknown',form='formatted')
     226            0 :    else if (aim_dtset%crit==-1) then
     227            0 :      ierr = open_file(hname(1:fin+5),msg,unit=untc,status='old',action='read',form='formatted')
     228              :    end if
     229           10 :    if (ierr /= 0) then
     230            0 :      ABI_ERROR(msg)
     231              :    end if
     232              : 
     233           10 :    if (aim_dtset%denout==1) then
     234            0 :      hname(fin+2:fin+4)='dn1'
     235            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untd,status='unknown',form='formatted')
     236           10 :    elseif (aim_dtset%denout==2) then
     237            0 :      hname(fin+2:fin+4)='dn2'
     238            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untd,status='unknown',form='formatted')
     239           10 :    elseif (aim_dtset%denout==3) then
     240            0 :      hname(fin+2:fin+4)='dn3'
     241            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untd,status='unknown',form='formatted')
     242           10 :    elseif (aim_dtset%denout==-1) then
     243            0 :      hname(fin+2:fin+4)='dna'
     244            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untd,status='unknown',form='unformatted')
     245              :    end if
     246              : 
     247           10 :    if (ierr /= 0) then
     248            0 :      ABI_ERROR(msg)
     249              :    end if
     250              : 
     251           10 :    if (aim_dtset%lapout==1) then
     252            0 :      hname(fin+2:fin+4)='lp1'
     253            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untl,status='unknown',form='formatted')
     254           10 :    elseif (aim_dtset%lapout==2) then
     255            0 :      hname(fin+2:fin+4)='lp2'
     256            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untl,status='unknown',form='formatted')
     257           10 :    elseif (aim_dtset%lapout==3) then
     258            0 :      hname(fin+2:fin+4)='lp3'
     259            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untl,status='unknown',form='formatted')
     260           10 :    elseif (aim_dtset%lapout==-1) then
     261            0 :      hname(fin+2:fin+4)='lpa'
     262            0 :      ierr = open_file(hname(1:fin+4),msg,unit=untl,status='unknown',form='unformatted')
     263              :    end if
     264              : 
     265           10 :    if (ierr /= 0) then
     266            0 :      ABI_ERROR(msg)
     267              :    end if
     268              : 
     269           10 :    if (aim_dtset%gpsurf==1) then
     270           10 :      hname(fin+2:fin+3)='gp'
     271           10 :      if (open_file(hname(1:fin+3),msg,unit=untg,status='unknown',form='formatted') /= 0) then
     272            0 :        ABI_ERROR(msg)
     273              :      end if
     274              :    end if
     275              : 
     276           10 :    if (aim_dtset%plden==1) then
     277            0 :      hname(fin+2:fin+4)='pld'
     278            0 :      if (open_file(hname(1:fin+5),msg,unit=untp,status='unknown',form='formatted') /= 0) then
     279            0 :        ABI_ERROR(msg)
     280              :      end if
     281              :    end if
     282              : 
     283              :  end if
     284              : 
     285           10 :  call timein(tcpu,twall)
     286           10 :  tsec(1)=tcpu-tcpui
     287           10 :  tsec(2)=twall-twalli
     288              :  write(std_out, '(5a,f13.1,a,f13.1)' ) &
     289           10 : & '-',ch10,'- After reading the input file and opening the output files ',ch10,&
     290           20 : & '- Proc.   0 individual time (sec): cpu=',tsec(1),'  wall=',tsec(2)
     291              : 
     292              : !MAIN DRIVER OF THE ANALYSIS
     293              : 
     294           10 :  write(std_out,'(a,a,a,a,i4)' )char(10),&
     295           20 : & ' aim : read density file ',trim(dnfile),' from unit number ',untad
     296              : 
     297           10 :  call drvaim(aim_dtset,tcpui,twalli)
     298              : 
     299              : !THE TOTAL TIME NEEDED
     300           10 :  call timein(tcpu,twall)
     301           10 :  tsec(1)=tcpu-tcpui
     302           10 :  tsec(2)=twall-twalli
     303              :  write(std_out, '(a,a,a,f13.1,a,f13.1)' ) &
     304           10 : & '-',ch10,'- Proc.   0 individual time (sec): cpu=',tsec(1),'  wall=',tsec(2)
     305              : 
     306              :  write(std_out,'(/," Time needed (seconds) - total, CP analyse, SURF determination:",/,/,"-         ",3F16.8)')&
     307           10 : & tsec(2),ttcp,ttsrf
     308              : 
     309              : 
     310           10 :  if(me==0)then
     311           10 :    write(untout,*)
     312           10 :    write(untout,*) "TIME ANALYSIS"
     313           10 :    write(untout,*) "============"
     314              :    write(untout,'(/," Time needed (seconds) - total, CP analyse, SURF determination:",/,/,"-         ",3F16.8)') &
     315           10 : &   tsec(1),ttcp,ttsrf
     316           10 :    write(untout,'(a,a,f11.3,a,f11.3,a,a,a,a)') char(10),&
     317           10 : &   '+Total cpu time',tsec(1),&
     318           10 : &   '  and wall time',tsec(2),' sec',char(10),char(10),&
     319           20 : &   ' aim : the run completed succesfully.'
     320              :  end if
     321              : 
     322              : !CLOSING OF THE FILES
     323           10 :  if(me==0)then
     324           10 :    close(unt0)
     325           10 :    close(untout)
     326           10 :    if (aim_dtset%isurf/=0) close(unts)
     327           10 :    if (aim_dtset%crit/=0) close(untc)
     328           10 :    if (aim_dtset%denout/=0) close(untd)
     329           10 :    if (aim_dtset%lapout/=0) close(untl)
     330           10 :    if (aim_dtset%gpsurf/=0) close(untg)
     331           10 :    if (aim_dtset%plden/=0) close(untp)
     332              :  end if
     333              : 
     334           10 :  call aim_shutdown()
     335              : 
     336              :  !call abinit_doctor("__aim")
     337              : 
     338              : !Eventual cleaning of MPI run
     339           10 :  call xmpi_end()
     340              : 
     341            0 :  end program aim
     342              : !!***
        

Generated by: LCOV version 2.3-1