LCOV - code coverage report
Current view: top level - src/78_effpot - m_effective_potential_file.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 73.3 % 1772 1299
Test Date: 2026-09-21 13:49:52 Functions: 82.4 % 17 14

            Line data    Source code
       1              : !!****m* ABINIT/m_effective_potential_file
       2              : !! NAME
       3              : !! m_effective_potential_file
       4              : !!
       5              : !! FUNCTION
       6              : !! This  module contains all routine to read the effective potential from files
       7              : !! Can also read coefficients from XML
       8              : !! (XML or DDB)
       9              : !!
      10              : !! COPYRIGHT
      11              : !! Copyright (C) 2000-2026 ABINIT group (AM)
      12              : !! This file is distributed under the terms of the
      13              : !! GNU General Public License, see ~abinit/COPYING
      14              : !! or http://www.gnu.org/copyleft/gpl.txt .
      15              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      16              : !!
      17              : !! SOURCE
      18              : 
      19              : #if defined HAVE_CONFIG_H
      20              : #include "config.h"
      21              : #endif
      22              : 
      23              : #include "abi_common.h"
      24              : 
      25              : 
      26              : module m_effective_potential_file
      27              : 
      28              :  use defs_basis
      29              :  use m_errors
      30              :  use m_abicore
      31              :  use m_xmpi
      32              :  use m_harmonics_terms
      33              :  use m_anharmonics_terms
      34              :  use m_effective_potential
      35              :  use m_ifc
      36              :  use m_ddb
      37              :  use m_ddb_hdr
      38              :  use netcdf
      39              : 
      40              :  use m_io_tools,   only : open_file, get_unit
      41              :  use m_geometry,   only : xcart2xred, xred2xcart, metric
      42              :  use m_symfind,    only : symfind, symlatt
      43              :  use m_crystal,    only : crystal_t
      44              :  use m_dynmat,     only : dfpt_prtph
      45              :  use m_abihist,    only : abihist,abihist_init,abihist_free,abihist_copy,read_md_hist
      46              :  use m_ddb_internalstr, only : ddb_internalstr
      47              : 
      48              :  implicit none
      49              : 
      50              :  public :: effective_potential_file_getDimCoeff
      51              :  public :: effective_potential_file_getDimMD
      52              :  public :: effective_potential_file_getDimSystem
      53              :  public :: effective_potential_file_getDimStrainCoupling
      54              :  public :: effective_potential_file_getType
      55              :  public :: effective_potential_file_mapHistToRef
      56              :  public :: effective_potential_file_read
      57              :  public :: effective_potential_file_readDisplacement
      58              :  public :: effective_potential_file_readMDfile
      59              :  private :: coeffs_xml2effpot
      60              :  private :: system_getDimFromXML
      61              :  private :: system_xml2effpot
      62              :  private :: system_ddb2effpot
      63              : 
      64              : #ifndef HAVE_XML
      65              :  private :: rdfromline
      66              :  private :: rmtabfromline
      67              :  private :: rdfromline_value
      68              :  private :: elementfromline
      69              : #endif
      70              : 
      71              : #if defined HAVE_XML
      72              :  public :: effpot_xml_checkXML
      73              :  public :: effpot_xml_getDimCoeff
      74              :  public :: effpot_xml_readSystem
      75              :  public :: effpot_xml_getValue
      76              :  public :: effpot_xml_getAttribute
      77              :  public :: effpot_xml_getDimSystem
      78              : 
      79              :  interface
      80              :    subroutine effpot_xml_readSystem(filename,natom,&
      81              : &     ntypat,nrpt,nqpt,amu,atmfrc,cell,dynmat,elastic_constants,&
      82              : &     energy,epsilon_inf,ewald_atmfrc,&
      83              : &     phfrq,rprimd,qph1l,short_atmfrc,typat,xcart,zeff)&
      84              : &                          bind(C,name="effpot_xml_readSystem")
      85              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
      86              :      integer(C_INT) :: natom,ntypat,nrpt,nqpt
      87              :      integer(C_INT) :: typat(natom)
      88              :      integer(C_INT) :: cell(3,nrpt)
      89              :      real(C_DOUBLE) :: energy
      90              :      real(C_DOUBLE) :: dynmat(2,3,natom,3,natom,nqpt)
      91              :      real(C_DOUBLE) :: phfrq(3*natom,nqpt),qph1l(3,nqpt)
      92              :      real(C_DOUBLE) :: atmfrc(3,natom,3,natom,nrpt)
      93              :      real(C_DOUBLE) :: short_atmfrc(3,natom,3,natom,nrpt)
      94              :      real(C_DOUBLE) :: ewald_atmfrc(3,natom,3,natom,nrpt)
      95              :      real(C_DOUBLE) :: amu(ntypat),rprimd(3,3),epsilon_inf(3,3)
      96              :      real(C_DOUBLE) :: zeff(3,3,natom)
      97              :      real(C_DOUBLE) :: elastic_constants(6,6),xcart(3,natom)
      98              :      character(kind=C_CHAR) :: filename(*)
      99              :    end subroutine effpot_xml_readSystem
     100              :  end interface
     101              : 
     102              :  interface
     103              :    subroutine effpot_xml_readStrainCoupling(filename,natom,&
     104              : &     nrpt,voigt,elastic3rd,elastic_displacement,&
     105              : &     strain_coupling,phonon_strain_atmfrc,phonon_straincell)&
     106              : &                          bind(C,name="effpot_xml_readStrainCoupling")
     107              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
     108              :      integer(C_INT) :: natom
     109              :      integer(C_INT) :: nrpt,voigt
     110              :      integer(c_INT) :: phonon_straincell(3,nrpt)
     111              :      real(C_DOUBLE) :: elastic3rd(6,6),elastic_displacement(6,3,natom)
     112              :      real(C_DOUBLE) :: strain_coupling(3,natom)
     113              :      real(C_DOUBLE) :: phonon_strain_atmfrc(3,natom,3,natom,nrpt)
     114              :      character(kind=C_CHAR) :: filename(*)
     115              :    end subroutine effpot_xml_readStrainCoupling
     116              :  end interface
     117              : 
     118              :  interface
     119              :    subroutine effpot_xml_readCoeff(filename,ncoeff,ndisp,nterm,&
     120              : &                                 coefficient,atindx,cell,direction,power_disp,&
     121              : &                                 power_strain,strain,weight)&
     122              : &                          bind(C,name="effpot_xml_readCoeff")
     123              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
     124              :      character(kind=C_CHAR) :: filename(*)
     125              :      integer(C_INT) :: ncoeff,ndisp,nterm
     126              :      integer(C_INT) :: atindx(ncoeff,nterm,2,ndisp)
     127              :      integer(C_INT) :: cell(ncoeff,nterm,3,2,ndisp)
     128              :      integer(C_INT) :: direction(ncoeff,nterm,ndisp)
     129              :      integer(C_INT) :: strain(ncoeff,nterm,ndisp)
     130              :      integer(C_INT) :: power_disp(ncoeff,nterm,ndisp)
     131              :      integer(C_INT) :: power_strain(ncoeff,nterm,ndisp)
     132              :      real(C_DOUBLE) :: coefficient(ncoeff)
     133              :      real(C_DOUBLE) :: weight(ncoeff,nterm)
     134              :    end subroutine effpot_xml_readCoeff
     135              :  end interface
     136              : 
     137              :  interface
     138              :    subroutine effpot_xml_getDimSystem(filename,natom,ntypat,nqpt,nrpt1,nrpt2)&
     139              : &                          bind(C,name="effpot_xml_getDimSystem")
     140              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
     141              :      integer(C_INT) :: natom,ntypat,nqpt,nrpt1,nrpt2
     142              :      character(kind=C_CHAR) :: filename(*)
     143              :    end subroutine effpot_xml_getDimSystem
     144              :  end interface
     145              : 
     146              :  interface
     147              :    subroutine effpot_xml_getDimStrainCoupling(filename,nrpt,voigt)&
     148              : &                          bind(C,name="effpot_xml_getDimStrainCoupling")
     149              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
     150              :      integer(C_INT) :: voigt
     151              :      integer(C_INT) :: nrpt
     152              :      character(kind=C_CHAR) :: filename(*)
     153              :    end subroutine effpot_xml_getDimStrainCoupling
     154              :  end interface
     155              : 
     156              :  interface
     157              :    subroutine effpot_xml_getDimCoeff(filename,ncoeff,nterm_max,ndisp_max)&
     158              : &                          bind(C,name="effpot_xml_getDimCoeff")
     159              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT,C_PTR
     160              :      character(kind=C_CHAR) :: filename(*)
     161              : !     character(kind=C_CHAR) :: name(*)
     162              :      type(C_PTR) :: name
     163              :      integer(C_INT) :: ncoeff,ndisp_max,nterm_max
     164              :    end subroutine effpot_xml_getDimCoeff
     165              :  end interface
     166              : 
     167              : 
     168              :  interface
     169              :    subroutine effpot_xml_checkXML(filename,name_root) &
     170              : &                          bind(C,name="effpot_xml_checkXML")
     171              :      use, intrinsic :: iso_c_binding, only : C_CHAR
     172              :      character(kind=C_CHAR) :: filename(*),name_root(*)
     173              :    end subroutine effpot_xml_checkXML
     174              :  end interface
     175              : 
     176              :  interface
     177              :    subroutine effpot_xml_getValue(filename,name_value,value_result) &
     178              :  &                          bind(C,name="effpot_xml_getValue")
     179              :       use, intrinsic :: iso_c_binding, only : C_CHAR
     180              :       character(kind=C_CHAR) :: filename(*),name_value(*)
     181              :       character(kind=C_CHAR) :: value_result
     182              :     end subroutine effpot_xml_getValue
     183              :   end interface
     184              : 
     185              :  interface
     186              :    subroutine effpot_xml_getAttribute(filename,name_value,name_attribute) &
     187              : &                          bind(C,name="effpot_xml_getAttribute")
     188              :      use, intrinsic :: iso_c_binding, only : C_CHAR
     189              :      character(kind=C_CHAR) :: filename(*),name_value(*),name_attribute(*)
     190              :    end subroutine effpot_xml_getAttribute
     191              :  end interface
     192              : 
     193              :  interface
     194              :    subroutine effpot_xml_getNumberKey(filename,name_value,number) &
     195              : &                          bind(C,name="effpot_xml_getNumberKey")
     196              :      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
     197              :      character(kind=C_CHAR) :: filename(*),name_value(*)
     198              :      integer(C_INT) :: number
     199              :    end subroutine effpot_xml_getNumberKey
     200              :  end interface
     201              : 
     202              : #endif
     203              : 
     204              :  integer,parameter :: XML_RECL = 50000
     205              : !!***
     206              : 
     207              : CONTAINS  !===========================================================================================
     208              : 
     209              : 
     210              : !****f* m_effective_potential_file/effective_potential_file_read
     211              : !!
     212              : !! NAME
     213              : !! effective_potential_file_read
     214              : !!
     215              : !! FUNCTION
     216              : !! tranfert file (XML or DDB) in effective potential type
     217              : !! Also transfert coefficient from xml file for ahnarmonic part
     218              : !!
     219              : !! INPUTS
     220              : !! filename = path of the file
     221              : !! hist<type(abihist)> = optional,The history of the MD (or snapshot of DFT)
     222              : !! inp<type(multibinit_dtset_type)> = optional,datatype with all the input variables (mantadory to
     223              : !!                                      read DDB file)
     224              : !! comm=MPI communicator
     225              : !!
     226              : !! OUTPUT
     227              : !! eff_pot<type(effective_potential_type)> = datatype with all the information for effective potential
     228              : !!
     229              : !! SOURCE
     230              : 
     231           91 : subroutine effective_potential_file_read(filename,eff_pot,inp,comm,hist)
     232              : 
     233              :   use m_multibinit_dataset
     234              :   use m_strain
     235              :   use m_crystal, only : crystal_t
     236              :   use m_dynmat, only : bigbx9
     237              : 
     238              : !Arguments ------------------------------------
     239              : !scalars
     240              :   integer,intent(in) :: comm
     241              :   character(len=fnlen),intent(in) :: filename
     242              : !array
     243              :   type(effective_potential_type), intent(inout)  :: eff_pot
     244              :   type(multibinit_dtset_type),optional,intent(in) :: inp
     245           91 :   type(ddb_type) :: ddb
     246         4732 :   type(crystal_t) :: Crystal
     247              :   type(abihist),optional :: hist
     248              : !Local variables------------------------------
     249              : !scalars
     250              :   integer :: ii,filetype,natom,ntypat,nqpt,nrpt
     251              :   character(500) :: message
     252         4732 :   type(ddb_hdr_type) :: ddb_hdr
     253              : ! *************************************************************************
     254              : 
     255           91 :   call effective_potential_file_getType(filename,filetype)
     256              : 
     257           91 :   if (filetype/=0) then
     258              : 
     259           91 :     if (.not.(present(inp))) then
     260              :       write(message, '(4a)' )&
     261            0 : &        ' effective_potential_file_read: you need to give input file to compute ',&
     262            0 : &        'the response fonction from DDB file ',ch10
     263            0 :       ABI_ERROR(message)
     264              :     end if
     265              : 
     266           91 :     if(filetype ==1) then
     267              : !     Read the DDB information, also perform some checks, and symmetrize partially the DDB
     268           29 :       write(message, '(3a)' )' Read the DDB information of the reference',&
     269           58 :  &      ' system and perform some checks',ch10
     270           29 :       call wrtout(std_out,message,'COLL')
     271           29 :       call wrtout(ab_out,message,'COLL')
     272              : 
     273           29 :       call effective_potential_file_getDimSystem(filename,comm,natom,ntypat,nqpt,nrpt)!
     274              : 
     275           29 :       call ddb%from_file(filename,ddb_hdr,Crystal,comm)
     276           29 :       call ddb_hdr%free()
     277              : 
     278           29 :       call ddb%set_brav(inp%brav)
     279              : 
     280              : !     Transfert the ddb to the effective potential
     281           29 :       call system_ddb2effpot(Crystal,ddb,eff_pot,inp,comm)
     282              : 
     283              :       ! Free memory
     284           29 :       call ddb%free()
     285           29 :       call Crystal%free()
     286              : 
     287              : !     Generate long rage interation for the effective potential for both type and generate supercell
     288           29 :       call effective_potential_generateDipDip(eff_pot,inp%dipdip_range,inp%dipdip,inp%asr,comm)
     289              : 
     290              : !     If needed, print the effective potential into the output
     291           29 :       if (inp%prt_model>=3.or.inp%prt_model==-1) then
     292            8 :         call effective_potential_print(eff_pot,-1)
     293              :       end if
     294              :     end if
     295           91 :     if (filetype==2 .or.filetype==23) then ! xml file
     296              : 
     297              : !     Free the effective potential before
     298           38 :       call effective_potential_free(eff_pot)
     299              : 
     300           38 :       call system_xml2effpot(eff_pot,filename,comm,strcpling=inp%strcpling)
     301              : 
     302              : 
     303              : !     Assign the energy of the reference from input
     304           38 :       if(abs(inp%energy_reference)>tol16)then
     305            0 :         write(message,'(11a)') ch10,&
     306            0 : &      ' --- !WARNING',ch10,&
     307            0 : &      '     Energy of the reference structure is specify in ',ch10,&
     308            0 : &      '     the input file. The energy is set with',ch10,&
     309            0 : &      '     this value.',ch10,&
     310            0 : &      ' ---',ch10
     311            0 :         call wrtout(std_out,message,'COLL')
     312            0 :         eff_pot%energy = inp%energy_reference
     313              :       end if
     314              : 
     315              : 
     316              : !     Generate long rage interation for the effective potential for both type and generate supercell
     317           38 :       call effective_potential_generateDipDip(eff_pot,inp%dipdip_range,inp%dipdip,inp%asr,comm,1)
     318              : 
     319              : !     If needed, print the effective potential
     320           38 :       call effective_potential_print(eff_pot,inp%prt_model)
     321              :     end if
     322           91 :     if (filetype==3 .or. filetype==23) then
     323              : !     Read the  coefficient of the fit for the anharmonic part
     324           28 :       write(message, '(4a)' )ch10,' Read the coefficients of the polynomial fit from XML',&
     325           56 :  &      ' and perform some checks',ch10
     326           28 :       call wrtout(std_out,message,'COLL')
     327           28 :       call wrtout(ab_out,message,'COLL')
     328              : 
     329           28 :       if(eff_pot%anharmonics_terms%ncoeff/=0)then
     330            0 :         write(message,'(9a)') ch10,&
     331            0 : &      ' --- !WARNING',ch10,&
     332            0 : &      '     There is already fitted polynome set in the model',ch10,&
     333            0 : &      '     The previous coefficients will be remove',ch10,&
     334            0 : &      ' ---',ch10
     335            0 :         call wrtout(std_out,message,'COLL')
     336              :       end if
     337              : 
     338           28 :       call coeffs_xml2effpot(eff_pot,filename,comm)
     339              : 
     340              : !     Assign the coeff number from input
     341           28 :       if(inp%ncoeff==0)then
     342           20 :         write(message,'(12a)') ch10,&
     343           20 : &      ' --- !WARNING',ch10,&
     344           20 : &      '     The values of the coefficients are set to 0',&
     345           20 : &      ' in the input file.',ch10,&
     346           20 : &      '     The values of the coefficients will be read in the XML',ch10,&
     347           20 : &      '     or might be fitted',ch10,&
     348           40 : &      ' ---',ch10
     349           20 :         call wrtout(std_out,message,'COLL')
     350           20 :         if(inp%fit_coeff <= 0 .and. &
     351              : &          all(abs(eff_pot%anharmonics_terms%coefficients(:)%coefficient) <tol16)) then
     352              : 
     353            0 :           write(message,'(12a)') ch10,&
     354            0 : &          ' --- !WARNING',ch10,&
     355            0 : &          '     The input for the fit process is set to 0 or -1',&
     356            0 : &          ' in the input file.',ch10,&
     357            0 : &          '     However, the values of the coefficients in the XMF files are zero,',ch10,&
     358            0 : &          '     So the coefficients can not be used',ch10,&
     359            0 : &          ' ---',ch10
     360            0 :           call wrtout(std_out,message,'COLL')
     361              : 
     362              :         end if
     363              :       else
     364            8 :         if (eff_pot%anharmonics_terms%ncoeff /= inp%ncoeff)then
     365              :           write(message, '(5a)' )&
     366            0 : &            ' The number of coefficients in the XML file is superior to the ',ch10,&
     367            0 : &            'number of coefficients in the input ',ch10,&
     368            0 : &            'Action: correct your input file or change the file'
     369            0 :           ABI_ERROR(message)
     370              :         end if
     371           40 :         do ii = 1,eff_pot%anharmonics_terms%ncoeff
     372              :           call polynomial_coeff_setCoefficient(inp%coefficients(ii),&
     373           40 : &                                              eff_pot%anharmonics_terms%coefficients(ii))
     374              :         end do
     375              :       end if
     376              : 
     377           63 :     else if(filetype==4) then
     378            0 :       if(present(hist))then
     379            0 :         write(message,'(5a)')ch10,&
     380            0 : &         '-Reading the file ',trim(filename),ch10,&
     381            0 : &         ' with NetCDF in order to fit the polynomial coefficients'
     382            0 :         call wrtout(std_out,message,'COLL')
     383            0 :         call wrtout(ab_out,message,'COLL')
     384            0 :         call effective_potential_file_readMDfile(filename,hist,option=inp%ts_option)
     385              :       else
     386              :        write(message, '(3a)' )&
     387            0 : &         'There is no hist argument ',ch10,&
     388            0 : &         'Action: add hist argument'
     389            0 :        ABI_ERROR(message)
     390              :      end if
     391              :    end if
     392              :  else
     393              :    write(message, '(5a)' )&
     394            0 : &      ' The file ',trim(filename),' is not readable with Multibinit',ch10,&
     395            0 : &      ' Action: Change the file.'
     396            0 :    ABI_BUG(message)
     397              :  end if
     398              : 
     399           91 : end subroutine effective_potential_file_read
     400              : !!***
     401              : 
     402              : !!****f* m_effective_potential_file/effective_potential_file_getType
     403              : !!
     404              : !! NAME
     405              : !! effective_potential_file_getType
     406              : !!
     407              : !! FUNCTION
     408              : !! This routine test the xml or ddb file
     409              : !!
     410              : !! INPUTS
     411              : !! filename = names of the files
     412              : !!
     413              : !! OUTPUT
     414              : !! type_file  = 0 no type found
     415              : !!              1 DDB file
     416              : !!              2 XML file the system definition and harmonic part
     417              : !!              3 XML file with polynomial coefficients
     418              : !!             23 XML file with both system definition and polynomial coefficients
     419              : !!             40 NetCDF file with history of MD or snapshot
     420              : !!             41 ASCII file with history of MD or snapshot
     421              : !!
     422              : !! SOURCE
     423              : 
     424          290 : subroutine effective_potential_file_getType(filename,filetype)
     425              : 
     426              : !Arguments ------------------------------------
     427              : !scalars
     428              :  character(len=fnlen),intent(in) :: filename
     429              :  integer, intent(out) :: filetype
     430              : !arrays
     431              : !Local variables-------------------------------
     432              : !scalar
     433              :  integer :: natom,nstep
     434              :  integer :: ddbun = 666,ios=0
     435              :  character(len=500) :: message
     436              :  character (len=1000) :: line,readline
     437              :  integer :: natom_id,time_id,xyz_id,six_id,ddb_version
     438              :  integer :: ncid,ncerr
     439              :  logical :: md_file
     440              : ! *************************************************************************
     441              : 
     442          290 :  filetype = 0
     443              : 
     444          290 :  ddbun = get_unit()
     445              : 
     446          290 :  if (open_file(filename,message,unit=ddbun,form="formatted",status="old",action="read") /= 0) then
     447            0 :    ABI_ERROR(message)
     448              :  end if
     449              : 
     450              : !Check if the file is a XML file or a DDB and in this case, store the DDB code.
     451          290 :  ios = 0
     452        26199 :  do while ((ios==0))
     453        25909 :    read(ddbun,'(a)',iostat=ios) readline
     454        25909 :    call rmtabfromline(readline)
     455        25909 :    line=adjustl(readline)
     456        26199 :    if(line(3:13)=="xml version") then
     457          380 :      do while ((ios==0))
     458          190 :        read(ddbun,'(a)',iostat=ios) readline
     459          190 :        call rmtabfromline(readline)
     460          190 :        line=adjustl(readline)
     461          190 :        if(line(1:16)==char(60)//"Heff_definition".or.&
     462              : &         line(1:17)==char(60)//"Terms_definition")then
     463           72 :          filetype = 3
     464           72 :          ios = -1
     465              :        end if
     466          380 :        if(line(1:18)==char(60)//"System_definition") then
     467          118 :          filetype = 2
     468       183318 :          do while ((ios==0))
     469       183200 :            read(ddbun,'(a)',iostat=ios) readline
     470       183200 :            call rmtabfromline(readline)
     471       183200 :            line=adjustl(readline)
     472       183200 :            if(line(1:16)==char(60)//"Heff_definition".or.&
     473          118 : &             line(1:17)==char(60)//"Terms_definition")then
     474           16 :              filetype = 23
     475           16 :              ios = -1
     476              :            end if
     477              :          end do
     478              :        end if
     479              :      end do
     480        25719 :    else  if(line(6:24)=="DERIVATIVE DATABASE") then
     481           87 :      filetype = 1
     482           87 :      ios = -1
     483              :    end if
     484              :  end do
     485          290 :  close(ddbun)
     486              : 
     487          303 :  if(filetype/=0) return
     488              : 
     489              : !try to read netcdf HIST file
     490           13 :  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
     491           13 :  if(ncerr == NF90_NOERR) then
     492           13 :    md_file = .TRUE.
     493           13 :    ncerr = nf90_inq_dimid(ncid,"natom",natom_id)
     494           13 :    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
     495           13 :    ncerr = nf90_inq_dimid(ncid,"xyz",xyz_id)
     496           13 :    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
     497           13 :    ncerr = nf90_inq_dimid(ncid,"time",time_id)
     498           13 :    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
     499           13 :    ncerr = nf90_inq_dimid(ncid,"six",six_id)
     500           13 :    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
     501           13 :    if (md_file) then
     502           13 :      filetype = 40
     503           13 :      return
     504              :    end if
     505              :  end if
     506            0 :  ncerr = nf90_close(ncid)
     507              : 
     508            0 :  if(filetype/=0) return
     509              : 
     510              : ! Try to read netcdf DDB file
     511            0 :  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
     512            0 :  if(ncerr==NF90_NOERR) then
     513            0 :    ncerr = nf90_get_var(ncid, nctk_idname(ncid, 'ddb_version'), ddb_version)
     514            0 :    if (ncerr==NF90_NOERR) then
     515            0 :      filetype = 1
     516            0 :      return
     517              :    end if
     518              :  end if
     519              : 
     520              : !Try to get the dim of MD ASCII file
     521            0 :  call effective_potential_file_getDimMD(filename,natom,nstep)
     522            0 :  if(natom /= 0 .and. nstep/=0) filetype = 41
     523              : 
     524           91 : end subroutine effective_potential_file_getType
     525              : !!***
     526              : 
     527              : !!****f* m_effective_potential_file/effective_potential_file_getDimSystem
     528              : !!
     529              : !! NAME
     530              : !! effective_potential_file_getDimSystem
     531              : !!
     532              : !! FUNCTION
     533              : !! This routine test the xml or ddb file
     534              : !! Return the number of atoms/ntypat in the unit cell from ddb and xml
     535              : !! Return natom/ntypat/nqpt and nrpt if the file is XML file
     536              : !! In case of DDB file, you have to run bigbx9 to get nrpt
     537              : !!
     538              : !! INPUTS
     539              : !! filename = names of the files
     540              : !! comm = MPI communicator
     541              : !!
     542              : !! OUTPUT
     543              : !! natom = number of atoms
     544              : !! ntypat= number of type of atoms
     545              : !! nqpt  = number of q points
     546              : !! nrpt  = number of rpt points
     547              : !!
     548              : !! SOURCE
     549              : 
     550          134 : subroutine effective_potential_file_getDimSystem(filename,comm,natom,ntypat,nqpt,nrpt)
     551              : 
     552              : !Arguments ------------------------------------
     553              : !scalars
     554              :  character(len=fnlen),intent(in) :: filename
     555              :  integer,intent(out) :: natom,ntypat,nqpt,nrpt
     556              :  integer,intent(in) :: comm
     557              : !arrays
     558              : 
     559              : !Local variables-------------------------------
     560              :  !scalar
     561              :  integer :: filetype
     562              : ! integer :: dimekb,lmnmax,mband,mtyp,msym,nblok,nkpt,usepaw
     563              :  character(len=500) :: message
     564         6968 :  type(ddb_hdr_type) :: ddb_hdr
     565              : ! *************************************************************************
     566              : 
     567          134 :  natom = 0
     568          134 :  ntypat= 0
     569          134 :  nqpt = 0
     570          134 :  nrpt  = 0
     571              : 
     572          134 :  call effective_potential_file_getType(filename,filetype)
     573              : 
     574          134 :  if(filetype==1)then
     575           58 :    write(message, '(6a)' )ch10,' The file ',trim(filename),ch10,&
     576          116 : &                  ' is DDB file (extraction of the number of atoms)',ch10
     577           58 :    call wrtout(std_out,message,'COLL')
     578              : 
     579              :    write(message, '(8a)' )&
     580           58 : &   ' The file ',trim(filename),ch10,' is ddb file only the number of atoms is read,',&
     581          116 : &    'if you want to predic the number of cell (nrpt)',ch10,' use bigbx9 routines',ch10
     582           58 :    call wrtout(std_out,message,'COLL')
     583              : 
     584           58 :    call ddb_hdr%open_read(filename,comm,dimonly=1)
     585           58 :    natom = ddb_hdr%natom
     586           58 :    ntypat = ddb_hdr%ntypat
     587           58 :    call ddb_hdr%free()
     588              : 
     589              : !  Must read some value to initialze  array (nprt for ifc)
     590              : !   call bigbx9(inp%brav,dummy_cell,0,1,inp%ngqpt,inp%nqshft,nrpt,ddb%rprim,dummy_rpt)
     591              : 
     592           76 :  else if (filetype==2 .or. filetype==23) then
     593           76 :    write(message, '(5a)' )ch10,' The file ',trim(filename),&
     594          152 : &                ' is XML file (extraction of all information)'
     595           76 :    call wrtout(std_out,message,'COLL')
     596              : 
     597           76 :    call system_getDimFromXML(filename,natom,ntypat,nqpt,nrpt)
     598              : 
     599              :  else
     600              :    write(message, '(a,a,a,a)' )&
     601            0 : &   ' The file ',trim(filename),' is not compatible with multibinit',ch10
     602            0 :    ABI_ERROR(message)
     603              :  end if
     604              : 
     605              : ! TODO hexu: temporarily disabled. Discuss with alex how to do this properly.
     606              : ! Do some checks
     607              : ! if (natom < 1) then
     608              : !   write(message, '(a,a,a,a,a)' )&
     609              : !&   ' Unable to read the number of atom from ',trim(filename),ch10,&
     610              : !&   'This file  is not compatible with multibinit',ch10
     611              : !   ABI_ERROR(message)
     612              : ! end if
     613              : !
     614              : ! if (filetype==2 .or. filetype==23) then
     615              : !
     616              : !   if (natom < 1) then
     617              : !     write(message, '(a,a,a)' )&
     618              : !&     ' Unable to read the number of atom from ',trim(filename),ch10
     619              : !     ABI_ERROR(message)
     620              : !   end if
     621              : !
     622              : !   if (nrpt < 1) then
     623              : !     write(message, '(a,a,a)' )&
     624              : !&     ' Unable to read the number of rpt points ',trim(filename),ch10
     625              : !     ABI_ERROR(message)
     626              : !   end if
     627              : !
     628              : !   if (ntypat < 1) then
     629              : !     write(message, '(a,a,a)' )&
     630              : !&     ' Unable to read the number of type of atoms ',trim(filename),ch10
     631              : !     ABI_ERROR(message)
     632              : !   end if
     633              : !
     634              : ! end if
     635              : 
     636          134 : end subroutine effective_potential_file_getDimSystem
     637              : !!***
     638              : 
     639              : !!****f* m_effective_potential_file/effective_potential_file_getDimCoeff
     640              : !!
     641              : !! NAME
     642              : !! effective_potential_file_getDimCoeff
     643              : !!
     644              : !! FUNCTION
     645              : !! This routine test the xml with polynomial coefficients
     646              : !! Return the number of coefficients and the maximum number of displacement/strain
     647              : !!
     648              : !! INPUTS
     649              : !! filename = names of the files
     650              : !!
     651              : !! OUTPUT
     652              : !! ncoeff = number of coefficient for the polynome
     653              : !! nterm(ncoeff) = number terms per coefficient
     654              : !! ndisp(nterm,ncoeff) = number displacement per term
     655              : !!
     656              : !! SOURCE
     657              : 
     658           28 : subroutine effective_potential_file_getDimCoeff(filename,ncoeff,ndisp_max,nterm_max)
     659              : 
     660              : !Arguments ------------------------------------
     661              : !scalars
     662              :  character(len=fnlen),intent(in) :: filename
     663              :  integer,intent(out) :: ncoeff,ndisp_max,nterm_max
     664              : !Local variables-------------------------------
     665              :  !scalar
     666              :  integer ::  filetype
     667              : #ifndef HAVE_XML
     668              :  integer ::  count,count2
     669              :  integer :: funit = 1,ios=0
     670              :  logical :: found,found2
     671              : #endif
     672              : !arrays
     673              : #ifndef HAVE_XML
     674              :  character (len=XML_RECL) :: line,readline
     675              : #endif
     676              :  character(len=500) :: message
     677              : ! *************************************************************************
     678              : 
     679           28 :  call effective_potential_file_getType(filename,filetype)
     680              : 
     681           28 :  if (filetype==3 .or. filetype==23) then
     682           28 :    write(message, '(2a)' )' Extraction of the number of coefficient in the XML ',&
     683           56 : &                         trim(filename)
     684           28 :    call wrtout(std_out,message,'COLL')
     685              : 
     686           28 :    ncoeff = 0
     687           28 :    nterm_max = 0
     688           28 :    ndisp_max = 0
     689              : 
     690              : #if defined HAVE_XML
     691              : !  Read with libxml the number of coefficient
     692              :    call effpot_xml_getDimCoeff(char_f2c(trim(filename)),ncoeff,nterm_max,ndisp_max)
     693              : #else
     694              : !  Read by hand
     695              : !  Start a reading loop
     696           28 :    found=.false.
     697              :    ncoeff = 0
     698              : 
     699           28 :    if (open_file(filename,message,unit=funit,form="formatted",status="old",&
     700              : &                action="read") /= 0) then
     701            0 :      ABI_ERROR(message)
     702              :    end if
     703              : 
     704              : !  First parse to know the number of coefficients
     705           28 :    ios = 0
     706         5038 :    do while (ios == 0)
     707         5010 :      read(funit,'(a)',iostat=ios) readline
     708         5038 :      if(ios == 0)then
     709         4982 :        call rmtabfromline(readline)
     710         4982 :        line=adjustl(readline)
     711              : !      Need test with char(9) because the old version of XML file
     712              : !      from old script includes tarbulation at the begining of each line
     713         4982 :        if (line(1:12)==char(60)//'coefficient') then
     714         1802 :          ncoeff=ncoeff+1
     715         1802 :          count = 0
     716         1802 :          found = .false.
     717              :          do while(.not.found)
     718        49004 :            read(funit,'(a)',iostat=ios) readline
     719        49004 :            call rmtabfromline(readline)
     720        49004 :            line=adjustl(readline)
     721        49004 :            if (line(1:5)==char(60)//'term') then
     722        47202 :              count = count +1
     723        47202 :              found2 = .false.
     724        47202 :              count2 = 0
     725              :              do while(.not.found2)
     726       501636 :                read(funit,'(a)',iostat=ios) readline
     727       501636 :                call rmtabfromline(readline)
     728       501636 :                line=adjustl(readline)
     729       501636 :                if (line(1:13)==char(60)//'displacement') then
     730       109854 :                  count2 = count2 + 1
     731       391782 :                else if (line(1:7)==char(60)//'strain') then
     732        15018 :                  count2 = count2 + 1
     733       376764 :                else if (line(1:6)==char(60)//'/term') then
     734        47202 :                  if (count2 > ndisp_max) ndisp_max = count2
     735              :                  found2 = .true.
     736              :                else
     737       329562 :                  cycle
     738              :                end if
     739              :              end do
     740         1802 :            else  if (line(1:13)==char(60)//'/coefficient') then
     741         1802 :              if (count > nterm_max) nterm_max = count
     742              :              found = .true.
     743              :            else
     744            0 :              cycle
     745              :            end if
     746              :          end do
     747              :          cycle
     748              :        end if
     749              :      end if
     750              :    end do
     751              : 
     752           28 :    close(funit)
     753              : #endif
     754              : 
     755              :  else
     756              : !  Maybe one day add an other type of file...
     757              :    write(message, '(a,a,a,a)' )&
     758            0 : &   ' The file ',trim(filename),' is not compatible with multibinit',ch10
     759            0 :    ABI_ERROR(message)
     760              :  end if
     761              : 
     762              : ! Do some checks
     763           28 :  if (ncoeff < 1) then
     764              :    write(message, '(5a)' )&
     765            0 : &   ' Unable to read the number of coeff from ',trim(filename),ch10,&
     766            0 : &   ' This file is not compatible with multibinit',ch10
     767            0 :    ABI_ERROR(message)
     768              :  end if
     769              : 
     770           28 : end subroutine effective_potential_file_getDimCoeff
     771              : !!***
     772              : 
     773              : 
     774              : !!****f* m_effective_potential_file/effective_potential_file_getDimStrainCoupling
     775              : !!
     776              : !! NAME
     777              : !! effective_potential_file_getDimStrainCoupling
     778              : !!
     779              : !! FUNCTION
     780              : !! Return the number of nrpt for specific strain coupling from xml system file
     781              : !!
     782              : !! INPUTS
     783              : !! filename = names of the files
     784              : !! voigt    = voigt notation of the strain
     785              : !!
     786              : !! OUTPUT
     787              : !! nrpt  = number of rpt points
     788              : !!
     789              : !! SOURCE
     790              : 
     791          228 : subroutine effective_potential_file_getDimStrainCoupling(filename,nrpt,voigt)
     792              : 
     793              : !Arguments ------------------------------------
     794              : !scalars
     795              :  character(len=fnlen),intent(in) :: filename
     796              :  integer,intent(in) :: voigt
     797              :  integer,intent(out) :: nrpt
     798              : !Local variables-------------------------------
     799              :  !scalar
     800              : #ifndef HAVE_XML
     801              :  integer :: irpt,ivoigt
     802              :  integer :: funit = 1,ios=0
     803              :  logical :: found
     804              : #endif
     805              : !arrays
     806              : #ifndef HAVE_XML
     807              :  character (len=XML_RECL) :: line,readline,strg,strg1
     808              :  character(len=500) :: message
     809              : #endif
     810              : ! *************************************************************************
     811              : 
     812          228 :    nrpt = 0
     813              : 
     814              : #if defined HAVE_XML
     815              : !  Read with libxml the number of coefficient
     816              :    call effpot_xml_getDimStrainCoupling(char_f2c(trim(filename)),nrpt,voigt)
     817              : #else
     818              : !  Read by hand
     819              : !  Start a reading loop
     820          228 :    found=.false.
     821              : 
     822          228 :    if (open_file(filename,message,unit=funit,form="formatted",status="old",&
     823              : &                action="read") /= 0) then
     824            0 :      ABI_ERROR(message)
     825              :    end if
     826              : 
     827              : !  First parse to know the number of atoms
     828       349458 :    do while (ios == 0.and.(.not.found))
     829       349230 :      read(funit,'(a)',iostat=ios) readline
     830       349458 :      if(ios == 0)then
     831       349230 :        call rmtabfromline(readline)
     832       349230 :        line=adjustl(readline)
     833       349230 :        if ((line(1:16)=='<strain_coupling')) then
     834          798 :          read(funit,'(a)',iostat=ios) readline
     835          798 :          call rdfromline("voigt",line,strg)
     836          798 :          strg1=trim(strg)
     837          798 :          read(strg1,*) ivoigt
     838          798 :          if (ivoigt == voigt)then
     839              :            irpt = 0
     840              :            do while (.not.found)
     841         2592 :              read(funit,'(a)',iostat=ios) readline
     842         2592 :              call rmtabfromline(readline)
     843         2592 :              line=adjustl(readline)
     844         2592 :              if ((line(1:26)=='<correction_force_constant')) then
     845            0 :                irpt = irpt + 1
     846            0 :                cycle
     847              :              end if
     848         2592 :              if ((line(1:17)=='</strain_coupling')) then
     849          228 :                found = .TRUE.
     850          228 :                nrpt = irpt
     851              :                cycle
     852              :              end if
     853              :            end do
     854              :          else
     855              :            cycle
     856              :          end if
     857              :        end if
     858              :      end if
     859              :    end do
     860              : 
     861          228 :    close(funit)
     862              : #endif
     863              : 
     864          228 : end subroutine effective_potential_file_getDimStrainCoupling
     865              : !!***
     866              : 
     867              : !!****f* m_effective_potential_file/effective_potential_file_getDimMD
     868              : !!
     869              : !! NAME
     870              : !! effective_potential_file_getDimMD
     871              : !!
     872              : !! FUNCTION
     873              : !! Read MD FILE (HIST or ASCII) and return the dimensions
     874              : !! (natom and nstep)
     875              : !!
     876              : !! INPUTS
     877              : !! filename = path of the file
     878              : !!
     879              : !! OUTPUT
     880              : !! natom = number of atoms
     881              : !! nstep = number of MD steps
     882              : !!
     883              : !! SOURCE
     884              : 
     885            0 : subroutine effective_potential_file_getDimMD(filename,natom,nstep)
     886              : 
     887              : !Arguments ------------------------------------
     888              : !scalars
     889              :  integer,intent(out) :: natom,nstep
     890              : !arrays
     891              :  character(len=fnlen),intent(in) :: filename
     892              : !Local variables-------------------------------
     893              : !scalar
     894              :  integer :: ia,natm_old,natm_new
     895              :  integer :: nenergy,nrprimd
     896              :  integer :: ios=0,ios2=0,ios3=0
     897              :  integer :: unit_md=24
     898              :  logical :: compatible,netcdf
     899              :  integer :: natom_id,time_id,xyz_id,six_id
     900              :  integer :: ncid,ncerr
     901              :  character(len=5) :: char_tmp
     902              : !arrays
     903              :  character (len=10000) :: readline,line
     904              :  character(len=500) :: msg
     905              : ! *************************************************************************
     906              : 
     907            0 :  natom = 0
     908            0 :  nstep = 0
     909              : !try to read netcdf
     910            0 :  netcdf = .false.
     911            0 :  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
     912            0 :  if(ncerr == NF90_NOERR) then
     913            0 :    netcdf = .TRUE.
     914            0 :    ncerr = nf90_inq_dimid(ncid,"natom",natom_id)
     915            0 :    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
     916            0 :    ncerr = nf90_inq_dimid(ncid,"xyz",xyz_id)
     917            0 :    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
     918            0 :    ncerr = nf90_inq_dimid(ncid,"time",time_id)
     919            0 :    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
     920            0 :    ncerr = nf90_inq_dimid(ncid,"six",six_id)
     921            0 :    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
     922            0 :    if(netcdf)then
     923            0 :      ncerr = nf90_inquire_dimension(ncid,natom_id,char_tmp,natom)
     924            0 :      NCF_CHECK_MSG(ncerr," inquire dimension ID for natom")
     925            0 :      ncerr = nf90_inquire_dimension(ncid,time_id,char_tmp,nstep)
     926            0 :      NCF_CHECK_MSG(ncerr," inquire dimension ID for time")
     927              :    end if
     928              :  end if
     929              : 
     930            0 :  if(.not.netcdf) then
     931              : !  try to read ASCII file...
     932            0 :    if (open_file(filename,msg,unit=unit_md,form="formatted",&
     933              : &       status="old",action="read") /= 0) then
     934            0 :      ABI_ERROR(msg)
     935              :    end if
     936              : 
     937              : !  Start a reading loop in fortran to get the dimension of the file
     938            0 :    rewind(unit=unit_md)
     939            0 :    ios = 0
     940            0 :    nstep   = 0
     941            0 :    nrprimd = 0
     942            0 :    natm_old= 0
     943            0 :    natm_new= 0
     944            0 :    nenergy = 0
     945            0 :    compatible = .TRUE.
     946              : 
     947            0 :    do while ((ios==0))
     948              : !    special treatment of the first step
     949            0 :      if(nstep==0)then
     950            0 :        ios2 = 0
     951            0 :        do while ((ios2==0))
     952            0 :          read(unit_md,'(a)',iostat=ios) readline
     953            0 :          line=adjustl(readline)
     954            0 :          call elementfromline(line,ia)
     955            0 :          if (ia==1)then
     956            0 :            nstep = nstep + 1
     957            0 :            ios2 = 1
     958              :          end if
     959              :        end do
     960              :      end if
     961            0 :      read(unit_md,'(a)',iostat=ios) readline
     962            0 :      if(ios == 0)then
     963            0 :        line=adjustl(readline)
     964            0 :        call elementfromline(line,ia)
     965            0 :        if (ia==1)then
     966            0 :          nenergy = nenergy + 1
     967            0 :          nrprimd = 0
     968            0 :        else if(ia==3)then
     969            0 :          nrprimd = nrprimd + 1
     970              :        end if
     971            0 :        if(nrprimd == 3)then
     972            0 :          ios3 = 0
     973            0 :          natm_new = 0
     974            0 :          do while ((ios3==0))
     975            0 :            read(unit_md,'(a)',iostat=ios3) readline
     976            0 :            if(ios3==0)then
     977            0 :              line=adjustl(readline)
     978            0 :              call elementfromline(line,ia)
     979            0 :              if(ia==1)then
     980            0 :                if(nstep==1) then
     981              :                  natm_old = natm_new
     982              :                else
     983            0 :                  if(natm_old /= natm_new) compatible = .FALSE.
     984              :                end if
     985            0 :                ios3 = 1
     986            0 :                ios2 = 1
     987            0 :                nstep = nstep + 1
     988              :              end if
     989            0 :              if(ia==6)then
     990            0 :                natm_new = natm_new + 1
     991              :              end if
     992              :            end if!end if ios3
     993              :          end do
     994              :        end if ! end if nrprimd
     995              :      end if! end if os1
     996              :    end do
     997              : 
     998            0 :    natom = natm_new - 1
     999            0 :    if(nstep /= nenergy) compatible = .FALSE.
    1000            0 :    if(natom <= 0) compatible = .FALSE.
    1001            0 :    if(nstep <= 0) compatible = .FALSE.
    1002              : 
    1003            0 :    if(.not.compatible)then
    1004            0 :      natom = 0
    1005            0 :      nstep = 0
    1006              :    end if
    1007              :  end if! end if not netcdf
    1008              : 
    1009            0 : end subroutine effective_potential_file_getDimMD
    1010              : !!***
    1011              : 
    1012              : !!****f* m_effective_potential_file/system_getDimFromXML
    1013              : !! NAME
    1014              : !! system_getDimFromXML
    1015              : !!
    1016              : !! FUNCTION
    1017              : !! Open xml file of effective potentiel, then reads the variables that
    1018              : !! must be known in order to dimension the arrays before complete reading
    1019              : !!
    1020              : !! INPUTS
    1021              : !! character(len=*) filnam: name of input or output file
    1022              : !!
    1023              : !! OUTPUT
    1024              : !! natom=number of atoms
    1025              : !! ntypat=number of atom types
    1026              : !! nrpt  =number of real space points used to integrate IFC
    1027              : !  nph1l =number of wavevectors for phonon
    1028              : !!
    1029              : !! SOURCE
    1030              : 
    1031           76 : subroutine system_getDimFromXML(filename,natom,ntypat,nph1l,nrpt)
    1032              : 
    1033              :  !Arguments ------------------------------------
    1034              :  !scalars
    1035              :   character(len=fnlen),intent(in) :: filename
    1036              :   integer, intent(out) :: natom,ntypat,nph1l,nrpt
    1037              :  !arrays
    1038              :  !Local variables-------------------------------
    1039              :  !scalar
    1040              :   integer :: nrpt1,nrpt2
    1041              :   real :: itypat
    1042              :   character(len=500) :: message
    1043              : #ifndef HAVE_XML
    1044              :   integer :: funit = 1,ios = 0
    1045              :   integer :: iatom
    1046              :   logical :: found
    1047              :   character (len=XML_RECL) :: line,readline
    1048              :   character (len=XML_RECL) :: strg,strg1
    1049              : #endif
    1050              :   !arrays
    1051              : #ifndef HAVE_XML
    1052           76 :   integer,allocatable :: typat(:)
    1053              : #endif
    1054              :  ! *************************************************************************
    1055              : 
    1056              : !Open the atomicdata XML file for reading
    1057           76 :  write(message,'(5a)') ' system_getDimFromXML :',&
    1058           76 : &    '-Opening the file ',trim(filename),' to read dimensions',&
    1059          152 : &    ' (before initialisation)'
    1060              : 
    1061           76 :  call wrtout(std_out,message,'COLL')
    1062              : 
    1063           76 :  natom = 0
    1064           76 :  ntypat= 0
    1065           76 :  nph1l = 0
    1066           76 :  nrpt  = 0
    1067           76 :  nrpt1 = 0
    1068           76 :  nrpt2 = 0
    1069           76 :  itypat= 0
    1070              : 
    1071              : !Open the atomicdata XML file for reading
    1072              : 
    1073              : #if defined HAVE_XML
    1074              : !Read with libxml
    1075              :  call effpot_xml_getDimSystem(char_f2c(trim(filename)),natom,ntypat,nph1l,nrpt1,nrpt2)
    1076              : #else
    1077              : !Read by hand
    1078              : 
    1079              : !Start a reading loop
    1080           76 :  found=.false.
    1081              : 
    1082           76 :  if (open_file(filename,message,unit=funit,form="formatted",status="old",&
    1083              : &              action="read") /= 0) then
    1084            0 :    ABI_ERROR(message)
    1085              :  end if
    1086              : 
    1087              : !First parse to know the number of atoms
    1088       297112 :  do while ((ios==0).and.(.not.found))
    1089       297036 :    read(funit,'(a)',iostat=ios) readline
    1090       297112 :    if(ios ==0)then
    1091       296960 :      call rmtabfromline(readline)
    1092       296960 :      line=adjustl(readline)
    1093              : 
    1094              : !Need test with char(9) because the old version of XML file
    1095              : !from old script includes tarbulation at the begining of each line
    1096       296960 :      if (line(1:5)==char(60)//'atom') then
    1097          408 :        natom=natom+1
    1098          408 :        cycle
    1099              :      end if
    1100              : 
    1101       296552 :      if (line(1:21)==char(60)//'local_force_constant') then
    1102         2256 :        nrpt1 = nrpt1+1
    1103         2256 :        cycle
    1104              :      end if
    1105              : 
    1106       294296 :      if (line(1:21)==char(60)//'total_force_constant') then
    1107         2166 :        nrpt2 = nrpt2+1
    1108         2166 :        cycle
    1109              :      end if
    1110              : 
    1111       292130 :      if (line(1:7)==char(60)//'qpoint') then
    1112          284 :        nph1l =  nph1l+1
    1113          284 :        cycle
    1114              :      end if
    1115              :    end if
    1116              :  end do
    1117              : 
    1118              : !second parse to get the number of typat
    1119          228 :  ABI_MALLOC(typat,(natom))
    1120          484 :  typat = 0
    1121           76 :  iatom = 0
    1122              : 
    1123           76 :  rewind(funit)
    1124              : !Start a reading loop
    1125           76 :  ios   = 0
    1126           76 :  found = .false.
    1127              : 
    1128         5980 :  do while ((ios==0).and.(.not.found))
    1129         5904 :    read(funit,'(a)',iostat=ios) readline
    1130         5980 :    if(ios == 0)then
    1131         5904 :      call rmtabfromline(readline)
    1132         5904 :      line=adjustl(readline)
    1133              : 
    1134         5904 :      if (line(1:5)==char(60)//'atom') then
    1135          408 :        iatom = iatom + 1
    1136          408 :        call rdfromline("mass",line,strg)
    1137          408 :        strg1=trim(strg)
    1138          408 :        read(unit=strg1,fmt=*) itypat
    1139         2128 :        if (.not.any(typat==int(itypat))) then
    1140          196 :          ntypat= ntypat+1
    1141              :        end if
    1142          408 :        typat(iatom) = int(itypat)
    1143              :      end if
    1144              : 
    1145         5904 :      if (line(1:6)==char(60)//'local') then
    1146           76 :        found=.true.
    1147              :      end if
    1148              :    end if
    1149              :  end do
    1150              : 
    1151           76 :  close(funit)
    1152           76 :  ABI_FREE(typat)
    1153              : 
    1154              : #endif
    1155              : 
    1156              : !Check the RPT
    1157           76 :  if (nrpt2/=nrpt1) then
    1158           46 :    if(nrpt1> 0 .and. nrpt2== 0) then
    1159              :      continue;
    1160           32 :    else if (nrpt1==0.and.nrpt2>=0) then
    1161            0 :      write(message, '(5a)' )ch10,&
    1162            0 : &   ' WARNING: the number of local IFC is set to 0  ',ch10,&
    1163            0 : &   '          Dipdip must be set to zero',ch10
    1164            0 :      call wrtout(std_out,message,'COLL')
    1165           32 :    else if (nrpt2 > nrpt1) then
    1166           32 :      write(message, '(2a,I0,3a,I0,5a)' )ch10,&
    1167           32 : &   ' WARNING: the number of total IFC  (',nrpt2,') is not equal to the  ',ch10,&
    1168           32 : &   '          the number of short range IFC (',nrpt1,') in ',trim(filename),ch10,&
    1169           64 : &   '          the missing ifc will be set to zero',ch10
    1170           32 :      call wrtout(std_out,message,'COLL')
    1171              :    else if(nrpt1>nrpt2)then
    1172            0 :      write(message, '(2a,I0,3a,I0,5a)' )ch10,&
    1173            0 : &   ' The number of total IFC  (',nrpt2,') is inferior to  ',ch10,&
    1174            0 : &   ' the number of short range IFC (',nrpt1,') in ',trim(filename),ch10,&
    1175            0 : &   ' This is not possible',ch10
    1176            0 :      ABI_BUG(message)
    1177              :    end if
    1178              :  end if
    1179              : 
    1180              : !nrpt is the max between local and total:
    1181           76 :  nrpt = max(nrpt1,nrpt2)
    1182              : 
    1183              : 
    1184           76 : end subroutine system_getDimFromXML
    1185              : !!***
    1186              : 
    1187              : !!****f* m_effective_potential_file/system_xml2effpot
    1188              : !! NAME
    1189              : !! system_xml2effpot
    1190              : !!
    1191              : !! FUNCTION
    1192              : !! Open xml file of effective potentiel, then reads the variables
    1193              : !! and store them in effective potentential type
    1194              : !!
    1195              : !! INPUTS
    1196              : !! eff_pot<type(effective_potential_type)> = datatype with all the information for effective potential
    1197              : !! comm=MPI communicator
    1198              : !! character(len=*) filnam: name of input or output file
    1199              : !! strcpling = optional,logical to disable the strcpling
    1200              : !!
    1201              : !! OUTPUT
    1202              : !! eff_pot<type(effective_potential_type)> = datatype with all the information for effective potential
    1203              : !!
    1204              : !! SOURCE
    1205              : 
    1206           38 :  subroutine system_xml2effpot(eff_pot,filename,comm,strcpling)
    1207              : 
    1208              :  use m_atomdata
    1209              :  use m_multibinit_dataset, only : multibinit_dtset_type
    1210              :  use m_ab7_symmetry
    1211              : 
    1212              :  !Arguments ------------------------------------
    1213              :  !scalars
    1214              :  character(len=*),intent(in) :: filename
    1215              :  integer, intent(in) :: comm
    1216              :  integer, optional,intent(in) :: strcpling
    1217              :  !arrays
    1218              :  type(effective_potential_type), intent(inout) :: eff_pot
    1219              : 
    1220              :  !Local variables-------------------------------
    1221              :  !scalar
    1222              :  integer :: ierr,ii,itypat,my_rank,msym,natom,ncoeff,nrpt,nrpt_scoupling
    1223              :  integer :: ntypat,nph1l,nptsym,npsp,nproc,nsym,space_group,timrev,use_inversion,voigt
    1224              :  real(dp):: energy,tolsym,ucvol
    1225              :  character(len=500) :: message
    1226              :  integer,parameter :: master=0
    1227              :  logical :: has_anharmonics
    1228              :  logical :: iam_master
    1229              : #ifndef HAVE_XML
    1230              :  integer :: funit = 1,ios=0
    1231              :  integer :: iatom,iamu,iph1l,irpt,irpt1,irpt2,irpt3,jj,mu,nu
    1232              :  real(dp):: amu
    1233              :  logical :: found,found2,short_range,total_range
    1234              :  character (len=XML_RECL) :: line,readline
    1235              :  character (len=XML_RECL) :: strg,strg1
    1236              :  logical :: has_straincoupling
    1237              : #endif
    1238              :  !arrays
    1239              :  integer :: bravais(11)
    1240           38 :  integer,allocatable :: typat(:)
    1241           38 :  integer,allocatable  :: symrel(:,:,:),symafm(:),ptsymrel(:,:,:)
    1242              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
    1243              :  real(dp) :: elastic_constants(6,6),elastic3rd(6,6,6),epsilon_inf(3,3)
    1244           38 :  real(dp),allocatable :: all_amu(:),cell_local(:,:),cell_total(:,:)
    1245           38 :  real(dp),allocatable :: elastic_displacement(:,:,:,:),dynmat(:,:,:,:,:,:)
    1246           38 :  real(dp),allocatable :: local_atmfrc(:,:,:,:,:),total_atmfrc(:,:,:,:,:)
    1247           38 :  real(dp),allocatable :: spinat(:,:),strain_coupling(:,:,:),phfrq(:,:),qph1l(:,:),tnons(:,:)
    1248           38 :  real(dp),allocatable :: xcart(:,:),xred(:,:),zeff(:,:,:),znucl(:),zion(:)
    1249           38 :  character(len=132),allocatable :: title(:)
    1250          228 :  type(ifc_type) :: ifcs
    1251           38 :  type(ifc_type),dimension(:),allocatable :: phonon_strain
    1252         1976 :  type(crystal_t)  :: crystal
    1253              :  type(atomdata_t) :: atom
    1254              : #ifdef HAVE_XML
    1255              :  real(dp),allocatable :: phonon_strain_atmfrc(:,:,:,:,:)
    1256              :  integer,allocatable  :: phonon_straincell(:,:)
    1257              : #endif
    1258              : #ifndef HAVE_XML
    1259           38 :  real(dp),allocatable :: work2(:,:)
    1260              : #endif
    1261              : ! *************************************************************************
    1262              : 
    1263              :  !Open the atomicdata XML file for reading
    1264           38 :  write(message,'(a,a)')'-Opening the file ',trim(filename)
    1265              : 
    1266           38 :  call wrtout(ab_out,message,'COLL')
    1267           38 :  call wrtout(std_out,message,'COLL')
    1268              : 
    1269           38 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    1270           38 :  iam_master = (my_rank == master)
    1271              : 
    1272              : !Get Dimention of system and allocation/initialisation of array
    1273           38 :  call effective_potential_file_getDimSystem(filename,comm,natom,ntypat,nph1l,nrpt)
    1274           38 :  gmet= zero; gprimd = zero; rmet = zero; rprimd = zero
    1275           38 :  elastic_constants = zero; epsilon_inf = zero; ncoeff = 0
    1276          114 :  ABI_MALLOC(all_amu,(ntypat))
    1277          114 :  ABI_MALLOC(cell_local,(3,nrpt))
    1278           76 :  ABI_MALLOC(cell_total,(3,nrpt))
    1279          114 :  ABI_MALLOC(elastic_displacement,(6,6,3,natom))
    1280          228 :  ABI_MALLOC(ifcs%atmfrc,(3,natom,3,natom,nrpt))
    1281          114 :  ABI_MALLOC(ifcs%cell,(3,nrpt))
    1282          152 :  ABI_MALLOC(ifcs%short_atmfrc,(3,natom,3,natom,nrpt))
    1283          152 :  ABI_MALLOC(ifcs%ewald_atmfrc,(3,natom,3,natom,nrpt))
    1284          114 :  ABI_MALLOC(strain_coupling,(6,3,natom))
    1285          152 :  ABI_MALLOC(total_atmfrc,(3,natom,3,natom,nrpt))
    1286          152 :  ABI_MALLOC(local_atmfrc,(3,natom,3,natom,nrpt))
    1287          228 :  ABI_MALLOC(dynmat,(2,3,natom,3,natom,nph1l))
    1288          114 :  ABI_MALLOC(typat,(natom))
    1289          152 :  ABI_MALLOC(phfrq,(3*natom,nph1l))
    1290          114 :  ABI_MALLOC(qph1l,(3,nph1l))
    1291          114 :  ABI_MALLOC(xcart,(3,natom))
    1292           76 :  ABI_MALLOC(xred,(3,natom))
    1293          114 :  ABI_MALLOC(zeff,(3,3,natom))
    1294           76 :  ABI_MALLOC(zion,(ntypat))
    1295           76 :  ABI_MALLOC(znucl,(ntypat))
    1296              : 
    1297          456 :  ABI_MALLOC(phonon_strain,(6))
    1298           38 :  nrpt_scoupling = 0
    1299          266 :  do ii = 1,6
    1300              : !  Get The size of the strainPhonon-coupling
    1301          228 :    call effective_potential_file_getDimStrainCoupling(filename,nrpt_scoupling,ii-1)
    1302         1140 :    ABI_MALLOC(phonon_strain(ii)%atmfrc,(3,natom,3,natom,nrpt_scoupling))
    1303          684 :    ABI_MALLOC(phonon_strain(ii)%cell,(3,nrpt_scoupling))
    1304          228 :    phonon_strain(ii)%nrpt   = nrpt_scoupling
    1305          228 :    phonon_strain(ii)%atmfrc = zero
    1306          266 :    phonon_strain(ii)%cell   = 0
    1307              :  end do
    1308              : 
    1309          136 :  all_amu(:) = zero
    1310        97068 :  dynmat(:,:,:,:,:,:)  = zero
    1311         5126 :  cell_local(:,:) = 99D99
    1312         5126 :  cell_total(:,:) = 99D99
    1313           38 :  elastic3rd(:,:,:) = zero
    1314        26558 :  elastic_displacement(:,:,:,:) = zero
    1315           38 :  ifcs%nrpt = nrpt
    1316       633086 :  ifcs%atmfrc(:,:,:,:,:)  = zero
    1317         5126 :  ifcs%cell(:,:)  = 0
    1318       633086 :  ifcs%ewald_atmfrc(:,:,:,:,:) = zero
    1319       633086 :  ifcs%short_atmfrc(:,:,:,:,:) = zero
    1320         4526 :  strain_coupling(:,:,:) = zero
    1321         2016 :  phfrq = zero
    1322          606 :  qph1l = 0
    1323          854 :  xcart = zero
    1324         2690 :  zeff  = zero
    1325          136 :  znucl = zero
    1326              : 
    1327           38 :  if(iam_master)then
    1328              : !Open the atomicdata XML file for reading
    1329              : #if defined HAVE_XML
    1330              : 
    1331              :    write(message,'(a,a,a,a)')'-Reading the file ',trim(filename),&
    1332              : &   ' with LibXML library'
    1333              : 
    1334              :    call wrtout(ab_out,message,'COLL')
    1335              :    call wrtout(std_out,message,'COLL')
    1336              : 
    1337              : !  Read with libxml library
    1338              :    call effpot_xml_readSystem(char_f2c(trim(filename)),natom,ntypat,nrpt,nph1l,all_amu,&
    1339              : &                       ifcs%atmfrc,ifcs%cell,dynmat,elastic_constants,energy,&
    1340              : &                       epsilon_inf,ifcs%ewald_atmfrc,phfrq,rprimd,qph1l,&
    1341              : &                       ifcs%short_atmfrc,typat,xcart,zeff)
    1342              : 
    1343              : !  convert atomic mass unit to znucl
    1344              :    do itypat=1,ntypat
    1345              :      do ii=1,103
    1346              :        call atomdata_from_znucl(atom,real(ii,dp))
    1347              :        if (abs((real(atom%amu,sp)-real(all_amu(itypat),sp))&
    1348              : &         /real(all_amu(itypat),sp)*100)<0.1) then
    1349              :          znucl(itypat) = atom%znucl
    1350              :          exit
    1351              :        end if
    1352              :      end do
    1353              :    end do
    1354              : 
    1355              : !  Get the Phonon Strain coupling
    1356              :    do voigt = 1,6
    1357              :      nrpt_scoupling = phonon_strain(voigt)%nrpt
    1358              :      ABI_MALLOC(phonon_straincell,(3,nrpt_scoupling))
    1359              :      ABI_MALLOC(phonon_strain_atmfrc,(3,natom,3,natom,nrpt_scoupling))
    1360              : 
    1361              : !      Get The value
    1362              :        call effpot_xml_readStrainCoupling(char_f2c(trim(filename)),natom,nrpt_scoupling,(voigt-1),&
    1363              : &                                         elastic3rd(voigt,:,:),elastic_displacement(voigt,:,:,:),&
    1364              : &                                         strain_coupling(voigt,:,:),&
    1365              : &                                         phonon_strain_atmfrc,phonon_straincell)
    1366              : 
    1367              : !      Check if the 3rd order strain_coupling is present
    1368              :        has_anharmonics = .FALSE.
    1369              :        if(any(elastic3rd>tol10).or.any(elastic_displacement>tol10)) has_anharmonics = .TRUE.
    1370              :        phonon_strain(voigt)%atmfrc(:,:,:,:,:) = phonon_strain_atmfrc(:,:,:,:,:)
    1371              :        phonon_strain(voigt)%cell(:,:)   = phonon_straincell(:,:)
    1372              :        if(any(phonon_strain(voigt)%atmfrc > tol10)) has_anharmonics = .TRUE.
    1373              : 
    1374              :        ABI_FREE(phonon_straincell)
    1375              :        ABI_FREE(phonon_strain_atmfrc)
    1376              :    end do
    1377              : #else
    1378              : 
    1379              : ! Read by hand
    1380           22 :    write(message,'(a,a,a,a)')'-Reading the file ',trim(filename),&
    1381           44 : & ' with Fortran'
    1382              : 
    1383           22 :    call wrtout(ab_out,message,'COLL')
    1384           22 :    call wrtout(std_out,message,'COLL')
    1385              : 
    1386           22 :    if (open_file(filename,message,unit=funit,form="formatted",&
    1387              : &               status="old",action="read") /= 0) then
    1388            0 :      ABI_ERROR(message)
    1389              :    end if
    1390              : 
    1391              : !Start a reading loop in fortran
    1392           22 :    rewind(unit=funit)
    1393           22 :    found=.false.
    1394              : 
    1395           22 :    iatom  = 1
    1396           22 :    iamu   = 1
    1397           22 :    itypat = 1
    1398           22 :    irpt   = 1
    1399           22 :    irpt1  = 0
    1400           22 :    irpt2  = 0
    1401           22 :    iph1l  = 1
    1402           22 :    amu    = zero
    1403           22 :    short_range  = .false.
    1404           22 :    total_range  = .false.
    1405           22 :    has_straincoupling = .FALSE.
    1406        94533 :    do while ((ios==0).and.(.not.found))
    1407        94511 :      read(funit,'(a)',iostat=ios) readline
    1408        94533 :      if(ios == 0)then
    1409        94489 :        call rmtabfromline(readline)
    1410        94489 :        line=adjustl(readline)
    1411        94489 :        if (.not.has_straincoupling) then
    1412              : 
    1413         5163 :          if ((line(1:7)=='<energy')) then
    1414           22 :            call rdfromline_value('energy',line,strg)
    1415           22 :            if (strg/="") then
    1416            0 :              strg1=trim(strg)
    1417            0 :              read(strg1,*) energy
    1418              :            else
    1419           22 :              read(funit,'(a)',iostat=ios) readline
    1420           22 :              call rmtabfromline(readline)
    1421           22 :              line=adjustl(readline)
    1422           22 :              call rdfromline_value('energy',line,strg)
    1423           22 :              if (strg/="") then
    1424            0 :                strg1=trim(strg)
    1425              :              else
    1426           22 :                strg1=trim(line)
    1427              :              end if
    1428           22 :              read(strg1,*) energy
    1429              :            end if
    1430              :            cycle
    1431              :          end if
    1432              : 
    1433         5141 :          if ((line(1:10)=='<unit_cell')) then
    1434           22 :            call rdfromline_value('unit_cell',line,strg)
    1435           22 :            if (strg/="") then
    1436            0 :              strg1=trim(strg)
    1437            0 :              read(strg1,*) (rprimd(1,mu),mu=1,3)
    1438            0 :              read(funit,*) (rprimd(2,mu),mu=1,3)
    1439              :            else
    1440           66 :              do nu=1,2
    1441           66 :                read(funit,*) (rprimd(nu,mu),mu=1,3)
    1442              :              end do
    1443              :            end if
    1444           22 :            read(funit,'(a)',iostat=ios) readline
    1445           22 :            call rmtabfromline(readline)
    1446           22 :            line=adjustl(readline)
    1447           22 :            call rdfromline_value('unit_cell',line,strg)
    1448           22 :            if (strg/="") then
    1449            0 :              strg1=trim(strg)
    1450              :            else
    1451           22 :              strg1=trim(line)
    1452              :            end if
    1453           22 :            read(strg1,*) (rprimd(3,mu),mu=1,3)
    1454           22 :            cycle
    1455              :          end if
    1456              : 
    1457         5119 :          if ((line(1:12)=='<epsilon_inf')) then
    1458           22 :            call rdfromline_value('epsilon_inf',line,strg)
    1459           22 :            if (strg/="") then
    1460            0 :              strg1=trim(strg)
    1461            0 :              read(strg1,*) (epsilon_inf(mu,1),mu=1,3)
    1462            0 :              read(funit,*) (epsilon_inf(mu,2),mu=1,3)
    1463              :            else
    1464           66 :              do nu=1,2
    1465           66 :                read(funit,*) (epsilon_inf(mu,nu),mu=1,3)
    1466              :              end do
    1467              :            end if
    1468           22 :            read(funit,'(a)',iostat=ios) readline
    1469           22 :            call rmtabfromline(readline)
    1470           22 :            line=adjustl(readline)
    1471           22 :            call rdfromline_value('epsilon_inf',line,strg)
    1472           22 :            if (strg/="") then
    1473            0 :              strg1=trim(strg)
    1474              :            else
    1475           22 :              strg1=trim(line)
    1476              :            end if
    1477           22 :            read(strg1,*) (epsilon_inf(mu,3),mu=1,3)
    1478           22 :            cycle
    1479              :          end  if
    1480              : 
    1481         5097 :          if ((line(1:8)=='<elastic')) then
    1482           22 :            call rdfromline_value('elastic',line,strg)
    1483           22 :            if (strg/="") then
    1484            0 :              strg1=trim(strg)
    1485            0 :              read(strg1,*) (elastic_constants(mu,1),mu=1,6)
    1486            0 :              do nu=2,5
    1487            0 :                read(funit,*) (elastic_constants(mu,nu),mu=1,6)
    1488              :              end do
    1489              :            else
    1490          132 :              do nu=1,5
    1491          132 :                read(funit,*) (elastic_constants(mu,nu),mu=1,6)
    1492              :              end do
    1493              :            end if
    1494           22 :            read(funit,'(a)',iostat=ios) readline
    1495           22 :            call rmtabfromline(readline)
    1496           22 :            line=adjustl(readline)
    1497           22 :            call rdfromline_value('elastic',line,strg)
    1498           22 :            if (strg/="") then
    1499            0 :              strg1=trim(strg)
    1500              :            else
    1501           22 :              strg1=trim(line)
    1502              :            end if
    1503           22 :            read(strg1,*) (elastic_constants(mu,6),mu=1,6)
    1504           22 :            cycle
    1505              :          end if
    1506              : 
    1507         5075 :          if ((line(1:5)=='<atom')) then
    1508          132 :            call rdfromline("mass",line,strg)
    1509          132 :            strg1=trim(strg)
    1510          132 :            read(strg1,*) amu
    1511          396 :            if (.not.any(abs(all_amu-amu)<tol16)) then
    1512           58 :              all_amu(iamu) = amu
    1513           58 :              typat(iatom) = int(amu)
    1514              :              !convert atomic mass unit to znucl
    1515         1260 :              do ii=1,103
    1516         1260 :                call atomdata_from_znucl(atom,real(ii,dp))
    1517         1260 :                if (abs((real(atom%amu,sp)-real(amu,sp))&
    1518         1260 : &                 /real(amu,sp)*100)<0.1) then
    1519           58 :                  znucl(iamu) = atom%znucl
    1520           58 :                  exit
    1521              :                end if
    1522              :              end do
    1523           58 :              iamu = iamu +1
    1524              :            end if
    1525          496 :            do itypat=1,ntypat
    1526          496 :              if(abs(amu-all_amu(itypat))<tol16) then
    1527          132 :                typat(iatom) = itypat
    1528              :              end if
    1529              :            end do
    1530              :            cycle
    1531              :          end if
    1532              : 
    1533         4943 :          if ((line(1:9)=='<position')) then
    1534          132 :            call rdfromline_value('position',line,strg)
    1535          132 :            if (strg/="") then
    1536            0 :              strg1=trim(strg)
    1537            0 :              read(strg1,*)(xcart(mu,iatom),mu=1,3)
    1538              :            else
    1539          132 :              read(funit,'(a)',iostat=ios) readline
    1540          132 :              call rmtabfromline(readline)
    1541          132 :              line=adjustl(readline)
    1542          132 :              call rdfromline_value('position',line,strg)
    1543          132 :              if (strg/="") then
    1544            0 :                strg1=trim(strg)
    1545              :              else
    1546          132 :                strg1=trim(line)
    1547              :              end if
    1548          132 :              read(strg1,*)(xcart(mu,iatom),mu=1,3)
    1549              :            end if
    1550              :            cycle
    1551              :          end if
    1552              : 
    1553         4811 :          if ((line(1:11)=='<borncharge')) then
    1554          132 :            call rdfromline_value('borncharge',line,strg)
    1555          132 :            if (strg/="") then
    1556            0 :              strg1=trim(strg)
    1557            0 :              read(strg1,*) (zeff(mu,1,iatom),mu=1,3)
    1558            0 :              read(funit,*) (zeff(mu,2,iatom),mu=1,3)
    1559              :            else
    1560          396 :              do nu=1,2
    1561          396 :                read(funit,*) (zeff(mu,nu,iatom),mu=1,3)
    1562              :              end do
    1563              :            end if
    1564          132 :            read(funit,'(a)',iostat=ios) readline
    1565          132 :            line=adjustl(readline)
    1566          132 :            call rdfromline_value('borncharge',line,strg)
    1567          132 :            if (strg/="") then
    1568            0 :              strg1=trim(strg)
    1569              :            else
    1570          132 :              strg1=trim(line)
    1571              :            end if
    1572          132 :              read(strg1,*) (zeff(mu,3,iatom),mu=1,3)
    1573          132 :            cycle
    1574              :          end if
    1575              : 
    1576         4679 :          if ((line(1:7)==char(60)//char(47)//'atom'//char(62))) then
    1577          132 :            iatom=iatom+1
    1578          132 :            cycle
    1579              :          end if
    1580              : 
    1581         4547 :          if ((line(1:12)=='<local_force')) then
    1582          648 :            found2 = .False.
    1583          648 :            irpt1 = irpt1 + 1
    1584              :            do while (.not.found2)
    1585         1944 :              read(funit,'(a)',iostat=ios) readline
    1586         1944 :              call rmtabfromline(readline)
    1587         1944 :              line=adjustl(readline)
    1588         1944 :              if ((line(1:5)=='<data')) then
    1589          648 :                call rdfromline_value('data',line,strg)
    1590          648 :                if (strg/="") then
    1591            0 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1592            0 :                  strg1=trim(strg)
    1593            0 :                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
    1594            0 :                  do mu=2,3*natom-1
    1595            0 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1596              :                  end do
    1597            0 :                  read(funit,'(a)',iostat=ios) readline
    1598            0 :                  call rmtabfromline(readline)
    1599            0 :                  line=adjustl(readline)
    1600            0 :                  call rdfromline_value('data',line,strg)
    1601            0 :                  if (strg/="") then
    1602            0 :                    strg1=trim(strg)
    1603              :                  else
    1604            0 :                    strg1=trim(line)
    1605              :                  end if
    1606            0 :                  read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
    1607            0 :                  local_atmfrc(:,:,:,:,irpt1) = reshape(work2,(/3,natom,3,natom/))
    1608            0 :                  ABI_FREE(work2)
    1609              :                else
    1610         2592 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1611        12726 :                  do mu=1,3*natom
    1612        12726 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1613              :                  end do
    1614         3240 :                  local_atmfrc(:,:,:,:,irpt1) =  reshape(work2,(/3,natom,3,natom/))
    1615          648 :                  ABI_FREE(work2)
    1616              :                end if
    1617              :              end if
    1618         1944 :              if ((line(1:5)=='<cell')) then
    1619          648 :                call rdfromline_value('cell',line,strg)
    1620          648 :                if (strg/="") then
    1621            0 :                  strg1=trim(strg)
    1622            0 :                  read(strg1,*)(cell_local(mu,irpt1),mu=1,3)
    1623              :                else
    1624          648 :                  read(funit,*)(cell_local(mu,irpt1),mu=1,3)
    1625              :                end if
    1626              :                found2 = .TRUE.
    1627              :                cycle
    1628              :              end if
    1629              :            end do
    1630              :          end if
    1631              : 
    1632         4547 :          if ((line(1:12)=='<total_force')) then
    1633          531 :            irpt2 = irpt2 + 1
    1634          531 :            found2 = .False.
    1635              :            do while (.not.found2)
    1636         1593 :              read(funit,'(a)',iostat=ios) readline
    1637         1593 :              call rmtabfromline(readline)
    1638         1593 :              line=adjustl(readline)
    1639         1593 :              if ((line(1:5)=='<data')) then
    1640          531 :                call rdfromline_value('data',line,strg)
    1641          531 :                if (strg/="") then
    1642            0 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1643            0 :                  strg1=trim(strg)
    1644            0 :                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
    1645            0 :                  do mu=2,3*natom-1
    1646            0 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1647              :                  end do
    1648            0 :                  read(funit,'(a)',iostat=ios) readline
    1649            0 :                  call rmtabfromline(readline)
    1650            0 :                  line=adjustl(readline)
    1651            0 :                  call rdfromline_value('data',line,strg)
    1652            0 :                  if (strg/="") then
    1653            0 :                    strg1=trim(strg)
    1654              :                  else
    1655            0 :                    strg1=trim(line)
    1656              :                  end if
    1657            0 :                  read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
    1658            0 :                  total_atmfrc(:,:,:,:,irpt2) = reshape(work2,(/3,natom,3,natom/))
    1659            0 :                  ABI_FREE(work2)
    1660              :                else
    1661         2124 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1662         8208 :                  do mu=1,3*natom
    1663         8208 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1664              :                  end do
    1665         2655 :                  total_atmfrc(:,:,:,:,irpt2) = reshape(work2,(/3,natom,3,natom/))
    1666          531 :                  ABI_FREE(work2)
    1667              :                end if
    1668              :              end if
    1669         1593 :              if ((line(1:5)=='<cell')) then
    1670          531 :                call rdfromline_value('cell',line,strg)
    1671          531 :                if (strg/="") then
    1672            0 :                  strg1=trim(strg)
    1673            0 :                  read(strg1,*)(cell_total(mu,irpt2),mu=1,3)
    1674              :                else
    1675          531 :                  read(funit,*)(cell_total(mu,irpt2),mu=1,3)
    1676              :                end if
    1677              :                found2 = .TRUE.
    1678              :                cycle
    1679              :              end if
    1680              :            end do
    1681              :          end if
    1682              : 
    1683         4547 :          if ((line(1:7)=='<qpoint')) then
    1684           74 :            call rdfromline_value('qpoint',line,strg)
    1685           74 :            if (strg/="") then
    1686            0 :              strg1=trim(strg)
    1687            0 :              read(strg1,*)(qph1l(mu,iph1l),mu=1,3)
    1688              :            else
    1689           74 :              read(funit,*) (qph1l(mu,iph1l),mu=1,3)
    1690              :            end if
    1691              :          end if
    1692              : 
    1693         4547 :          if ((line(1:12)=='<frequencies')) then
    1694           74 :            call rdfromline_value('frequencies',line,strg)
    1695           74 :            if (strg/="") then
    1696            0 :              strg1=trim(strg)
    1697            0 :              read(strg1,*)(phfrq(mu,iph1l),mu=1,3*natom)
    1698              :            else
    1699          410 :              do nu=1,natom
    1700         1418 :                read(funit,*) (phfrq(((nu-1)*3)+mu,iph1l),mu=1,3)
    1701              :              end do
    1702              :            end if
    1703              :          end if
    1704              : 
    1705         4547 :          if ((line(1:17)=='<dynamical_matrix')) then
    1706           74 :            call rdfromline_value('dynamical_matrix',line,strg)
    1707           74 :            if (strg/="") then
    1708            0 :              ABI_MALLOC(work2,(3*natom,3*natom))
    1709            0 :              strg1=trim(strg)
    1710            0 :              read(strg1,*) (work2(nu,1),nu=1,3*natom)
    1711            0 :              do mu=2,3*natom-1
    1712            0 :                read(funit,*)(work2(nu,mu),nu=1,3*natom)
    1713              :              end do
    1714            0 :              read(funit,'(a)',iostat=ios) readline
    1715            0 :              call rmtabfromline(readline)
    1716            0 :              line=adjustl(readline)
    1717            0 :              call rdfromline_value('dynamical_matrix',line,strg)
    1718            0 :              if (strg/="") then
    1719            0 :                strg1=trim(strg)
    1720              :              else
    1721            0 :                strg1=trim(line)
    1722              :              end if
    1723            0 :              read(strg1,*) (work2(nu,3*natom),nu=1,3*natom)
    1724            0 :              dynmat(1,:,:,:,:,iph1l) = reshape(work2,(/3,natom,3,natom/))
    1725            0 :              ABI_FREE(work2)
    1726              :            else
    1727          296 :              ABI_MALLOC(work2,(3*natom,3*natom))
    1728         1082 :              do mu=1,3*natom
    1729         1082 :                read(funit,*)(work2(nu,mu),nu=1,3*natom)
    1730              :              end do
    1731        26002 :              dynmat(1,:,:,:,:,iph1l) = reshape(work2,(/3,natom,3,natom/))
    1732           74 :              ABI_FREE(work2)
    1733              :            end if
    1734              :          end if
    1735              : 
    1736         4547 :          if ((line(1:8)==char(60)//char(47)//'phonon')) then
    1737           74 :            iph1l = iph1l +1
    1738              :          end if
    1739              : 
    1740         4547 :          if ((line(1:16)=='<strain_coupling')) then
    1741           22 :            read(funit,'(a)',iostat=ios) readline
    1742           22 :            call rdfromline("voigt",line,strg)
    1743           22 :            strg1=trim(strg)
    1744           22 :            read(strg1,*) voigt
    1745           22 :            voigt = voigt + 1 ! 0 to 5 in the xml
    1746           22 :            has_straincoupling = .true.
    1747           22 :            irpt = 1
    1748              :          end if
    1749              : 
    1750              :        else
    1751              : !        Now treat the strain phonon coupling part
    1752        89326 :          if ((line(1:16)=='<strain_coupling')) then
    1753          110 :            read(funit,'(a)',iostat=ios) readline
    1754          110 :            call rdfromline("voigt",line,strg)
    1755          110 :            strg1=trim(strg)
    1756          110 :            read(strg1,*) voigt
    1757          110 :            voigt = voigt + 1 ! 0 to 5 in the xml
    1758          110 :            irpt = 1
    1759          110 :            cycle
    1760              :          end if
    1761              : 
    1762        89216 :          if(voigt>6)then
    1763            0 :            write(message, '(4a)' )ch10,&
    1764            0 : &               ' WARNING: the number of strain phonon coupling is superior to 6 in ',trim(filename),ch10
    1765            0 :            call wrtout(std_out,message,'COLL')
    1766            0 :            exit
    1767              :          end if
    1768              : 
    1769        89216 :          if ((line(1:22)=='<correction_force unit')) then
    1770          132 :            call rdfromline_value('correction_force',line,strg)
    1771          132 :            if (strg/="") then
    1772            0 :              ABI_MALLOC(work2,(3,natom))
    1773            0 :              strg1=trim(strg)
    1774            0 :              read(strg1,*) (work2(nu,1),nu=1,3)
    1775            0 :              do mu=2,natom-1
    1776            0 :                read(funit,*)(work2(nu,mu),nu=1,3)
    1777              :              end do
    1778            0 :              read(funit,'(a)',iostat=ios) readline
    1779            0 :              call rmtabfromline(readline)
    1780            0 :              line=adjustl(readline)
    1781            0 :              call rdfromline_value('correction_force',line,strg)
    1782            0 :              if (strg/="") then
    1783            0 :                strg1=trim(strg)
    1784            0 :                read(strg1,*) (work2(nu,natom),nu=1,3)
    1785              :              else
    1786            0 :                strg1=trim(line)
    1787            0 :                read(strg1,*) (work2(nu,natom),nu=1,3)
    1788              :              end if
    1789            0 :              strain_coupling(voigt,:,:) = work2(:,:)
    1790            0 :              ABI_FREE(work2)
    1791              :            else
    1792          396 :              ABI_MALLOC(work2,(3,natom))
    1793          924 :              do mu=1,natom
    1794          924 :                read(funit,*)(work2(nu,mu),nu=1,3)
    1795              :              end do
    1796         3300 :              strain_coupling(voigt,:,:) = work2(:,:)
    1797          132 :              ABI_FREE(work2)
    1798              :            end if
    1799              :          end if
    1800              : 
    1801        89216 :          if ((line(1:11)=='<elastic3rd')) then
    1802            0 :            call rdfromline_value('elastic3rd',line,strg)
    1803            0 :            if (strg/="") then
    1804            0 :              strg1=trim(strg)
    1805            0 :              read(strg1,*) (elastic3rd(voigt,mu,1),mu=1,6)
    1806            0 :              do nu=2,5
    1807            0 :                read(funit,*) (elastic3rd(voigt,mu,nu),mu=1,6)
    1808              :              end do
    1809              :            else
    1810            0 :              do nu=1,5
    1811            0 :                read(funit,*) (elastic3rd(voigt,mu,nu),mu=1,6)
    1812              :              end do
    1813              :            end if
    1814            0 :            read(funit,'(a)',iostat=ios) readline
    1815            0 :            call rmtabfromline(readline)
    1816            0 :            line=adjustl(readline)
    1817            0 :            call rdfromline_value('elastic3rd',line,strg)
    1818            0 :            if (strg/="") then
    1819            0 :              strg1=trim(strg)
    1820            0 :              read(strg1,*) (elastic3rd(voigt,mu,6),mu=1,6)
    1821              :            else
    1822            0 :              strg1=trim(line)
    1823            0 :              read(strg1,*) (elastic3rd(voigt,mu,6),mu=1,6)
    1824              :            end if
    1825            0 :            has_anharmonics = .true.
    1826            0 :            cycle
    1827              :          end if
    1828              : 
    1829        89216 :          if ((line(1:29)=='<correction_strain_force unit')) then
    1830            0 :            call rdfromline_value('correction_strain_force',line,strg)
    1831            0 :            if (strg/="") then
    1832            0 :              ABI_MALLOC(work2,(3*6,natom))
    1833            0 :              strg1=trim(strg)
    1834            0 :              read(strg1,*) (work2(nu,1),nu=1,3*6)
    1835            0 :              do mu=2,natom-1
    1836            0 :                read(funit,*)(work2(nu,mu),nu=1,3*6)
    1837              :              end do
    1838            0 :              read(funit,'(a)',iostat=ios) readline
    1839            0 :              call rmtabfromline(readline)
    1840            0 :              line=adjustl(readline)
    1841            0 :              call rdfromline_value('correction_strain_force',line,strg)
    1842            0 :              if (strg/="") then
    1843            0 :                strg1=trim(strg)
    1844            0 :                read(strg1,*) (work2(nu,natom),nu=1,3*6)
    1845              :              else
    1846            0 :                strg1=trim(line)
    1847            0 :                read(strg1,*) (work2(nu,natom),nu=1,3*6)
    1848              :              end if
    1849            0 :              elastic_displacement(voigt,:,:,:) = reshape(work2(:,:),(/6,3,natom/))
    1850            0 :              ABI_FREE(work2)
    1851              :            else
    1852            0 :              ABI_MALLOC(work2,(3*6,natom))
    1853            0 :              do mu=1,natom
    1854            0 :                read(funit,*)(work2(nu,mu),nu=1,3*6)
    1855              :              end do
    1856            0 :              elastic_displacement(voigt,:,:,:) = reshape(work2(:,:),(/6,3,natom/))
    1857            0 :              ABI_FREE(work2)
    1858              :            end if
    1859              :          end if
    1860              : 
    1861        89216 :          if ((line(1:26)=='<correction_force_constant')) then
    1862              :            found2=.false.
    1863              :            do while (.not.found2)
    1864            0 :              read(funit,'(a)',iostat=ios) readline
    1865            0 :              call rmtabfromline(readline)
    1866            0 :              line=adjustl(readline)
    1867            0 :              if ((line(1:5)=='<data')) then
    1868            0 :                call rdfromline_value('data',line,strg)
    1869            0 :                if (strg/="") then
    1870            0 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1871            0 :                  strg1=trim(strg)
    1872            0 :                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
    1873            0 :                  do mu=2,3*natom-1
    1874            0 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1875              :                  end do
    1876            0 :                  read(funit,'(a)',iostat=ios) readline
    1877            0 :                  call rmtabfromline(readline)
    1878            0 :                  line=adjustl(readline)
    1879            0 :                  call rdfromline_value('data',line,strg)
    1880            0 :                  if (strg/="") then
    1881            0 :                    strg1=trim(strg)
    1882            0 :                    read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
    1883              :                  else
    1884            0 :                    strg1=trim(line)
    1885            0 :                    read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
    1886              :                  end if
    1887              :                  phonon_strain(voigt)%atmfrc(:,:,:,:,irpt) = &
    1888            0 : &                           reshape(work2,(/3,natom,3,natom/))
    1889            0 :                  ABI_FREE(work2)
    1890              :                else
    1891            0 :                  ABI_MALLOC(work2,(3*natom,3*natom))
    1892            0 :                  do mu=1,3*natom
    1893            0 :                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
    1894              :                  end do
    1895              :                  phonon_strain(voigt)%atmfrc(:,:,:,:,irpt) =&
    1896            0 : &              reshape(work2,(/3,natom,3,natom/))
    1897            0 :                  ABI_FREE(work2)
    1898              :                end if
    1899            0 :                has_anharmonics = .true.
    1900              :              end if
    1901            0 :              if ((line(1:5)=='<cell')) then
    1902            0 :                call rdfromline_value('cell',line,strg)
    1903            0 :                if (strg/="") then
    1904            0 :                  strg1=trim(strg)
    1905            0 :                  read(strg1,*)(phonon_strain(voigt)%cell(mu,irpt),mu=1,3)
    1906              :                else
    1907            0 :                  read(funit,*)(phonon_strain(voigt)%cell(mu,irpt),mu=1,3)
    1908              :                end if
    1909            0 :                irpt = irpt + 1
    1910              :                found2=.true.
    1911              :                cycle
    1912              :              end if
    1913              :            end do
    1914              :          end if
    1915              : 
    1916        89216 :          if ((line(1:17)==char(60)//char(47)//'strain_coupling')) then
    1917              : !          set nrpt for the previous value of strain
    1918          132 :            phonon_strain(voigt)%nrpt = irpt - 1
    1919              : !         restart the calculation of nrpt
    1920              :          end if
    1921              :        end if
    1922              :      end if
    1923              :    end do
    1924              : 
    1925              : 
    1926              : ! Reorder the ATMFRC
    1927              : ! Case 1: only local in the xml
    1928           22 :    if (irpt1>0 .and. irpt2==0) then
    1929          763 :      ifcs%cell(:,:) = int(cell_local(:,:))
    1930       306916 :      ifcs%atmfrc(:,:,:,:,:)  = zero !local_atmfrc(:,:,:,:,:)
    1931       306916 :      ifcs%short_atmfrc(:,:,:,:,:) = local_atmfrc(:,:,:,:,:)
    1932       306916 :      ifcs%ewald_atmfrc(:,:,:,:,:) = zero
    1933              : 
    1934              : ! Case 2: only total in the xml
    1935           15 :    else if(irpt1==0 .and. irpt2>0)then
    1936            0 :      ifcs%cell(:,:) = int(cell_total(:,:))
    1937            0 :      ifcs%atmfrc(:,:,:,:,:)  = total_atmfrc(:,:,:,:,:)
    1938            0 :      ifcs%short_atmfrc(:,:,:,:,:) = zero
    1939            0 :      ifcs%ewald_atmfrc(:,:,:,:,:) = zero !total_atmfrc(:,:,:,:,:)
    1940              : 
    1941              : ! Case 3: local + total in the xml
    1942           15 :    else if (irpt1>0 .and. irpt2>0)then
    1943           15 :      if(irpt1 <= irpt2)then
    1944           15 :        irpt3 = 0
    1945          546 :        do ii=1,irpt2
    1946         2124 :          ifcs%cell(:,ii) = int(cell_total(:,ii))
    1947       159699 :          ifcs%atmfrc(:,:,:,:,ii)  = total_atmfrc(:,:,:,:,ii)
    1948        36753 :          do jj=1,irpt1
    1949        46965 :            if (all(abs(int(cell_local(:,jj))-ifcs%cell(:,ii))<tol16)) then
    1950       144651 :              ifcs%short_atmfrc(:,:,:,:,ii) = local_atmfrc(:,:,:,:,jj)
    1951          459 :              irpt3 = irpt3 + 1
    1952              :            end if
    1953              :          end do
    1954              :        end do
    1955           15 :        if(irpt3 /= irpt1)then
    1956            0 :          write(message, '(4a)' )ch10,&
    1957            0 : &         ' There is several similar short IFC in ',trim(filename),ch10
    1958            0 :          ABI_BUG(message)
    1959              :        end if
    1960              :      else
    1961            0 :        write(message, '(2a,I5,3a,I5,5a)' )ch10,&
    1962            0 : &     ' The number of total IFC  (',irpt2,') is inferior to  ',ch10,&
    1963            0 : &     ' the number of short range IFC (',irpt1,') in ',trim(filename),ch10,&
    1964            0 : &     ' This is not possible',ch10
    1965              : 
    1966            0 :        ABI_BUG(message)
    1967              :      end if
    1968              :    end if
    1969              : 
    1970              : !  Do some checks
    1971          154 :    if (any(typat==0)) then
    1972              :      write(message, '(a,a,a)' )&
    1973            0 : &      ' Unable to read the type of atoms ',trim(filename),ch10
    1974            0 :      ABI_ERROR(message)
    1975              :    end if
    1976              : 
    1977           80 :    if (any(abs(znucl)<tol16)) then
    1978              :      write(message, '(a,a,a)' )&
    1979            0 : &      ' Unable to read the atomic number ',trim(filename),ch10
    1980            0 :      ABI_ERROR(message)
    1981              :    end if
    1982              : 
    1983           80 :    if (any(abs(all_amu)<tol16)) then
    1984              :      write(message, '(a,a,a)' )&
    1985            0 : &     ' Unable to read the atomic mass ',trim(filename),ch10
    1986            0 :      ABI_ERROR(message)
    1987              :    end if
    1988              : 
    1989           22 :    close(unit=funit)
    1990              : 
    1991              : #endif
    1992              : 
    1993              :  end if !End if master
    1994              : 
    1995              : !MPI BROADCAST
    1996           38 :  call xmpi_bcast(energy,master, comm, ierr)
    1997           38 :  call xmpi_bcast(all_amu,master, comm, ierr)
    1998           38 :  call xmpi_bcast(dynmat,master, comm, ierr)
    1999           38 :  call xmpi_bcast(elastic_constants,master, comm, ierr)
    2000           38 :  call xmpi_bcast(epsilon_inf,master, comm, ierr)
    2001           38 :  call xmpi_bcast(ifcs%nrpt,master, comm, ierr)
    2002           38 :  call xmpi_bcast(ifcs%atmfrc,master, comm, ierr)
    2003           38 :  call xmpi_bcast(ifcs%cell,master, comm, ierr)
    2004           38 :  call xmpi_bcast(ifcs%ewald_atmfrc,master, comm, ierr)
    2005           38 :  call xmpi_bcast(ifcs%short_atmfrc,master, comm, ierr)
    2006           38 :  call xmpi_bcast(strain_coupling,master, comm, ierr)
    2007           38 :  call xmpi_bcast(phfrq,master, comm, ierr)
    2008           38 :  call xmpi_bcast(qph1l,master, comm, ierr)
    2009           38 :  call xmpi_bcast(typat,master, comm, ierr)
    2010           38 :  call xmpi_bcast(rprimd,master, comm, ierr)
    2011           38 :  call xmpi_bcast(xcart,master, comm, ierr)
    2012           38 :  call xmpi_bcast(zeff,master, comm, ierr)
    2013           38 :  call xmpi_bcast(znucl,master, comm, ierr)
    2014          266 :  do ii = 1,6
    2015          228 :    call xmpi_bcast(phonon_strain(ii)%nrpt   ,master, comm, ierr)
    2016          228 :    call xmpi_bcast(phonon_strain(ii)%atmfrc ,master, comm, ierr)
    2017          266 :    call xmpi_bcast(phonon_strain(ii)%cell   ,master, comm, ierr)
    2018              :  end do
    2019           38 :  call xmpi_bcast(elastic3rd   ,master, comm, ierr)
    2020           38 :  call xmpi_bcast(elastic_displacement ,master, comm, ierr)
    2021           38 :  call xmpi_bcast(has_anharmonics ,master, comm, ierr)
    2022              : 
    2023              : !Fill somes others variables
    2024           38 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
    2025           38 :  call xcart2xred(natom,rprimd,xcart,xred)
    2026              : 
    2027              : !Re-generate symmetry operations from the lattice and atomic coordinates
    2028           38 :  tolsym=tol8
    2029           38 :  msym = 384
    2030          114 :  ABI_MALLOC(spinat,(3,natom))
    2031           38 :  ABI_MALLOC(ptsymrel,(3,3,msym))
    2032           38 :  ABI_MALLOC(symafm,(msym))
    2033           38 :  ABI_MALLOC(symrel,(3,3,msym))
    2034           38 :  ABI_MALLOC(tnons,(3,msym))
    2035           38 :  use_inversion=1
    2036          854 :  spinat = 0;
    2037       189734 :  symrel = 0;
    2038        14630 :  symafm = 0;
    2039        58406 :  tnons = 0 ;
    2040           38 :  space_group = 0;
    2041           38 :  call symlatt(bravais,std_out,msym,nptsym,ptsymrel,rprimd,tolsym)
    2042           38 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
    2043              :  call symfind(gprimd,msym,natom,nptsym,0,nsym,&
    2044           38 : &  0,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred)
    2045              : 
    2046              : !Initialisation of crystal
    2047           38 :  npsp = ntypat; timrev = 1
    2048          114 :  ABI_MALLOC(title, (ntypat))
    2049          136 :  do ii=1,ntypat
    2050          136 :    write(title(ii),'(a,i0)')"No title for typat ",ii
    2051              :  end do
    2052              : 
    2053              : !Warning znucl is dimension with ntypat = nspsp hence alchemy is not supported here
    2054              :  call crystal%init(all_amu,space_group,natom,npsp,ntypat,nsym,rprimd,typat,xred,&
    2055              : &  zion,znucl,timrev,.FALSE.,.FALSE.,title,&
    2056           38 : &  symrel=symrel(:,:,1:nsym),tnons=tnons(:,1:nsym),symafm=symafm(1:nsym))
    2057              : 
    2058              : !amu is not fill in crystal_init...
    2059          136 :  Crystal%amu(:) = all_amu(:)
    2060              : 
    2061           38 :  ABI_FREE(symrel)
    2062           38 :  ABI_FREE(symafm)
    2063           38 :  ABI_FREE(tnons)
    2064           38 :  ABI_FREE(spinat)
    2065           38 :  ABI_FREE(ptsymrel)
    2066              : 
    2067              : !if strcpling is set to 0 by the user, need to set the flag to false for
    2068              : !the initialisation of the effective potential
    2069           38 :  if (present(strcpling))then
    2070           38 :    if(strcpling == 0 )then
    2071            0 :      has_anharmonics = .FALSE.
    2072              :    end if
    2073              :  end if
    2074              : 
    2075              : !Initialisation of eff_pot
    2076              :  call effective_potential_init(crystal,eff_pot,energy,ifcs,ncoeff,nph1l,comm,&
    2077              : &                              dynmat=dynmat,elastic_constants=elastic_constants,&
    2078              : &                              elastic3rd=elastic3rd,elastic_displacement=elastic_displacement,&
    2079              : &                              epsilon_inf=epsilon_inf,strain_coupling=strain_coupling,&
    2080              : &                              phonon_strain=phonon_strain,phfrq=phfrq,qpoints=qph1l,&
    2081           38 : &                              has_anharmonicsTerms=has_anharmonics,zeff=zeff)
    2082              : 
    2083              : !DEALLOCATION OF ARRAYS
    2084           38 :  ABI_FREE(all_amu)
    2085           38 :  ABI_FREE(cell_local)
    2086           38 :  ABI_FREE(cell_total)
    2087           38 :  ABI_FREE(total_atmfrc)
    2088           38 :  ABI_FREE(local_atmfrc)
    2089           38 :  ABI_FREE(ifcs%atmfrc)
    2090           38 :  ABI_FREE(ifcs%cell)
    2091           38 :  ABI_FREE(ifcs%short_atmfrc)
    2092           38 :  ABI_FREE(ifcs%ewald_atmfrc)
    2093           38 :  ABI_FREE(dynmat)
    2094           38 :  ABI_FREE(strain_coupling)
    2095           38 :  ABI_FREE(phfrq)
    2096           38 :  ABI_FREE(qph1l)
    2097           38 :  ABI_FREE(title)
    2098           38 :  ABI_FREE(typat)
    2099           38 :  ABI_FREE(xcart)
    2100           38 :  ABI_FREE(xred)
    2101           38 :  ABI_FREE(zeff)
    2102           38 :  ABI_FREE(zion)
    2103           38 :  ABI_FREE(znucl)
    2104          266 :  do ii = 1,6
    2105          228 :    phonon_strain(ii)%nrpt   = nrpt
    2106          228 :    phonon_strain(ii)%atmfrc = zero
    2107          228 :    phonon_strain(ii)%cell   = 0
    2108          228 :    ABI_FREE(phonon_strain(ii)%atmfrc)
    2109          266 :    ABI_FREE(phonon_strain(ii)%cell)
    2110              :  end do
    2111          266 :  ABI_FREE(phonon_strain)
    2112           38 :  ABI_FREE(elastic_displacement)
    2113              : 
    2114              : !DEALLOCATION OF TYPES
    2115           38 :  call ifcs%free()
    2116           38 :  call crystal%free()
    2117              : 
    2118          114 : end subroutine system_xml2effpot
    2119              : !!***
    2120              : 
    2121              : !!****f* m_effective_potential_file/system_ddb2effpot
    2122              : !!
    2123              : !! NAME
    2124              : !! system_ddb2effpot
    2125              : !!
    2126              : !! FUNCTION
    2127              : !!  Transfert ddb into effective potential structure.
    2128              : !!  Also calculate the IFC
    2129              : !!
    2130              : !! INPUTS
    2131              : !! crytal<type(crystal_t)> = datatype with all the information for the crystal
    2132              : !! ddb<type(ddb_type)> = datatype with the ddb
    2133              : !! inp<type(multibinit_dtset_type)> = datatype with the input variables of multibinit
    2134              : !! comm = MPI communicator
    2135              : !!
    2136              : !! OUTPUT
    2137              : !! effective_potantial<type(effective_potential_type)> = effective_potential datatype to be initialized
    2138              : !!
    2139              : !! SOURCE
    2140              : 
    2141           29 : subroutine system_ddb2effpot(crystal,ddb, effective_potential,inp,comm)
    2142              : 
    2143           38 :  use m_dynmat
    2144              : 
    2145              :  use m_copy,            only : alloc_copy
    2146              :  use m_crystal,         only : crystal_t
    2147              :  use m_multibinit_dataset, only : multibinit_dtset_type
    2148              : 
    2149              : !Arguments ------------------------------------
    2150              : !scalars
    2151              :  integer,intent(in) :: comm
    2152              : !arrays
    2153              :  type(ddb_type),intent(inout) :: ddb
    2154              :  type(effective_potential_type), intent(inout) :: effective_potential
    2155              :  type(crystal_t),intent(in) :: crystal
    2156              :  type(multibinit_dtset_type),intent(in) :: inp
    2157              : 
    2158              : !Local variables-------------------------------
    2159              : !scalar
    2160              :  real(dp):: wcount1,wcount2
    2161              :  integer :: chneut,i1,i2,i3,ia,ib,iblok,idir1,idir2,ierr,ii,ipert1,iphl1
    2162              :  integer :: ipert2,irpt,irpt2,ivarA,ivarB,max1,max2,max3,min1,min2,min3
    2163              :  integer :: msize,mpert,natom,nblok,nrpt_new,nrpt_new2,rftyp,selectz
    2164              :  integer :: my_rank,nproc,prt_internalstr
    2165              :  logical :: iam_master
    2166              :  integer,parameter :: master=0
    2167              :  integer :: nptsym,nsym
    2168              :  integer :: msym = 384,  use_inversion = 1, space_group
    2169              :  real(dp):: max_phfq,eta, tolsym = tol8
    2170              : !arrays
    2171              :  integer :: bravais(11),cell_number(3),cell2(3)
    2172              :  integer :: shift(3),rfelfd(4),rfphon(4),rfstrs(4)
    2173           29 :  integer,allocatable :: cell_red(:,:)
    2174              :  real(dp):: dielt(3,3),elast_clamped(6,6),fact
    2175              :  real(dp):: red(3,3),qphnrm(3),qphon(3,3)
    2176           29 :  real(dp),allocatable :: blkval(:,:,:,:,:,:),d2asr(:,:,:,:,:)
    2177           29 :  real(dp),allocatable :: instrain(:,:),zeff(:,:,:),qdrp_cart(:,:,:,:)
    2178           58 :  real(dp),pointer :: atmfrc_red(:,:,:,:,:),wghatm_red(:,:,:)
    2179              :  character(len=500) :: message
    2180           29 :  type(asrq0_t) :: asrq0
    2181          174 :  type(ifc_type) :: ifc
    2182           29 :  real(dp),allocatable :: d2cart(:,:,:,:,:),displ(:)
    2183           58 :  real(dp),allocatable :: eigval(:,:),eigvec(:,:,:,:,:),phfrq(:)
    2184           29 :  real(dp),allocatable :: spinat(:,:),tnons(:,:)
    2185           29 :  integer,allocatable  :: symrel(:,:,:),symafm(:),ptsymrel(:,:,:)
    2186              : ! *************************************************************************
    2187              : 
    2188              : !0 MPI variables
    2189           29 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2190              :  iam_master=.FALSE.
    2191           29 :  iam_master = (my_rank == master)
    2192              : 
    2193              : !Free the eff_pot before filling
    2194           29 :  call effective_potential_free(effective_potential)
    2195              : 
    2196              : !Initialisation of usefull values
    2197           29 :   natom = ddb%natom
    2198           29 :   nblok = ddb%nblok
    2199           29 :   mpert= ddb%mpert
    2200           29 :   msize=3*mpert*3*mpert;
    2201              : 
    2202              : !Tranfert the ddb into usable array (ipert and idir format like in abinit)
    2203          174 :   ABI_MALLOC(blkval,(2,3,mpert,3,mpert,nblok))
    2204              : 
    2205      4992469 :   blkval = 0
    2206          116 :   if(size(ddb%val) /= 2*3*mpert*3*mpert*nblok ) then
    2207            0 :     ABI_BUG("Size of ddb%val is not consistent.")
    2208              :   endif
    2209          203 :   blkval = reshape(ddb%val,(/2,3,mpert,3,mpert,nblok/))
    2210              : 
    2211              : 
    2212              : !**********************************************************************
    2213              : ! Transfert crystal values
    2214              : !**********************************************************************
    2215              : ! Re-generate symmetry operations from the lattice and atomic coordinates
    2216           87 :   ABI_MALLOC(spinat,(3,natom))
    2217           87 :   ABI_MALLOC(ptsymrel,(3,3,msym))
    2218           87 :   ABI_MALLOC(symafm,(msym))
    2219           58 :   ABI_MALLOC(symrel,(3,3,msym))
    2220           87 :   ABI_MALLOC(tnons,(3,msym))
    2221       201085 :   spinat = zero;  symrel = 0;  symafm = 0;  tnons = zero ; space_group = 0;
    2222           29 :   call symlatt(bravais,std_out,msym,nptsym,ptsymrel,crystal%rprimd,tolsym)
    2223              :   call symfind(crystal%gprimd,msym,crystal%natom,nptsym,0,nsym,&
    2224              : &              0,ptsymrel,spinat,symafm,symrel,tnons,tolsym,&
    2225           29 : &              crystal%typat,use_inversion,crystal%xred)
    2226           29 :   if(crystal%nsym/=nsym)then
    2227            0 :     write(message,'(4a,I0,3a,I0,3a)') ch10,&
    2228            0 : &          ' --- !WARNING:',ch10,&
    2229            0 : &          '     There is ',nsym,' found for the crystal',ch10,&
    2230            0 : &          '     but ',crystal%nsym,' found in the DDB',ch10,&
    2231            0 : &          ' ---'
    2232            0 :       call wrtout(std_out,message,'COLL')
    2233              :   end if
    2234              :   call effective_potential%crystal%init(ddb%amu,&
    2235              : &                   space_group,crystal%natom,crystal%npsp,&
    2236              : &                   crystal%ntypat,nsym,crystal%rprimd,&
    2237              : &                   crystal%typat,crystal%xred,crystal%zion,&
    2238              : &                   crystal%znucl,crystal%timrev,crystal%use_antiferro,&
    2239              : &                   .FALSE.,crystal%title,&
    2240              : &                   symrel=symrel,tnons=tnons,&
    2241           29 : &                   symafm=symafm)
    2242              : 
    2243           29 :   ABI_FREE(spinat)
    2244           29 :   ABI_FREE(ptsymrel)
    2245           29 :   ABI_FREE(symafm)
    2246           29 :   ABI_FREE(symrel)
    2247           29 :   ABI_FREE(tnons)
    2248              : 
    2249              : !**********************************************************************
    2250              : ! Transfert energy from input file
    2251              : !**********************************************************************
    2252         2378 :   write(message, '(2a,(80a),6a)') ch10,('=',ii=1,80),ch10,ch10,&
    2253         2407 : &     ' Extraction of the energy of the structure (unit: Hartree)',ch10
    2254           29 :   call wrtout(std_out,message,'COLL')
    2255           29 :   call wrtout(ab_out,message,'COLL')
    2256           29 :   if (ddb%get_etotal(effective_potential%energy) == 0) then
    2257           17 :     if(abs(inp%energy_reference) < tol16)then
    2258              :       write(message,'(5a)')&
    2259            0 : &      ' Warning : Energy of the reference structure is not specify in',&
    2260            0 : &      ' the input file.',ch10,' Energy will set to zero',ch10
    2261            0 :       call wrtout(std_out,message,'COLL')
    2262            0 :       effective_potential%energy = zero
    2263              :     else
    2264           17 :       effective_potential%energy = inp%energy_reference
    2265              :     end if
    2266              :   else
    2267           12 :     if(abs(inp%energy_reference) > tol16)then
    2268              :       write(message,'(6a)')&
    2269            1 : &      ' Warning : Energy of the reference structure is specify in',&
    2270            1 : &      ' the input file.',ch10,' and in the DDB.',&
    2271            2 : &      ' The value of the energy is set with the value from the input file',ch10
    2272            1 :       call wrtout(std_out,message,'COLL')
    2273            1 :       effective_potential%energy = inp%energy_reference
    2274              :     end if
    2275              :   end if
    2276           29 :   write(message,'(a,es25.12)') ' Energy  = ',&
    2277           58 : &                    effective_potential%energy
    2278           29 :   call wrtout(std_out,message,'COLL')
    2279           29 :   call wrtout(ab_out,message,'COLL')
    2280              : 
    2281              : !**********************************************************************
    2282              : ! Dielectric Tensor and Effective Charges
    2283              : !**********************************************************************
    2284           87 :   ABI_MALLOC(zeff,(3,3,natom))
    2285           87 :   ABI_MALLOC(qdrp_cart,(3,3,3,natom))
    2286           58 :   ABI_MALLOC(effective_potential%harmonics_terms%zeff,(3,3,natom))
    2287              : 
    2288           29 :   rftyp   = 1 ! Blocks obtained by a non-stationary formulation.
    2289           29 :   chneut  = 1 ! The ASR for effective charges is imposed
    2290           29 :   selectz = 0 ! No selection of some parts of the effective charge tensor
    2291           29 :   iblok = ddb%get_dielt_zeff(crystal,rftyp,chneut,selectz,dielt,zeff)
    2292         6109 :   qdrp_cart = zero
    2293          377 :   if (iblok /=0 .and. maxval(abs(dielt)) < 10000) then
    2294          247 :     effective_potential%harmonics_terms%epsilon_inf = dielt
    2295         1364 :     effective_potential%harmonics_terms%zeff = zeff
    2296              :   else
    2297           10 :     effective_potential%harmonics_terms%epsilon_inf(1,1) = one
    2298           10 :     effective_potential%harmonics_terms%epsilon_inf(2,2) = one
    2299           10 :     effective_potential%harmonics_terms%epsilon_inf(3,3) = one
    2300          660 :     effective_potential%harmonics_terms%zeff = zero
    2301              :   end if
    2302              : 
    2303              : !**********************************************************************
    2304              : ! Look after the blok no. that contains the stress tensor
    2305              : !**********************************************************************
    2306         2378 :   write(message, '(a,a,(80a),a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
    2307         2407 : &   ' Extraction of the stress tensor (unit: GPa) and forces (unit: Ha/bohr)'
    2308           29 :   call wrtout(std_out,message,'COLL')
    2309           29 :   call wrtout(ab_out,message,'COLL')
    2310              : 
    2311           58 :   ABI_MALLOC(effective_potential%fcart,(3,natom))
    2312          637 :   effective_potential%fcart = zero
    2313          203 :   effective_potential%strten = zero
    2314              : 
    2315          116 :   qphon(:,1)=zero
    2316           29 :   qphnrm(1)=zero
    2317           87 :   rfphon(1:2)=0
    2318           87 :   rfelfd(1:2)=0
    2319           87 :   rfstrs(1:2)=0
    2320           29 :   rftyp=4
    2321              : 
    2322           29 :   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
    2323              : 
    2324           29 :   if (iblok /=0) then
    2325           84 :    if(any(abs(inp%strten_reference)>tol16))then
    2326            0 :      write(message,'(10a)') ch10,&
    2327            0 : &          ' --- !WARNING:',ch10,&
    2328            0 : &          '     The stress tensor of the reference structure is specify in the',ch10,&
    2329            0 : &          '     input file and in the DDB. The value of the stress tensor is set',ch10,&
    2330            0 : &          '     with the value from the input file',ch10,&
    2331            0 : &          ' ---'
    2332            0 :      call wrtout(std_out,message,'COLL')
    2333            0 :      call wrtout(ab_out,message,'COLL')
    2334            0 :      effective_potential%strten = inp%strten_reference
    2335              :    else
    2336              : !    firts give the corect stress values store in hartree
    2337              : !    diagonal parts
    2338           12 :      effective_potential%strten(1)=blkval(1,1,natom+3,1,1,iblok) *  crystal%ucvol
    2339           12 :      effective_potential%strten(2)=blkval(1,2,natom+3,1,1,iblok) *  crystal%ucvol
    2340           12 :      effective_potential%strten(3)=blkval(1,3,natom+3,1,1,iblok) *  crystal%ucvol
    2341              : !    the shear parts
    2342           12 :      effective_potential%strten(4)=blkval(1,1,natom+4,1,1,iblok) *  crystal%ucvol
    2343           12 :      effective_potential%strten(5)=blkval(1,2,natom+4,1,1,iblok) *  crystal%ucvol
    2344           12 :      effective_potential%strten(6)=blkval(1,3,natom+4,1,1,iblok) *  crystal%ucvol
    2345              :    end if
    2346              : !  Get forces
    2347          308 :    effective_potential%fcart(:,1:natom) = blkval(1,:,1:natom,1,1,iblok)
    2348              :  else
    2349          119 :    if(all(abs(inp%strten_reference(:))<tol16))then
    2350           17 :      write(message,'(8a)') ch10,&
    2351           17 : &          ' --- !WARNING:',ch10,&
    2352           17 : &          '     The stress tensor of the reference structure is not specify',ch10,&
    2353           17 : &          '     The stress tensor will be set to zero',ch10,&
    2354           34 : &          ' ---'
    2355           17 :      call wrtout(std_out,message,'COLL')
    2356           17 :      call wrtout(ab_out,message,'COLL')
    2357          119 :      effective_potential%strten = zero
    2358              :    else
    2359            0 :      effective_potential%strten = inp%strten_reference
    2360              :    end if
    2361              :  end if
    2362              : 
    2363          131 :  if(any(abs(effective_potential%strten(:)) >tol16))then
    2364           12 :    write(message, '(3a)' )ch10,&
    2365           24 : &   ' Cartesian components of forces (hartree/bohr)',ch10
    2366           12 :    call wrtout(ab_out,message,'COLL')
    2367           12 :    call wrtout(std_out,  message,'COLL')
    2368           86 :    do ii = 1, natom
    2369              :      write(message, '(I4,a,3(e16.8))' ) &
    2370           74 : &     ii,'   ',effective_potential%fcart(:,ii)
    2371              : 
    2372           74 :      call wrtout(ab_out,message,'COLL')
    2373           86 :      call wrtout(std_out,  message,'COLL')
    2374              :    end do
    2375              : 
    2376           12 :    write(message, '(a,a)' )ch10,&
    2377           24 : &   ' Cartesian components of stress tensor (hartree/bohr^3)'
    2378           12 :    call wrtout(ab_out,message,'COLL')
    2379           12 :    call wrtout(std_out,  message,'COLL')
    2380              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
    2381           12 : &   '  sigma(1 1)=',effective_potential%strten(1) / crystal%ucvol,&
    2382           24 : &   '  sigma(3 2)=',effective_potential%strten(4) / crystal%ucvol
    2383           12 :    call wrtout(ab_out,message,'COLL')
    2384           12 :    call wrtout(std_out,  message,'COLL')
    2385              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
    2386           12 : &   '  sigma(2 2)=',effective_potential%strten(2) / crystal%ucvol,&
    2387           24 : &   '  sigma(3 1)=',effective_potential%strten(5) / crystal%ucvol
    2388           12 :    call wrtout(ab_out,message,'COLL')
    2389           12 :    call wrtout(std_out,  message,'COLL')
    2390              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
    2391           12 : &   '  sigma(3 3)=',effective_potential%strten(3) / crystal%ucvol,&
    2392           24 : &   '  sigma(2 1)=',effective_potential%strten(6) / crystal%ucvol
    2393           12 :    call wrtout(ab_out,message,'COLL')
    2394           12 :    call wrtout(std_out,  message,'COLL')
    2395           12 :    write(message, '(a)' ) ' '
    2396           12 :    call wrtout(ab_out,message,'COLL')
    2397           12 :    call wrtout(std_out,  message,'COLL')
    2398              :  end if
    2399              : 
    2400              : !**********************************************************************
    2401              : ! Elastic tensors at Gamma Point
    2402              : !**********************************************************************
    2403         2378 :   write(message, '(a,a,(80a),a,a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
    2404         2407 : &   ' Extraction of the clamped elastic tensor (unit:10^2GPa)',ch10
    2405           29 :   call wrtout(std_out,message,'COLL')
    2406           29 :   call wrtout(ab_out,message,'COLL')
    2407              : 
    2408              : ! look after the blok no.iblok that contains the elastic tensor
    2409          116 :   qphon(:,1)=zero
    2410           29 :   qphnrm(1)=zero
    2411           87 :   rfphon(1:2)=0
    2412           87 :   rfelfd(1:2)=0
    2413           87 :   rfstrs(1:2)=3 ! Need uniaxial  both stresses and  shear stresses
    2414           29 :   rftyp=1 ! Blocks obtained by a non-stationary formulation.
    2415              : ! for both diagonal and shear parts
    2416           29 :   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
    2417              : 
    2418           29 :   if (iblok /=0) then
    2419              : !   extraction of the elastic constants from the blkvals (GPa)
    2420          203 :     do ivarA=1,6
    2421         1247 :       do ivarB=1,6
    2422              : !       because the elastic constant is 6*6,
    2423              : !       so we should judge if the idir is larger than 3
    2424              : !       or not
    2425         1044 :         if(ivarA>3) then
    2426          522 :           idir1=ivarA-3
    2427          522 :           ipert1=natom+4  !for the shear modulus
    2428              :         else if(ivarA<=3) then
    2429          522 :           idir1=ivarA
    2430          522 :           ipert1=natom+3  !for the diagonal part
    2431              :         end if
    2432         1044 :         if(ivarB>3) then
    2433          522 :           idir2=ivarB-3
    2434          522 :           ipert2=natom+4  !for the shear modulus
    2435              :         else if(ivarB<=3) then
    2436          522 :           idir2=ivarB
    2437          522 :           ipert2=natom+3  !for the diagonal part
    2438              :         end if
    2439         1218 :         elast_clamped(ivarA,ivarB) = blkval(1,idir1,ipert1,idir2,ipert2,iblok)
    2440              :       end do
    2441              :     end do
    2442           29 :     fact=HaBohr3_GPa / crystal%ucvol
    2443          203 :     do ivarA=1,6
    2444          174 :       write(message,'(6f12.7)')elast_clamped(ivarA,1)*fact/100.00_dp,&
    2445          174 : &                              elast_clamped(ivarA,2)*fact/100.00_dp,&
    2446          174 : &                              elast_clamped(ivarA,3)*fact/100.00_dp,&
    2447          174 : &                              elast_clamped(ivarA,4)*fact/100.00_dp,&
    2448          174 : &                              elast_clamped(ivarA,5)*fact/100.00_dp,&
    2449          348 : &                              elast_clamped(ivarA,6)*fact/100.00_dp
    2450          174 :     call wrtout(std_out,message,'COLL')
    2451          203 :     call wrtout(ab_out,message,'COLL')
    2452              :     end do
    2453              : 
    2454              : !   Set the clamped tensor into the effective potentiel
    2455         1247 :     effective_potential%harmonics_terms%elastic_constants = elast_clamped
    2456              : 
    2457              :   else
    2458              : 
    2459            0 :     write(message,'(3a)')ch10,&
    2460            0 : &    ' Warning : Elastic Tensor is set to zero (not available in the DDB)'
    2461            0 :     call wrtout(std_out,message,'COLL')
    2462            0 :     call wrtout(ab_out,message,'COLL')
    2463              : 
    2464              : !   Set the clamped tensor to zero into the effective potentiel (not available in the DDB)
    2465            0 :     effective_potential%harmonics_terms%elastic_constants = zero
    2466              :   end if
    2467              : 
    2468              : !**********************************************************************
    2469              : !   Acoustic Sum Rule
    2470              : !***************************************************************************
    2471              : ! ASR-correction (d2asr) has to be determined here from the Dynamical matrix at Gamma.
    2472          145 :   ABI_MALLOC(d2asr,(2,3,natom,3,natom))
    2473              : 
    2474         2378 :   write(message, '(a,a,(80a),a,a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
    2475         2407 : &   ' Calculation of acoustic sum rule',ch10
    2476           29 :   call wrtout(std_out,message,'COLL')
    2477           29 :   call wrtout(ab_out,message,'COLL')
    2478              : 
    2479              : ! Find the Gamma block in the DDB (no need for E-field entries)
    2480          116 :   qphon(:,1)=zero
    2481           29 :   qphnrm(1)=zero
    2482           87 :   rfphon(1:2)=1
    2483           29 :   rfelfd(:)=0
    2484           29 :   rfstrs(:)=0
    2485           29 :   rftyp=inp%rfmeth
    2486              : 
    2487           29 :   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
    2488              : 
    2489        31477 :   d2asr = zero
    2490           29 :   if (iblok /=0) then
    2491           29 :     call asria_calc(inp%asr,d2asr,ddb%val(:,:,iblok),ddb%mpert,ddb%natom)
    2492              :   end if
    2493              : 
    2494              :   ! Acoustic sum rule imposition (not yet applied)
    2495           29 :   call asrq0%init(ddb, inp%asr, inp%rfmeth, crystal, inp%sys_dim)
    2496              : 
    2497              : !**********************************************************************
    2498              : ! Interatomic Forces Calculation
    2499              : !**********************************************************************
    2500              : ! ifc to be calculated for interpolation
    2501         2378 :   write(message, '(a,a,(80a),a,a,a,a)' ) ch10,('=',ii=1,80),ch10,ch10,&
    2502         2407 : &   ' Calculation of the interatomic forces from DDB',ch10
    2503           29 :   call wrtout(std_out,message,'COLL')
    2504           29 :   call wrtout(ab_out,message,'COLL')
    2505              : 
    2506              :   call ifc%init(crystal,ddb,inp%brav,inp%asr,inp%symdynmat,inp%dipdip,inp%rfmeth,&
    2507              : &   inp%ngqpt(1:3),inp%nqshft,inp%q1shft,dielt,effective_potential%harmonics_terms%zeff,qdrp_cart,&
    2508           29 : &   inp%nsphere,inp%rifcsph,inp%prtsrlr,inp%enunit,inp%sys_dim,comm)
    2509              : !***************************************************************************
    2510              : ! Interpolation of the dynamical matrix for each qpoint from ifc
    2511              : !***************************************************************************
    2512              : 
    2513          116 :   ABI_MALLOC(d2cart,(2,3,mpert,3,mpert))
    2514           87 :   ABI_MALLOC(displ,(2*3*natom*3*natom))
    2515           58 :   ABI_MALLOC(eigval,(3,natom))
    2516           87 :   ABI_MALLOC(eigvec,(2,3,natom,3,natom))
    2517           87 :   ABI_MALLOC(phfrq,(3*natom))
    2518              : 
    2519          145 :   ABI_MALLOC(effective_potential%harmonics_terms%dynmat,(2,3,natom,3,natom,inp%nph1l))
    2520          116 :   ABI_MALLOC(effective_potential%harmonics_terms%phfrq,(3*natom,inp%nph1l))
    2521           87 :   ABI_MALLOC(effective_potential%harmonics_terms%qpoints,(3,inp%nph1l))
    2522              : 
    2523         2378 :   write(message,'(a,(80a),3a)')ch10,('=',ii=1,80),ch10,ch10,&
    2524         2407 : &     ' Calculation of dynamical matrix for each ph1l points '
    2525           29 :   call wrtout(ab_out,message,'COLL')
    2526           29 :   call wrtout(std_out,message,'COLL')
    2527              : 
    2528              : !Transfer value in effective_potential structure
    2529           29 :   effective_potential%harmonics_terms%nqpt         = inp%nph1l
    2530          369 :   effective_potential%harmonics_terms%qpoints(:,:) = inp%qph1l(:,:)
    2531              : 
    2532              : ! Store the highest frequency
    2533           29 :   max_phfq = zero
    2534              : 
    2535          114 :   do iphl1=1,inp%nph1l
    2536              : 
    2537              :    ! Initialisation of the phonon wavevector
    2538          340 :     qphon(:,1)=inp%qph1l(:,iphl1)
    2539           85 :     if (inp%nph1l /= 0) qphnrm(1) = inp%qnrml1(iphl1)
    2540              : 
    2541              :     ! Get d2cart using the interatomic forces and the
    2542              :     ! long-range coulomb interaction through Ewald summation
    2543              :     call gtdyn9(ddb%acell,ifc%atmfrc,ifc%dielt,ifc%dipdip,ifc%dyewq0,d2cart,crystal%gmet,&
    2544              : &     ddb%gprim,mpert,natom,ifc%nrpt,qphnrm(1),qphon(:,1),crystal%rmet,ddb%rprim,ifc%rpt,&
    2545              : &     ifc%trans,crystal%ucvol,ifc%wghatm,crystal%xred,zeff,qdrp_cart,ifc%ewald_option,eta,&
    2546           85 : &     xmpi_comm_self,ifc%sys_dim)
    2547              : 
    2548              :     ! Calculation of the eigenvectors and eigenvalues of the dynamical matrix
    2549              :     call dfpt_phfrq(ddb%amu,displ,d2cart,eigval,eigvec,crystal%indsym,&
    2550              : &     mpert,crystal%nsym,natom,crystal%nsym,crystal%ntypat,phfrq,qphnrm(1),qphon,&
    2551           85 : &     crystal%rprimd,inp%symdynmat,crystal%symrel,crystal%symafm,crystal%typat,crystal%ucvol)
    2552              : 
    2553              :     ! Write the phonon frequencies
    2554           85 :     call dfpt_prtph(displ,inp%eivec,inp%enunit,ab_out,natom,phfrq,qphnrm(1),qphon)
    2555              : 
    2556              : !   Store the highest frequency in cmm-1
    2557         1298 :     max_phfq = max(maxval(phfrq*Ha_cmm1),max_phfq)
    2558              : 
    2559        59309 :     effective_potential%harmonics_terms%dynmat(:,:,:,:,:,iphl1) = d2cart(:,:,:natom,:,:natom)
    2560         1242 :     effective_potential%harmonics_terms%phfrq(:,iphl1) = phfrq(:) * Ha_cmm1
    2561              : 
    2562              :   end do
    2563              : 
    2564           29 :   write(message, '(2a,f15.7,a)' ) ch10,&
    2565           58 : &   ' The highest frequency found is ',max_phfq,' cm-1'
    2566           29 :   call wrtout(std_out,message,'COLL')
    2567              : 
    2568           29 :   ABI_FREE(d2cart)
    2569           29 :   ABI_FREE(displ)
    2570           29 :   ABI_FREE(eigval)
    2571           29 :   ABI_FREE(eigvec)
    2572           29 :   ABI_FREE(phfrq)
    2573              : 
    2574              : !**********************************************************************
    2575              : ! Transfert inter-atomic forces constants in reduced coordinates
    2576              : !**********************************************************************
    2577              : 
    2578              : !Reorder cell from canonical coordinates to reduced coordinates (for multibinit)
    2579              : !store the number of ifc before rearrangement
    2580              : 
    2581              : ! Store the sum of the weight of IFC for the final check
    2582           29 :   wcount1 = 0
    2583         5112 :   do irpt=1,ifc%nrpt
    2584       166452 :     wcount1 = wcount1 + sum(ifc%wghatm(:,:,irpt))
    2585              :   end do
    2586              : 
    2587              : !Set the maximum and the miminum for the bound of the cell
    2588        10195 :   max1 = maxval(ifc%cell(1,:));  min1 = minval(ifc%cell(1,:))
    2589        10195 :   max2 = maxval(ifc%cell(2,:));  min2 = minval(ifc%cell(2,:))
    2590        10195 :   max3 = maxval(ifc%cell(3,:));  min3 = minval(ifc%cell(3,:))
    2591           29 :   cell_number(1) = max1 - min1 + 1
    2592           29 :   cell_number(2) = max2 - min2 + 1
    2593           29 :   cell_number(3) = max3 - min3 + 1
    2594              : 
    2595              : ! set the new number of cell, sometimes, in canonical coordinates,
    2596              : ! some cell are delete but they exist in reduced coordinates.
    2597          116 :   nrpt_new = product(cell_number(:))
    2598              : 
    2599              : ! Allocate temporary array
    2600          174 :   ABI_MALLOC(atmfrc_red,(3,natom,3,natom,nrpt_new))
    2601          145 :   ABI_MALLOC(wghatm_red,(natom,natom,nrpt_new))
    2602           87 :   ABI_MALLOC(cell_red,(3,nrpt_new))
    2603              : 
    2604       169320 :   wghatm_red(:,:,:) = zero
    2605              : 
    2606           29 :   if(iam_master)then
    2607          137 :     do ia=1,natom
    2608         1001 :       do ib=1,natom
    2609              : 
    2610              : !       Simple Lattice
    2611          864 :         if (inp%brav==1) then
    2612              : !          In this case, it is better to work in reduced coordinates
    2613              : !          As rcan is in canonical coordinates, => multiplication by gprim
    2614         3456 :            do ii=1,3
    2615              :              red(1,ii)=  ifc%rcan(1,ia)*ddb%gprim(1,ii) + &
    2616              :  &                       ifc%rcan(2,ia)*ddb%gprim(2,ii) + &
    2617         2592 :  &                       ifc%rcan(3,ia)*ddb%gprim(3,ii)
    2618              :              red(2,ii)=  ifc%rcan(1,ib)*ddb%gprim(1,ii) + &
    2619              :                          ifc%rcan(2,ib)*ddb%gprim(2,ii) + &
    2620         3456 :  &                       ifc%rcan(3,ib)*ddb%gprim(3,ii)
    2621              :            end do
    2622              :          end if
    2623              : 
    2624              : !       Get the shift of cell
    2625         3456 :         shift(:) = int(anint(red(2,:) - crystal%xred(:,ib)) - anint(red(1,:) - crystal%xred(:,ia)))
    2626              : 
    2627       133224 :         do irpt=1,ifc%nrpt
    2628              : 
    2629       528976 :           cell2(:)= int(ifc%cell(:,irpt) + shift(:))
    2630              : 
    2631              : !         Use boundary condition to get the right cell
    2632       132244 :           if (cell2(1) < min1 .and. cell2(1) < max1) then
    2633          915 :             cell2(1) = cell2(1) + cell_number(1)
    2634       131329 :           else if (cell2(1) > min1 .and. cell2(1) > max1) then
    2635          915 :             cell2(1) = cell2(1) - cell_number(1)
    2636              :           end if
    2637              : 
    2638       132244 :           if (cell2(2) < min2 .and. cell2(2) < max2) then
    2639          960 :             cell2(2) = cell2(2) + cell_number(2)
    2640       131284 :           else if (cell2(2) > min2 .and. cell2(2) > max2) then
    2641          960 :             cell2(2) = cell2(2) - cell_number(2)
    2642              :           end if
    2643              : 
    2644       132244 :           if (cell2(3) < min3 .and. cell2(3) < max3) then
    2645          948 :             cell2(3) = cell2(3) + cell_number(3)
    2646       131296 :           else if (cell2(3) > min3 .and. cell2(3) > max3) then
    2647          948 :             cell2(3) = cell2(3) - cell_number(3)
    2648              :           end if
    2649              : 
    2650              :            irpt2=1
    2651      1198440 :            do i1=min1,max1
    2652     10360972 :              do i2=min2,max2
    2653     91175516 :                do i3=min3,max3
    2654              :                  if (i1  ==  cell2(1)  .and.&
    2655     80946788 :                      i2  ==  cell2(2)  .and.&
    2656              :                      i3  ==  cell2(3)) then
    2657       132244 :                    wghatm_red(ia,ib,irpt2) =  ifc%wghatm(ia,ib,irpt)
    2658      1719172 :                    atmfrc_red(:,ia,:,ib,irpt2) = ifc%atmfrc(:,ia,:,ib,irpt)
    2659       132244 :                    cell_red(1,irpt2) = i1
    2660       132244 :                    cell_red(2,irpt2) = i2
    2661       132244 :                    cell_red(3,irpt2) = i3
    2662              :                  end if
    2663     90110184 :                  irpt2 = irpt2 + 1
    2664              :                end do
    2665              :              end do
    2666              :           end do
    2667              :         end do
    2668              :       end do
    2669              :     end do
    2670              :   end if
    2671              : 
    2672           29 :   call xmpi_bcast(atmfrc_red,master, comm, ierr)
    2673           29 :   call xmpi_bcast(wghatm_red,master, comm, ierr)
    2674           29 :   call xmpi_bcast(cell_red,master, comm, ierr)
    2675              : 
    2676              : !  Copy ifc into effective potential
    2677              : ! !!Warning eff_pot%ifcs only contains atmfrc,short_atmfrc,ewald_atmfrc,,nrpt and cell!!
    2678              : ! rcan,ifc%rpt,wghatm and other quantities
    2679              : ! are not needed for effective potential!!!
    2680           29 :   call ifc%free()
    2681           29 :   call effective_potential%harmonics_terms%ifcs%free()
    2682              : 
    2683              : ! Only conserve the necessary points in rpt
    2684           29 :   nrpt_new2 = 0
    2685         5220 :   do irpt = 1, nrpt_new
    2686       169320 :     if (abs(sum(wghatm_red(:,:,irpt))) >tol16) then
    2687         5003 :       nrpt_new2 = nrpt_new2 + 1
    2688              :     end if
    2689              :   end do
    2690              : 
    2691              : ! Set the new number of rpt
    2692           29 :   effective_potential%harmonics_terms%ifcs%nrpt = nrpt_new2
    2693              : 
    2694              : ! Allocation of the final arrays
    2695          174 :   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%atmfrc,(3,natom,3,natom,nrpt_new2))
    2696          116 :   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%short_atmfrc,(3,natom,3,natom,nrpt_new2))
    2697          116 :   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%ewald_atmfrc,(3,natom,3,natom,nrpt_new2))
    2698           87 :   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%cell,(3,nrpt_new2))
    2699          145 :   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%wghatm,(natom,natom,nrpt_new2))
    2700              : 
    2701           29 :   irpt2 = 0
    2702         5220 :   do irpt = 1,nrpt_new
    2703       169320 :     if (abs(sum(wghatm_red(:,:,irpt))) > tol16) then
    2704         5003 :       irpt2 = irpt2 + 1
    2705              : !     Apply weight on each R point
    2706        30335 :       do ia=1,effective_potential%crystal%natom
    2707       164743 :         do ib=1,effective_potential%crystal%natom
    2708      1772636 :           atmfrc_red(:,ia,:,ib,irpt) = atmfrc_red(:,ia,:,ib,irpt)*wghatm_red(ia,ib,irpt)
    2709              :         end do
    2710              :       end do
    2711        20012 :       effective_potential%harmonics_terms%ifcs%cell(:,irpt2) = cell_red(:,irpt)
    2712      1719227 :       effective_potential%harmonics_terms%ifcs%atmfrc(:,:,:,:,irpt2) = atmfrc_red(:,:,:,:,irpt)
    2713         5003 :       if (inp%dipdip == 1) then
    2714              :         effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2)=&
    2715      1520030 : &                                                                     atmfrc_red(:,:,:,:,irpt)
    2716              :       else
    2717       199197 :         effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2) = zero
    2718              :       end if
    2719      1719227 :       effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2)=atmfrc_red(:,:,:,:,irpt)
    2720      1719227 :       effective_potential%harmonics_terms%ifcs%ewald_atmfrc(:,:,:,:,irpt2) = zero
    2721       164743 :       effective_potential%harmonics_terms%ifcs%wghatm(:,:,irpt2) =  wghatm_red(:,:,irpt)
    2722              :     end if
    2723              :   end do
    2724              : 
    2725              : 
    2726           29 :   ABI_FREE(atmfrc_red)
    2727           29 :   ABI_FREE(wghatm_red)
    2728           29 :   ABI_FREE(cell_red)
    2729              : 
    2730              : ! Final check
    2731           29 :   wcount2 = 0
    2732         5032 :   do irpt = 1, effective_potential%harmonics_terms%ifcs%nrpt
    2733       164772 :     wcount2 = wcount2 + sum(effective_potential%harmonics_terms%ifcs%wghatm(:,:,irpt))
    2734              :   end do
    2735              : 
    2736           29 :   if (abs(wcount1-wcount2)/(wcount1+wcount2)>tol8) then
    2737            0 :     write(message,'(2a,es15.4,a,es15.4,a,es15.4)')'The total wghatm has changed',ch10,&
    2738            0 : &    wcount1,' before and ', wcount2, ' now, difference being ',wcount1-wcount2
    2739            0 :     ABI_BUG(message)
    2740              :   end if
    2741              : 
    2742              : 
    2743              : !**********************************************************************
    2744              : ! Internal strain tensors at Gamma point
    2745              : !**********************************************************************
    2746         2378 :   write(message, '(a,a,(80a),a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
    2747         2407 : &   ' Calculation of the internal-strain  tensor'
    2748           29 :   call wrtout(std_out,message,'COLL')
    2749           29 :   call wrtout(ab_out,message,'COLL')
    2750          116 :   ABI_MALLOC(instrain,(3*natom,6))
    2751              : ! looking after the no. of blok that contains the internal strain tensor
    2752          116 :   qphon(:,1)=zero
    2753           29 :   qphnrm(1)=zero
    2754           87 :   rfphon(1:2)=0
    2755              :   rfelfd(1:2)=0
    2756           87 :   rfstrs(1:2)=3
    2757           29 :   rftyp=1
    2758           29 :   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
    2759              : 
    2760           87 :   ABI_MALLOC(effective_potential%harmonics_terms%strain_coupling,(6,3,natom))
    2761         3373 :   effective_potential%harmonics_terms%strain_coupling = zero
    2762              : 
    2763           29 :   if (iblok /=0) then
    2764              : 
    2765              : !   then print the internal strain tensor (only the force one)
    2766           29 :     prt_internalstr=1
    2767              :     call ddb_internalstr(inp%asr,ddb%val,d2asr,iblok,instrain,&
    2768           29 : &                        ab_out,mpert,natom,nblok,prt_internalstr)
    2769              : 
    2770          203 :     do ipert1=1,6
    2771         1115 :       do ipert2=1,natom
    2772         3822 :         do idir2=1,3
    2773         2736 :           ii=3*(ipert2-1)+idir2
    2774              :             effective_potential%harmonics_terms%strain_coupling(ipert1,idir2,ipert2)=&
    2775         3648 : &                                                            (-1.0_dp)*instrain(ii,ipert1)
    2776              :         end do
    2777              :       end do
    2778              :     end do
    2779              :   else
    2780            0 :     write(message,'(3a)')ch10,&
    2781            0 : &    ' Warning : Internal strain is set to zero (not available in the DDB)'
    2782            0 :     call wrtout(std_out,message,'COLL')
    2783            0 :     call wrtout(ab_out,message,'COLL')
    2784              :   end if
    2785              : !-------------------------------------------------------------------------------------
    2786              : ! DEALLOCATION OF ARRAYS
    2787           29 :   ABI_FREE(blkval)
    2788           29 :   ABI_FREE(zeff)
    2789           29 :   ABI_FREE(qdrp_cart)
    2790           29 :   ABI_FREE(instrain)
    2791           29 :   ABI_FREE(d2asr)
    2792           29 :   call asrq0%free()
    2793              : 
    2794           29 :   write(message,'(a)')ch10
    2795           29 :   call wrtout(std_out,message,'COLL')
    2796           29 :   call wrtout(ab_out,message,'COLL')
    2797              : 
    2798           87 : end subroutine system_ddb2effpot
    2799              : !!***
    2800              : 
    2801              : !!****f* m_effective_potential_file/coeffs_xml2effpot
    2802              : !! NAME
    2803              : !! coeffs_xml2effpot
    2804              : !!
    2805              : !! FUNCTION
    2806              : !! Open xml file of effective potentiel, then reads the variables
    2807              : !! and store them in effective potentential type
    2808              : !!
    2809              : !! INPUTS
    2810              : !! filename = path of input or output file
    2811              : !! comm=MPI communicator
    2812              : !!
    2813              : !! OUTPUT
    2814              : !! eff_pot<type(effective_potential_type)> = effective_potential datatype
    2815              : !!
    2816              : !! SOURCE
    2817              : 
    2818           28 : subroutine coeffs_xml2effpot(eff_pot,filename,comm)
    2819              : 
    2820           29 :  use m_atomdata
    2821              :  use m_polynomial_coeff
    2822              :  use m_polynomial_term
    2823              :  use m_crystal, only : symbols_crystal
    2824              : #if defined HAVE_XML
    2825              :  use, intrinsic :: iso_c_binding, only : C_CHAR,C_PTR,c_f_pointer
    2826              : #endif
    2827              : 
    2828              :  !Arguments ------------------------------------
    2829              :  !scalars
    2830              :  character(len=*),intent(in) :: filename
    2831              :  integer, intent(in) :: comm
    2832              :  !arrays
    2833              :  type(effective_potential_type), intent(inout) :: eff_pot
    2834              : 
    2835              :  !Local variables-------------------------------
    2836              :  !scalar
    2837              :  integer :: ii,jj,my_rank,ndisp,ncoeff,nterm_max,nstrain,ndisp_max,nproc,nterm
    2838              : ! character(len=200),allocatable :: name(:)
    2839              :  character(len=200) :: name
    2840              : #ifdef HAVE_XML
    2841              :  integer :: icoeff,iterm
    2842              : #endif
    2843              : 
    2844              : #ifndef HAVE_XML
    2845              :  integer :: funit = 1,ios = 0
    2846              :  integer :: icoeff,idisp,istrain,iterm,mu
    2847              :  logical :: found,found2,displacement
    2848              :  character (len=XML_RECL) :: line,readline
    2849              :  character (len=XML_RECL) :: strg,strg1
    2850              : #endif
    2851              :  character(len=500) :: message
    2852              :  character(len=264) :: filename_tmp
    2853           28 :  character(len=5),allocatable :: symbols(:)
    2854              :  integer,parameter :: master=0
    2855              :  logical :: iam_master
    2856              :  logical :: debug
    2857              :  !arrays
    2858           28 :  real(dp),allocatable :: coefficient(:),weight(:,:)
    2859           28 :  integer,allocatable :: atindx(:,:,:,:), cell(:,:,:,:,:),direction(:,:,:),power_disp(:,:,:)
    2860           28 :  integer,allocatable :: strain(:,:,:),power_strain(:,:,:)
    2861           28 :  type(polynomial_coeff_type),dimension(:),allocatable :: coeffs
    2862           28 :  type(polynomial_term_type),dimension(:,:),allocatable :: terms
    2863              : ! *************************************************************************
    2864              : 
    2865           28 :  filename_tmp = trim(filename)
    2866              :  !Open the atomicdata XML file for reading
    2867           28 :  write(message,'(a,a)')'-Opening the file ',trim(filename_tmp)
    2868              : 
    2869           28 :  call wrtout(ab_out,message,'COLL')
    2870           28 :  call wrtout(std_out,message,'COLL')
    2871              : 
    2872           28 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2873           28 :  iam_master = (my_rank == master)
    2874              : 
    2875              : !Get Dimention of system and allocation/initialisation of array
    2876              :  ncoeff  = 0
    2877           28 :  nterm   = 0
    2878           28 :  ndisp   = 0
    2879           28 :  nstrain = 0
    2880           28 :  call effective_potential_file_getDimCoeff(filename,ncoeff,ndisp_max,nterm_max)
    2881              : 
    2882              : !  Do some checks
    2883           28 :  if (nterm_max<=0) then
    2884              :    write(message, '(a,a,a)' )&
    2885            0 : &     ' Unable to read the number of terms in ',trim(filename),ch10
    2886            0 :    ABI_ERROR(message)
    2887              :  end if
    2888              : 
    2889           28 :   if (ndisp_max<=0) then
    2890              :     write(message, '(a,a,a)' )&
    2891            0 : &    ' Unable to read the number of displacement in ',trim(filename),ch10
    2892            0 :     ABI_ERROR(message)
    2893              :   end if
    2894              : 
    2895              : !Allocation ov the polynomial coeff type
    2896         1886 :  ABI_MALLOC(coeffs,(ncoeff))
    2897              : 
    2898           28 :  if(iam_master)then
    2899              : 
    2900              : #if defined HAVE_XML
    2901              :    write(message,'(3a)')'-Reading the file ',trim(filename),&
    2902              : &   ' with LibXML library'
    2903              : #else
    2904           20 :    write(message,'(3a)')'-Reading the file ',trim(filename),&
    2905           40 : &   ' with Fortran'
    2906              : #endif
    2907           20 :    call wrtout(ab_out,message,'COLL')
    2908           20 :    call wrtout(std_out,message,'COLL')
    2909              : 
    2910              : 
    2911           60 :    ABI_MALLOC(symbols,(eff_pot%crystal%natom))
    2912              : !  Get the symbols arrays
    2913              :    call symbols_crystal(eff_pot%crystal%natom,eff_pot%crystal%ntypat,&
    2914           20 : &                       eff_pot%crystal%npsp,symbols,eff_pot%crystal%typat,eff_pot%crystal%znucl)
    2915              : 
    2916              : 
    2917              :  !Read with libxml librarie
    2918              : #if defined HAVE_XML
    2919              : 
    2920              :    ABI_MALLOC(terms,(ncoeff,nterm_max))
    2921              :    ABI_MALLOC(atindx,(ncoeff,nterm_max,2,ndisp_max))
    2922              :    ABI_MALLOC(coefficient,(ncoeff))
    2923              :    ABI_MALLOC(cell,(ncoeff,nterm_max,3,2,ndisp_max))
    2924              :    ABI_MALLOC(direction,(ncoeff,nterm_max,ndisp_max))
    2925              :    ABI_MALLOC(strain,(ncoeff,nterm_max,ndisp_max))
    2926              :    ABI_MALLOC(power_disp,(ncoeff,nterm_max,ndisp_max))
    2927              :    ABI_MALLOC(power_strain,(ncoeff,nterm_max,ndisp_max))
    2928              :    ABI_MALLOC(weight,(ncoeff,nterm_max))
    2929              : 
    2930              : !  Read the values of this term with libxml
    2931              :    call effpot_xml_readCoeff(char_f2c(trim(filename)),ncoeff,ndisp_max,nterm_max,&
    2932              : &                            coefficient,atindx,cell,direction,power_disp,power_strain,&
    2933              : &                            strain,weight)
    2934              : !  In the XML the atom index begin to zero
    2935              : !  Need to shift for fortran array
    2936              :    atindx(:,:,:,:) = atindx(:,:,:,:) + 1
    2937              : 
    2938              :    do icoeff=1,ncoeff
    2939              :      do iterm=1,nterm_max
    2940              : !      Initialisation of the polynomial_term structure with the values from the
    2941              :        call polynomial_term_init(atindx(icoeff,iterm,:,:),cell(icoeff,iterm,:,:,:),&
    2942              : &                                direction(icoeff,iterm,:),ndisp_max,ndisp_max,terms(icoeff,iterm),&
    2943              : &                                power_disp(icoeff,iterm,:),power_strain(icoeff,iterm,:),&
    2944              : &                                strain(icoeff,iterm,:),weight(icoeff,iterm),check=.true.)
    2945              :      end do
    2946              : !    Initialisation of the polynomial_coefficent structure with the values
    2947              :      call polynomial_coeff_init(coefficient(icoeff),nterm_max,coeffs(icoeff),&
    2948              : &                               terms(icoeff,:), check=.true., debug_str="init from xml")
    2949              : !    Set the name of the coefficient
    2950              : 
    2951              : !    Get the name of this coefficient  and set it
    2952              : !    Try to find the index of the term corresponding to the interation in the
    2953              : !    reference cell (000) in order to compute the name correctly...
    2954              : !    If this coeff is not in the ref cell, take by default the first term
    2955              :      if(coeffs(icoeff)%nterm > 0)then
    2956              :        call polynomial_coeff_getName(name,coeffs(icoeff),symbols,recompute=.true.)
    2957              :        call polynomial_coeff_setName(name,coeffs(icoeff))
    2958              :      end if
    2959              : 
    2960              : !    Free them all
    2961              :      do iterm=1,nterm_max
    2962              :        call polynomial_term_free(terms(icoeff,iterm))
    2963              :      end do
    2964              :    end do
    2965              : 
    2966              : #else
    2967         1884 :    ABI_MALLOC(terms,(1,nterm_max))
    2968           60 :    ABI_MALLOC(atindx,(1,1,2,ndisp_max))
    2969           20 :    ABI_MALLOC(coefficient,(1))
    2970           60 :    ABI_MALLOC(cell,(1,1,3,2,ndisp_max))
    2971           60 :    ABI_MALLOC(direction,(1,1,ndisp_max))
    2972           40 :    ABI_MALLOC(strain,(1,1,ndisp_max))
    2973           40 :    ABI_MALLOC(power_disp,(1,1,ndisp_max))
    2974           40 :    ABI_MALLOC(power_strain,(1,1,ndisp_max))
    2975           20 :    ABI_MALLOC(weight,(1,1))
    2976              : !  Loop over the file
    2977              : !  Read the values of all the terms with fortran
    2978           20 :    if (open_file(filename,message,unit=funit,form="formatted",&
    2979              : &              status="old",action="read") /= 0) then
    2980            0 :      ABI_ERROR(message)
    2981              :    end if
    2982              : 
    2983              : !    Start a reading loop in fortran
    2984           20 :      rewind(unit=funit)
    2985           20 :      ios  = 0
    2986           20 :      found=.false.
    2987              : 
    2988              : !    Initialisation of counter
    2989           20 :      icoeff  = 0
    2990              : 
    2991              : !    Parser
    2992         4966 :      do while (ios==0)
    2993         4946 :        read(funit,'(a)',iostat=ios) readline
    2994         4966 :        if (ios == 0) then
    2995         4926 :          call rmtabfromline(readline)
    2996         4926 :          line=adjustl(readline)
    2997         4926 :          if ((line(1:12)==char(60)//'coefficient')) then
    2998              : !          Read headers of coefficient
    2999         1770 :            call rdfromline('text',line,strg)
    3000         1770 :            if (strg/="") then
    3001         1770 :              name=trim(strg)
    3002              :            end if
    3003         1770 :            call rdfromline('value',line,strg)
    3004         1770 :            if (strg/="") then
    3005         1754 :              strg1=trim(strg)
    3006         1754 :              read(strg1,*) coefficient(1)
    3007              :            else
    3008           16 :              coefficient(1) = zero
    3009              :            end if
    3010              : !          End read headers of coefficient
    3011              : !          Reset counter
    3012         8833 :            found  = .false.
    3013       220723 :            atindx = 0;  cell   = 0 ;  direction = 0
    3014        65337 :            strain = 0; power_strain = 0;  power_disp  = 0
    3015         1770 :            iterm   = 0
    3016         1770 :            idisp   = 0
    3017         1770 :            istrain = 0
    3018         1770 :            nterm   = 0
    3019              :            do while (.not.found)
    3020        48012 :              read(funit,'(a)',iostat=ios) readline
    3021        48012 :              call rmtabfromline(readline)
    3022        48012 :              line=adjustl(readline)
    3023        48012 :              if ((line(1:13)==char(60)//'/coefficient')) then
    3024              :                found= .true.
    3025              :                cycle
    3026              :              end if
    3027        46242 :              if ((line(1:5)==char(60)//'term')) then
    3028        46242 :                nterm = nterm + 1
    3029        46242 :                ndisp = 0
    3030        46242 :                nstrain = 0
    3031        46242 :                idisp = 0
    3032        46242 :                istrain = 0
    3033        46242 :                displacement = .true.
    3034        46242 :                call rdfromline('weight',line,strg)
    3035        46242 :                if (strg/="") then
    3036        46242 :                  strg1=trim(strg)
    3037        46242 :                  read(strg1,*) weight
    3038              :                end if
    3039       214908 :                do while(displacement)
    3040       168666 :                  read(funit,'(a)',iostat=ios) readline
    3041       168666 :                  call rmtabfromline(readline)
    3042       168666 :                  line=adjustl(readline)
    3043       168666 :                  if ((line(1:6)==char(60)//'/term')) then
    3044        46242 :                    displacement = .false.
    3045              :                  end if
    3046       168666 :                  if ((line(1:7)==char(60)//'strain')) then
    3047        14682 :                    nstrain = nstrain + 1
    3048        14682 :                    istrain = istrain + 1
    3049        14682 :                    call rdfromline('power',line,strg)
    3050        14682 :                    if (strg/="") then
    3051        14682 :                      strg1=trim(strg)
    3052        14682 :                      read(strg1,*) power_strain(1,1,istrain)
    3053              :                    end if
    3054        14682 :                    call rdfromline('voigt',line,strg)
    3055        14682 :                    if (strg/="") then
    3056        14682 :                      strg1=trim(strg)
    3057        14682 :                      read(strg1,*) strain(1,1,istrain)
    3058              :                    end if
    3059              :                  end if
    3060       214908 :                  if ((line(1:18)==char(60)//'displacement_diff')) then
    3061       107742 :                    ndisp = ndisp + 1
    3062       107742 :                    idisp = idisp + 1
    3063       107742 :                    found2=.true.
    3064       107742 :                    call rdfromline('atom_a',line,strg)
    3065       107742 :                    if (strg/="") then
    3066       107742 :                      strg1=trim(strg)
    3067       107742 :                      read(strg1,*) atindx(1,1,1,idisp)
    3068              :                    end if
    3069       107742 :                    call rdfromline('atom_b',line,strg)
    3070       107742 :                    if (strg/="") then
    3071       107742 :                      strg1=trim(strg)
    3072       107742 :                      read(strg1,*) atindx(1,1,2,idisp)
    3073              :                    end if
    3074       107742 :                    call rdfromline('direction',line,strg)
    3075       107742 :                    if (strg/="") then
    3076       107742 :                      strg1=trim(strg)
    3077       107742 :                      if (trim(strg1).eq."x") direction(1,1,idisp) = 1
    3078       107742 :                      if (trim(strg1).eq."y") direction(1,1,idisp) = 2
    3079       107742 :                      if (trim(strg1).eq."z") direction(1,1,idisp) = 3
    3080              :                    end if
    3081       107742 :                    call rdfromline('power',line,strg)
    3082       107742 :                    if (strg/="") then
    3083       107742 :                      strg1=trim(strg)
    3084       107742 :                      read(strg1,*) power_disp(1,1,idisp)
    3085              :                    end if
    3086              :                    do while(found2)
    3087       323226 :                      read(funit,'(a)',iostat=ios) readline
    3088       323226 :                      call rmtabfromline(readline)
    3089       323226 :                      line=adjustl(readline)
    3090       323226 :                      if ((line(1:7)==char(60)//'cell_a')) then
    3091       107742 :                        call rdfromline_value('cell_a',line,strg)
    3092       107742 :                        if (strg/="") then
    3093       107742 :                          strg1=trim(strg)
    3094       107742 :                          read(strg1,*) (cell(1,1,mu,1,idisp),mu=1,3)
    3095              :                        else
    3096            0 :                          read(funit,'(a)',iostat=ios) readline
    3097            0 :                          call rmtabfromline(readline)
    3098            0 :                          line=adjustl(readline)
    3099            0 :                          call rdfromline_value('cell_a',line,strg)
    3100            0 :                          if (strg/="") then
    3101            0 :                            strg1=trim(strg)
    3102            0 :                            read(strg1,*)(cell(1,1,mu,1,idisp),mu=1,3)
    3103              :                          else
    3104            0 :                            strg1=trim(line)
    3105            0 :                            read(strg1,*)(cell(1,1,mu,1,idisp),mu=1,3)
    3106              :                          end if
    3107              :                        end  if
    3108              :                      end if
    3109       323226 :                      if ((line(1:7)==char(60)//'cell_b')) then
    3110       107742 :                        call rdfromline_value('cell_b',line,strg)
    3111       107742 :                        if (strg/="") then
    3112       107742 :                          strg1=trim(strg)
    3113       107742 :                          read(strg1,*) (cell(1,1,mu,2,idisp),mu=1,3)
    3114              :                        else
    3115            0 :                          read(funit,'(a)',iostat=ios) readline
    3116            0 :                          call rmtabfromline(readline)
    3117            0 :                          line=adjustl(readline)
    3118            0 :                          call rdfromline_value('cell_b',line,strg)
    3119            0 :                          if (strg/="") then
    3120            0 :                            strg1=trim(strg)
    3121            0 :                            read(strg1,*)(cell(1,1,mu,2,idisp),mu=1,3)
    3122              :                          else
    3123            0 :                            strg1=trim(line)
    3124            0 :                            read(strg1,*)(cell(1,1,mu,2,idisp),mu=1,3)
    3125              :                          end if
    3126              :                        end  if
    3127              :                      end if
    3128       323226 :                      if ((line(1:19)==char(60)//'/displacement_diff')) then
    3129              :                        found2=.false.
    3130              :                      end if
    3131              :                    end do
    3132              :                  end if
    3133              :                end do!end do while displacement
    3134              : !              In the XML the atom index begin to zero
    3135              : !              Need to shift for fortran array
    3136       599490 :                atindx(1,1,:,:) = atindx(1,1,:,:) + 1
    3137              : !              Initialisation of the polynomial_term structure with the values from the
    3138              : !              previous step
    3139        46242 :                iterm = iterm + 1
    3140              :                call polynomial_term_init(atindx(1,1,:,:),cell(1,1,:,:,:),&
    3141              : &                                        direction(1,1,:),ndisp,nstrain,terms(1,iterm),&
    3142              : &                                        power_disp(1,1,:),power_strain(1,1,:),&
    3143        46242 : &                                        strain(1,1,:),weight(1,1),check=.true.)
    3144              :              end if!end if term
    3145              :            end do!end do while found (coeff)
    3146              : 
    3147              : !          Initialisation of the polynomial_coefficent structure with the values from the
    3148              : !          previous step
    3149         1770 :            icoeff = icoeff + 1
    3150         1770 :            call polynomial_coeff_init(coefficient(1),nterm,coeffs(icoeff),terms(1,:), debug_str="init from xml fortran", check=.true.)
    3151         1770 :            call polynomial_coeff_getName(name,coeffs(icoeff),symbols,recompute=.true.)
    3152         1770 :            call polynomial_coeff_setName(name,coeffs(icoeff))
    3153              : !          Deallocation of the terms array for this coefficient
    3154        84330 :            do jj=1,nterm_max
    3155        84330 :              call polynomial_term_free(terms(1,jj))
    3156              :            end do
    3157              :          end if!end if line = coefficient
    3158              :        end if!end if ios==0
    3159              :      end do!end do while on file
    3160              : 
    3161           20 :      close(unit=funit)
    3162              : 
    3163              : #endif
    3164          932 :      ABI_FREE(terms)
    3165           20 :      ABI_FREE(atindx)
    3166           20 :      ABI_FREE(coefficient)
    3167           20 :      ABI_FREE(cell)
    3168           20 :      ABI_FREE(direction)
    3169           20 :      ABI_FREE(strain)
    3170           20 :      ABI_FREE(power_disp)
    3171           20 :      ABI_FREE(power_strain)
    3172           20 :      ABI_FREE(weight)
    3173           20 :      ABI_FREE(symbols)
    3174              :    end if !End if master
    3175              : 
    3176              : !9-MPI BROADCAST
    3177         1830 :  do ii=1,ncoeff
    3178         1830 :    call polynomial_coeff_broadcast(coeffs(ii),master, comm)
    3179              :  end do
    3180              : 
    3181              : !10-checks
    3182              : 
    3183              : !11-debug print
    3184           28 :  debug = .FALSE.
    3185              :  if(debug)then
    3186              :    do ii=1,ncoeff
    3187              :      do jj=1,coeffs(ii)%nterm
    3188              : #if defined HAVE_XML
    3189              :        write(200+my_rank,*)"ii,jj,ndisp,nterm",ii,jj,coeffs(ii)%nterm,coeffs(ii)%terms(jj)%ndisp
    3190              :        write(200+my_rank,*)"atindx",coeffs(ii)%terms(jj)%atindx
    3191              :        write(200+my_rank,*)"cell1",coeffs(ii)%terms(jj)%cell(:,1,:)
    3192              :        write(200+my_rank,*)"cell2",coeffs(ii)%terms(jj)%cell(:,2,:)
    3193              :        write(200+my_rank,*)"direction",coeffs(ii)%terms(jj)%direction
    3194              :        write(200+my_rank,*)"power_disp",coeffs(ii)%terms(jj)%power_disp
    3195              :        write(200+my_rank,*)"weight",coeffs(ii)%terms(jj)%weight
    3196              : #else
    3197              :        write(300+my_rank,*)"ii,jj,ndisp,nterm",ii,jj,coeffs(ii)%nterm,coeffs(ii)%terms(jj)%ndisp
    3198              :        write(300+my_rank,*)"atindx",coeffs(ii)%terms(jj)%atindx
    3199              :        write(300+my_rank,*)"cell1",coeffs(ii)%terms(jj)%cell(:,1,:)
    3200              :        write(300+my_rank,*)"cell2",coeffs(ii)%terms(jj)%cell(:,2,:)
    3201              :        write(300+my_rank,*)"direction",coeffs(ii)%terms(jj)%direction
    3202              :        write(300+my_rank,*)"power_disp",coeffs(ii)%terms(jj)%power_disp
    3203              :        write(300+my_rank,*)"weight",coeffs(ii)%terms(jj)%weight
    3204              : #endif
    3205              :      end do
    3206              :    end do
    3207              : #if defined HAVE_XML
    3208              :    close(200+my_rank)
    3209              : #else
    3210              :    close(300+my_rank)
    3211              : #endif
    3212              :  end if
    3213              : 
    3214              : !12-Initialisation of eff_pot
    3215           28 :  call effective_potential_setCoeffs(coeffs,eff_pot,ncoeff)
    3216              : 
    3217              : !13-Deallocation of type
    3218         1830 :  do ii=1,ncoeff
    3219         1830 :    call polynomial_coeff_free(coeffs(ii))
    3220              :  end do
    3221         1830 :  ABI_FREE(coeffs)
    3222              : 
    3223              : 
    3224           84 : end subroutine coeffs_xml2effpot
    3225              : !!***
    3226              : 
    3227              : !!****f* m_effective_potential_file/effective_potential_file_readMDfile
    3228              : !!
    3229              : !! NAME
    3230              : !! effective_potential_file_readMDfile
    3231              : !!
    3232              : !! FUNCTION
    3233              : !! Read MD FILE (HIST or ASCII)
    3234              : !!
    3235              : !! INPUTS
    3236              : !! filename = path of the file
    3237              : !! option,optional   = 0 (default), the stress is printed in the MD File
    3238              : !!                     1, the force on the cell is printed in the MD File (-1 * stress),
    3239              : !!                        in this case, we multiply the stress by -1 in order to get the stresse
    3240              : !!
    3241              : !! OUTPUT
    3242              : !! hist<type(abihist)> = datatype with the  history of the MD
    3243              : !!
    3244              : !! SOURCE
    3245              : 
    3246           13 : subroutine effective_potential_file_readMDfile(filename,hist,option)
    3247              : 
    3248              : !Arguments ------------------------------------
    3249              : !scalars
    3250              :  integer,optional :: option
    3251              : !arrays
    3252              :  type(abihist),intent(inout) :: hist
    3253              :  character(len=fnlen),intent(in) :: filename
    3254              : !Local variables-------------------------------
    3255              : !scalar
    3256              :  integer :: ia,ii,mu,nu,natom,nstep,type,option_in
    3257              :  integer :: ios=0, unit_md=24
    3258              : !arrays
    3259              :  character (len=10000) :: readline,line
    3260              :  real(dp) :: tmp(6)
    3261           13 :  real(dp),allocatable :: xcart(:,:)
    3262              : ! *************************************************************************
    3263              : 
    3264           13 :  call effective_potential_file_getType(filename,type)
    3265              : 
    3266           13 :  option_in = 0
    3267              :  if(present(option))then
    3268              :    option_in = option
    3269              :  end if
    3270           13 :  if(type==40)then
    3271              : !  Netcdf type
    3272           13 :    call read_md_hist(filename,hist,.FALSE.,.FALSE.,.FALSE.)
    3273              : 
    3274            0 :  else if(type==41)then
    3275              : 
    3276              : !  ASCII file
    3277            0 :    call  effective_potential_file_getDimMD(filename,natom,nstep)
    3278              : 
    3279            0 :    ii  = 1
    3280            0 :    ios = 0
    3281              : 
    3282            0 :    ABI_MALLOC(xcart,(3,natom))
    3283            0 :    call abihist_free(hist)
    3284            0 :    call abihist_init(hist,natom,nstep,.FALSE.,.FALSE.)
    3285              : 
    3286              : !  Start a reading loop in fortran
    3287            0 :    rewind(unit=unit_md)
    3288            0 :    do while ((ios==0).and.ii<=nstep)
    3289            0 :      read(unit_md,'(a)',iostat=ios) readline
    3290            0 :      read(unit_md,'(a)',iostat=ios) readline
    3291            0 :      line=adjustl(readline)
    3292            0 :      read(line,*) hist%etot(ii)
    3293              :      hist%etot(ii) = hist%etot(ii)
    3294            0 :      do mu=1,3
    3295            0 :        read(unit_md,'(a)',iostat=ios) readline
    3296            0 :        line=adjustl(readline)
    3297            0 :        read(line,*) (hist%rprimd(nu,mu,ii),nu=1,3)
    3298              :      end do
    3299            0 :      do ia=1,natom
    3300            0 :        read(unit_md,'(a)',iostat=ios) readline
    3301            0 :        line=adjustl(readline)
    3302            0 :        read(line,*) (tmp(mu),mu=1,6)
    3303            0 :        xcart(:,ia) = tmp(1:3)
    3304            0 :        hist%fcart(:,ia,ii) = tmp(4:6)
    3305              :      end do
    3306            0 :      call xcart2xred(natom,hist%rprimd(:,:,ii),xcart(:,:),hist%xred(:,:,ii))
    3307            0 :      read(unit_md,'(a)',iostat=ios) readline
    3308            0 :      line=adjustl(readline)
    3309            0 :      read(line,*) (hist%strten(mu,ii),mu=1,6)
    3310            0 :      ii = ii + 1
    3311              :    end do
    3312            0 :    do ii=1,nstep
    3313            0 :      do mu=1,3
    3314            0 :        hist%acell(mu,:) = hist%rprimd(mu,mu,ii)
    3315              :      end do
    3316              :    end do
    3317            0 :    close(unit_md)
    3318            0 :    ABI_FREE(xcart)
    3319              : 
    3320              :  end if!end if type
    3321              : 
    3322           13 :    if((type==40 .or. type==41).and.option == 1)then
    3323              : !    multiply by -1 if the current strten -1*stress, we need only stress...
    3324            0 :      hist%strten(:,:) = -1 * hist%strten(:,:)
    3325              :    end if
    3326              : 
    3327              : 
    3328              : 
    3329           28 : end subroutine effective_potential_file_readMDfile
    3330              : !!***
    3331              : 
    3332              : !!****f* m_effective_potential_file/effective_potential_file_mapHistToRef
    3333              : !!
    3334              : !! NAME
    3335              : !! effective_potential_file_mapHistToRef
    3336              : !!
    3337              : !! FUNCTION
    3338              : !! Generate the supercell in the effective potential according to the size of the
    3339              : !! supercell in the hist file
    3340              : !! Check if the hist file match to reference supercell in the effective potential
    3341              : !! If not, the hist file is reordering
    3342              : !!
    3343              : !! INPUTS
    3344              : !! eff_pot<type(effective_potential)> = effective potential
    3345              : !! hist<type(abihist)> = The history of the MD
    3346              : !! comm = MPI communicator
    3347              : !!
    3348              : !! OUTPUT
    3349              : !! hist<type(abihist)> = The history of the MD
    3350              : !!
    3351              : !! SOURCE
    3352              : 
    3353           34 : subroutine effective_potential_file_mapHistToRef(eff_pot,hist,comm,iatfix,verbose,sc_size)
    3354              : 
    3355              : !Arguments ------------------------------------
    3356              : !scalars
    3357              :  integer,intent(in) :: comm
    3358              :  logical,optional,intent(in) :: verbose
    3359              : !arrays
    3360              :  type(effective_potential_type),intent(inout) :: eff_pot
    3361              :  type(abihist),intent(inout) :: hist
    3362              :  integer,optional,allocatable,intent(inout) :: iatfix(:,:)
    3363              :  integer,optional,intent(in) :: sc_size(3)
    3364              : !Local variables-------------------------------
    3365              : !scalar
    3366              :  integer :: factE_hist,ia,ib,ii,jj,natom_hist,ncells,nstep_hist
    3367              :  real(dp):: factor,ratio
    3368              :  logical :: revelant_factor,need_map,need_verbose,need_fixmap
    3369              : !arrays
    3370              :  real(dp) :: rprimd_hist(3,3),rprimd_ref(3,3)
    3371              :  integer :: ncell(3),scale_cell(3)
    3372           34 :  integer,allocatable  :: shift(:,:),iatfix_tmp(:,:)
    3373           34 :  integer,allocatable  :: list_map(:) !blkval(:),
    3374           34 :  real(dp),allocatable :: xred_ref(:,:) ! xred_hist(:,:),
    3375           34 :  real(dp),allocatable :: list_dist(:),list_reddist(:,:),list_absdist(:,:)
    3376              :  character(len=500) :: msg
    3377           34 :  type(abihist) :: hist_tmp
    3378              : ! *************************************************************************
    3379              : 
    3380              : !Set optional values
    3381           34 :  need_verbose = .false.
    3382           34 :  need_fixmap = .FALSE.
    3383           34 :  if (present(verbose)) need_verbose = verbose
    3384           34 :  if (present(iatfix)) need_fixmap = .TRUE.
    3385              : 
    3386              : 
    3387           34 :  natom_hist = size(hist%xred,2)
    3388           34 :  nstep_hist = size(hist%xred,3)
    3389              : 
    3390              : ! Try to set the supercell according to the hist file
    3391          442 :  rprimd_ref(:,:)  = eff_pot%crystal%rprimd
    3392          442 :  rprimd_hist(:,:) = hist%rprimd(:,:,1)
    3393              : 
    3394              : 
    3395           34 :  if(present(sc_size))then
    3396           12 :     ncell(:) = sc_size
    3397              :  else
    3398           88 :     do ia=1,3
    3399           66 :       scale_cell(:) = 0
    3400          264 :       do ii=1,3
    3401          264 :         if(abs(rprimd_ref(ii,ia)) > tol10)then
    3402           66 :           scale_cell(ii) = nint(rprimd_hist(ii,ia) / rprimd_ref(ii,ia))
    3403              :         end if
    3404              :       end do
    3405              : !     Check if the factor for the supercell is revelant
    3406           66 :       revelant_factor = .TRUE.
    3407          264 :       do ii=1,3
    3408          198 :         if(abs(scale_cell(ii)) < tol10) cycle
    3409           66 :         factor = abs(scale_cell(ii))
    3410          264 :         do jj=ii,3
    3411          132 :           if(abs(scale_cell(jj)) < tol10) cycle
    3412          396 :           if(abs(abs(scale_cell(ii))-abs(scale_cell(jj))) > tol10) revelant_factor = .FALSE.
    3413              :         end do
    3414              :       end do
    3415           88 :       if(.not.revelant_factor)then
    3416              :         write(msg, '(3a)' )&
    3417            0 : &            'unable to map the hist file ',ch10,&
    3418            0 : &            'Action: check/change your MD file'
    3419            0 :         ABI_ERROR(msg)
    3420              :       else
    3421           66 :         ncell(ia) = int(factor)
    3422              :       end if
    3423              :     end do
    3424              :  end if
    3425              : 
    3426          136 :  ncells = product(ncell)
    3427              : 
    3428              : !Check if the energy stored in the hist is revelant, sometimes some MD files gives
    3429              : !the energy of the unit cell... This is not suppose to happen... But just in case...
    3430          705 :  do ii=1,nstep_hist
    3431          705 :    if(abs(eff_pot%energy)>tol12)then
    3432          671 :      ratio=hist%etot(ii) / eff_pot%energy
    3433          671 :      if(abs(ratio)<real(huge(factE_hist))*half)then
    3434          671 :        factE_hist = nint(ratio)
    3435          671 :        if(factE_hist == 1) then
    3436              : !      In this case we mutiply the energy of the hist by the number of cell
    3437            0 :          hist%etot(ii) = hist%etot(ii)  * ncells
    3438              :        end if
    3439          671 :        if(factE_hist /=1 .and. factE_hist /= ncells)then
    3440           31 :          write(msg, '(4a,I0,a,I0,2a,I0,3a,I0,3a)' )ch10,&
    3441           31 : &            ' --- !WARNING',ch10,&
    3442           31 : &            '     The energy of the history step ',ii,' seems to be with multiplicity of ',factE_hist,ch10,&
    3443           31 : &            '     However, the multiplicity of the cell is ',ncells,'.',ch10,&
    3444           31 : &            '     Please check the energy of the step ',ii,ch10,&
    3445           62 : &            ' ---',ch10
    3446           31 :          if(need_verbose) call wrtout(std_out,msg,'COLL')
    3447              :        endif
    3448              :      else
    3449            0 :        write(msg, '(4a,i0,3a,es16.6,5a)' )ch10,&
    3450            0 : &          ' --- !WARNING',ch10,&
    3451            0 : &          '     The energy of the history step ',ii,' is apparently not initialized.',ch10,&
    3452            0 : &          '     Its current value is',hist%etot(ii),ch10,&
    3453            0 : &          '     This does not allow to perform checking on the multiplicity of the cell ',ch10,&
    3454            0 : &          ' ---',ch10
    3455            0 :        if(need_verbose) call wrtout(std_out,msg,'COLL')
    3456              :      end if
    3457              :    end if
    3458              :  end do
    3459              : 
    3460              : 
    3461              : !Set the new supercell datatype into the effective potential reference
    3462           34 :  call effective_potential_setSupercell(eff_pot,comm,ncell)
    3463              : 
    3464              : !allocation
    3465          102 :  ABI_MALLOC(shift,(3,natom_hist))
    3466          102 :  ABI_MALLOC(list_map,(natom_hist))
    3467          102 :  ABI_MALLOC(list_reddist,(3,natom_hist))
    3468           68 :  ABI_MALLOC(list_absdist,(3,natom_hist))
    3469          102 :  ABI_MALLOC(list_dist,(natom_hist))
    3470           68 :  ABI_MALLOC(xred_ref,(3,natom_hist))
    3471              : 
    3472              :  !Putting maping list to zero
    3473         1534 :  list_map = 0
    3474              : 
    3475              :  !Fill xcart_ref/hist and xred_ref/hist
    3476              : 
    3477              :  call xcart2xred(eff_pot%supercell%natom,eff_pot%supercell%rprimd,&
    3478           34 : &                eff_pot%supercell%xcart,xred_ref)                   ! Get xred_ref
    3479              : 
    3480              : 
    3481         1534 : do ia=1,natom_hist !Loop over all reference atoms
    3482              :    ! Put temporary lists to zero
    3483       310300 :    list_reddist = 0
    3484       310300 :    list_absdist = 0
    3485        78700 :    list_dist = 0
    3486       310300 :    shift = 0
    3487        78700 :    do ib=1,natom_hist !Loop over all atoms of distorted structure
    3488              :       !Calculate list of reduced distance between reference atom ia and all others
    3489       308800 :       list_reddist(:,ib) = hist%xred(:,ib,1) - xred_ref(:,ia)
    3490              :       !If the distorted atom is further away than half the unit cell shift it.
    3491        77200 :       if(list_reddist(1,ib) > 0.5)then
    3492         6439 :          list_reddist(1,ib) = 1 -  list_reddist(1,ib)
    3493         6439 :          shift(1,ib) = -1
    3494              :       end if
    3495        77200 :       if(list_reddist(2,ib) > 0.5)then
    3496         6370 :          list_reddist(2,ib) = 1 -  list_reddist(2,ib)
    3497         6370 :          shift(2,ib) = -1
    3498              :       end if
    3499        77200 :       if(list_reddist(3,ib) > 0.5)then
    3500         2541 :          list_reddist(3,ib) = 1 -  list_reddist(3,ib)
    3501         2541 :          shift(3,ib) = -1
    3502              :       end if
    3503        77200 :       if(list_reddist(1,ib) < -0.5)then
    3504         9714 :          list_reddist(1,ib) = -1 -  list_reddist(1,ib)
    3505         9714 :          shift(1,ib) = 1
    3506              :       end if
    3507        77200 :       if(list_reddist(2,ib) < -0.5)then
    3508         9410 :          list_reddist(2,ib) = -1 -  list_reddist(2,ib)
    3509         9410 :          shift(2,ib) = 1
    3510              :       end if
    3511        77200 :       if(list_reddist(3,ib) < -0.5)then
    3512         4543 :          list_reddist(3,ib) = -1 -  list_reddist(3,ib)
    3513         4543 :          shift(3,ib) = 1
    3514              :       end if
    3515        77200 :       list_absdist(1,ib) = (rprimd_hist(1,1)+rprimd_hist(2,1)+rprimd_hist(3,1))*list_reddist(1,ib)
    3516        77200 :       list_absdist(2,ib) = (rprimd_hist(1,2)+rprimd_hist(2,2)+rprimd_hist(3,2))*list_reddist(2,ib)
    3517        77200 :       list_absdist(3,ib) = (rprimd_hist(1,3)+rprimd_hist(2,3)+rprimd_hist(3,3))*list_reddist(3,ib)
    3518        78700 :       list_dist(ib) = sqrt(abs(list_absdist(1,ib))**2 + abs(list_absdist(2,ib))**2 + abs(list_absdist(3,ib))**2 )
    3519              :    end do !ib
    3520              :    !find the closest atom ib
    3521        78700 :    list_map(ia) = minloc(list_dist,DIM=1)
    3522              :    !If the closest atom ib was shifted, apply and store the shift
    3523         6018 :    if(any(shift(:,list_map(ia)) /= 0))then
    3524           16 :       hist%xred(1,list_map(ia),:)= hist%xred(1,list_map(ia),:) + 1*shift(1,list_map(ia))
    3525           16 :       hist%xred(2,list_map(ia),:)= hist%xred(2,list_map(ia),:) + 1*shift(2,list_map(ia))
    3526           16 :       hist%xred(3,list_map(ia),:)= hist%xred(3,list_map(ia),:) + 1*shift(3,list_map(ia))
    3527              :    end if
    3528              :    !TEST MS
    3529              :    !write(*,*) 'Atom', ia,' of reference is matche with', list_map(ia)
    3530              :    !write(*,*) 'xred_ref(',xred_ref(:,ia),'), xred_hist(',hist%(:,list_map(ia)),')'
    3531              : end do  ! ia
    3532              : 
    3533           34 :  if(need_verbose) then
    3534           13 :    write(msg,'(2a,I3,a,I3,a,I3)') ch10,&
    3535           26 : &       ' The size of the supercell for the fit is ',ncell(1),' ',ncell(2),' ',ncell(3)
    3536           13 :    call wrtout(std_out,msg,'COLL')
    3537           13 :    call wrtout(ab_out,msg,'COLL')
    3538              :  end if
    3539              : 
    3540              : 
    3541         1534 :    if(any(list_map(:)==0))then
    3542              :        write(msg, '(5a)' )&
    3543            0 : &         'Unable to map the molecular dynamic file  ',ch10,&
    3544            0 : &         'on the reference supercell structure',ch10,&
    3545            0 : &         'Action: change the MD file'
    3546            0 :        ABI_ERROR(msg)
    3547              :    end if
    3548              : 
    3549           34 :  need_map = .FALSE.
    3550         1534 :  do ia=1,natom_hist
    3551         1534 :    if(list_map(ia) /= ia) need_map = .TRUE.
    3552              :  end do
    3553           34 :  if(need_map)then
    3554           21 :    if(need_verbose) then
    3555            1 :      write(msg, '(11a)' )ch10,&
    3556            1 : &      ' --- !WARNING',ch10,&
    3557            1 : &      '     The ordering of the atoms in the _HIST.nc file is different,',ch10,&
    3558            1 : &      '     of the one built by multibinit. The _HIST.nc file will be mapped,',ch10,&
    3559            1 : &      '     to the ordering of multibinit.',ch10,&
    3560            2 : &      ' ---',ch10
    3561            1 :      call wrtout(ab_out,msg,'COLL')
    3562            1 :      call wrtout(std_out,msg,'COLL')
    3563              :    end if
    3564              : 
    3565              : ! Allocate hist datatype
    3566           21 :    call abihist_init(hist_tmp,natom_hist,nstep_hist,.false.,.false.)
    3567              : ! copy all the information
    3568          512 :    do ia=1,nstep_hist
    3569          491 :      hist%ihist = ia
    3570          491 :      hist_tmp%ihist = ia
    3571          512 :      call abihist_copy(hist,hist_tmp)
    3572              :    end do
    3573           21 :    hist_tmp%mxhist = nstep_hist
    3574              : 
    3575              : ! reoder array
    3576          861 :    do ia=1,natom_hist
    3577        79400 :      hist_tmp%xred(:,ia,:)  = hist%xred(: ,list_map(ia),:)
    3578        79400 :      hist_tmp%fcart(:,ia,:) = hist%fcart(:,list_map(ia),:)
    3579        79421 :      hist_tmp%vel(:,ia,:)   = hist%vel(:,list_map(ia),:)
    3580              :    end do
    3581              : 
    3582              : ! free the old hist and reinit
    3583           21 :    call abihist_free(hist)
    3584           21 :    call abihist_init(hist,natom_hist,nstep_hist,.false.,.false.)
    3585              : ! copy the temporary hist into output
    3586          512 :    do ia=1,nstep_hist
    3587          491 :      hist%ihist = ia
    3588          491 :      hist_tmp%ihist = ia
    3589          512 :      call abihist_copy(hist_tmp,hist)
    3590              :    end do
    3591              :    hist_tmp%mxhist = nstep_hist
    3592           21 :    call abihist_free(hist_tmp)
    3593              : 
    3594              :    !map also fixes if present
    3595           21 :    if(need_fixmap)then
    3596            2 :      ABI_MALLOC(iatfix_tmp,(3,natom_hist))
    3597           41 :      do ia=1,natom_hist
    3598          161 :         iatfix_tmp(:,ia) = iatfix(:,list_map(ia))
    3599              :      end do
    3600          162 :      iatfix = iatfix_tmp
    3601            1 :      ABI_FREE(iatfix_tmp)
    3602              :    end if
    3603              :  end if !need map
    3604              : 
    3605              : !deallocation
    3606           34 :  ABI_FREE(shift)
    3607           34 :  ABI_FREE(list_map)
    3608           34 :  ABI_FREE(list_dist)
    3609           34 :  ABI_FREE(list_reddist)
    3610           34 :  ABI_FREE(list_absdist)
    3611           34 :  ABI_FREE(xred_ref)
    3612           34 : end subroutine effective_potential_file_mapHistToRef
    3613              : !!***
    3614              : 
    3615              : 
    3616              : !****f* m_effective_potential_file/effective_potential_file_readDisplacement
    3617              : !!
    3618              : !! NAME
    3619              : !! effective_potential_file_readDisplacement
    3620              : !!
    3621              : !! FUNCTION
    3622              : !! Read a displacement ASCII file
    3623              : !!
    3624              : !! INPUTS
    3625              : !! filename = path of the file
    3626              : !! natom = number of atoms in the cell
    3627              : !! nstep = number of time step
    3628              : !!
    3629              : !! OUTPUT
    3630              : !! disp(3,natom_sc) = atomics displacement between configuration and the reference
    3631              : !!
    3632              : !! SOURCE
    3633              : 
    3634            0 : subroutine effective_potential_file_readDisplacement(filename,disp,nstep,natom)
    3635              : 
    3636              : !Arguments ------------------------------------
    3637              : !scalars
    3638              :  integer, intent(in) :: natom,nstep
    3639              :  character(len=fnlen),intent(in) :: filename
    3640              : !array
    3641              :  real(dp),intent(out) :: disp(nstep,3,natom)
    3642              : !Local variables------------------------------
    3643              : !scalars
    3644              :  integer :: ios = 0
    3645              :  integer :: ia,istep,mu
    3646              :  character(500) :: message
    3647              :  character (len=500000) :: line,readline
    3648              :  integer :: funit = 666
    3649              : ! *************************************************************************
    3650              : 
    3651            0 :  if (open_file(filename,message,unit=funit,form="formatted",&
    3652              :    status="old",action="read") /= 0) then
    3653            0 :    ABI_ERROR(message)
    3654              :  end if
    3655              : 
    3656            0 :  write(message, '(2a)' ) " Read displacements from ", trim(filename)
    3657              : 
    3658            0 :  call wrtout(ab_out,message,'COLL')
    3659            0 :  call wrtout(std_out,message,'COLL')
    3660            0 :  do istep=1,nstep
    3661            0 :    do ia=1,natom
    3662            0 :      read(funit,'(a)',iostat=ios) readline
    3663            0 :      line=adjustl(readline)
    3664            0 :      read(unit=line,fmt=*) (disp(istep,mu,ia),mu=1,3)
    3665            0 :      write(111,'(3(es21.12))') disp(istep,:,ia)
    3666              :    end do
    3667              :  end do
    3668              : 
    3669            0 :  close(funit)
    3670              : 
    3671            0 : end subroutine effective_potential_file_readDisplacement
    3672              : !!***
    3673              : 
    3674              : !!****f* m_effective_potential_file/elementfromline
    3675              : !! NAME
    3676              : !! elementfromline
    3677              : !!
    3678              : !! FUNCTION
    3679              : !! Read the number of element of a line
    3680              : !!
    3681              : !! INPUTS
    3682              : !!  line= string from which the data are read
    3683              : !!
    3684              : !! OUTPUT
    3685              : !!  nelement = number of element in the line
    3686              : !!
    3687              : !! SOURCE
    3688              : 
    3689            0 : subroutine elementfromline(line,nelement)
    3690              : 
    3691              : !Arguments ---------------------------------------------
    3692              :  character(len=*), intent(in) :: line
    3693              :  integer, intent(out) :: nelement
    3694              : !Local variables ---------------------------------------
    3695              :  integer :: ii,n
    3696              :  logical :: element
    3697              : ! *********************************************************************
    3698              : 
    3699              : !Set the output
    3700            0 :  nelement = 0
    3701            0 :  n = len_trim(line)
    3702            0 :  element = .false.
    3703            0 :  do ii=1,n
    3704            0 :    if(.not.element.and.line(ii:ii) /="")  then
    3705              :      element=.true.
    3706              :    else
    3707            0 :      if((element.and.line(ii:ii) =="")) then
    3708            0 :        element=.false.
    3709            0 :        nelement = nelement + 1
    3710              :      end if
    3711              :    end if
    3712            0 :    if((element.and.ii==n)) nelement = nelement + 1
    3713              :  end do
    3714              : 
    3715            0 :  end subroutine elementfromline
    3716              : !!***
    3717              : 
    3718              : !!****f* m_effective_potential_file/rdfromline
    3719              : !! NAME
    3720              : !! rdfromline
    3721              : !!
    3722              : !! FUNCTION
    3723              : !! Read the value of a keyword from a XML line
    3724              : !! Same function than m_pawxmlps/paw_rdfromline.F90
    3725              : !!
    3726              : !! INPUTS
    3727              : !!  keyword= keyword which value has to be read
    3728              : !!  line= string from which the data are read (line from a XML)
    3729              : !!
    3730              : !! OUTPUT
    3731              : !!  output= (string) value of the keyword
    3732              : !!
    3733              : !! SOURCE
    3734              : 
    3735       511584 :  subroutine rdfromline(keyword,line,output)
    3736              : 
    3737              : !Arguments ---------------------------------------------
    3738              :   character(len=*), intent(in) :: keyword,line
    3739              :   character(len=*), intent(out) :: output
    3740              : !Local variables ---------------------------------------
    3741       511584 :   character(len=len(line)) :: temp
    3742              :   integer :: pos,pos2
    3743              : 
    3744              : ! *********************************************************************
    3745              : 
    3746       511584 :  output=""
    3747       511584 :  pos=index(line,trim(keyword))
    3748       511584 :  if (pos>0) then
    3749       511568 :    temp=line(pos+len_trim(keyword):len_trim(line))
    3750       511568 :    pos=index(temp,char(34))
    3751       511568 :    if (pos>0) then
    3752       511568 :      pos2=index(temp(pos+1:len_trim(temp)),char(34))
    3753       511568 :      if (pos2>0) then
    3754       511568 :        output=temp(pos+1:pos+pos2-1)
    3755              :      end if
    3756              :    end if
    3757              :  end if
    3758              : 
    3759       511584 :  end subroutine rdfromline
    3760              : !!***
    3761              : 
    3762              : 
    3763              : !!****f* m_effective_potential_file/rmtabfromline
    3764              : !! NAME
    3765              : !! rmtabfromline
    3766              : !!
    3767              : !! FUNCTION
    3768              : !! Read remove tab from the begining of line
    3769              : !!
    3770              : !! INPUTS
    3771              : !!  line= string from which the data are read (line from a XML)
    3772              : !!
    3773              : !! OUTPUT
    3774              : !!  output= line without tab
    3775              : !!
    3776              : !! SOURCE
    3777              : 
    3778      2062683 : recursive subroutine rmtabfromline(line)
    3779              : 
    3780              : !Arguments ---------------------------------------------
    3781              :   character(len=*), intent(inout) :: line
    3782              : !Local variables ---------------------------------------
    3783              :   integer :: pos
    3784              : 
    3785              : ! *********************************************************************
    3786              : 
    3787      2062764 :  pos=index(line,char(9))
    3788      2062764 :  if (pos==1) then
    3789           81 :    line = line(2:len_trim(line))//" "
    3790              :    call rmtabfromline(line)
    3791              :  end if
    3792              : 
    3793      2062764 :  end subroutine rmtabfromline
    3794              : !!***
    3795              : 
    3796              : 
    3797              : 
    3798              : !!****f* m_effective_potential_file/rdfromline_value
    3799              : !! NAME
    3800              : !! rdfromline
    3801              : !!
    3802              : !! FUNCTION
    3803              : !! Read the value of a keyword from a XML line
    3804              : !!
    3805              : !! INPUTS
    3806              : !!  keyword= keyword which value has to be read
    3807              : !!  line= string from which the data are read (line from a XML)
    3808              : !!
    3809              : !! OUTPUT
    3810              : !!  output= (string) value of the keyword
    3811              : !!
    3812              : !! SOURCE
    3813              : 
    3814       218900 :  subroutine rdfromline_value(keyword,line,output)
    3815              : 
    3816              : !Arguments ---------------------------------------------
    3817              :   character(len=*), intent(in) :: keyword,line
    3818              :   character(len=*), intent(out) :: output
    3819              : !Local variables ---------------------------------------
    3820       218900 :   character(len=len(line)) :: temp
    3821              :   integer :: pos,pos2
    3822              : 
    3823              : ! *********************************************************************
    3824              : 
    3825       218900 :  output=""
    3826       218900 :  pos=index(line,trim(keyword))
    3827       218900 :  if (pos==2) then
    3828       218548 :    pos=pos+len_trim(keyword)
    3829       218548 :    pos=pos+index(line(pos:len_trim(line)),char(62))
    3830       218548 :    temp=line(pos:len_trim(line))
    3831       218548 :    pos2=index(temp,char(60))
    3832       218548 :    if (pos2>0) then
    3833       215484 :      output=line(pos:pos+pos2-2)
    3834              :    else
    3835         3064 :      output=line(pos:len_trim(line))
    3836              :    end if
    3837              :  else
    3838          352 :    if(pos>2)then
    3839            0 :      output=line(1:pos-3)
    3840              :    end if
    3841              :  end if
    3842       218900 : end subroutine rdfromline_value
    3843              : !!***
    3844              : 
    3845              : 
    3846              : !!****f* m_effpot_xml/char_f2c
    3847              : !! NAME
    3848              : !!  char_f_to_c
    3849              : !!
    3850              : !! FUNCTION
    3851              : !! Helper function to convert a Fortran string to a C string
    3852              : !! Based on a routine by Joseph M. Krahn
    3853              : !!
    3854              : !! INPUTS
    3855              : !!  f_string=Fortran string
    3856              : !!
    3857              : !! OUTPUT
    3858              : !!  c_string=C string
    3859              : !!
    3860              : !! SOURCE
    3861              : 
    3862              : #if defined HAVE_XML
    3863              : 
    3864              : function char_f2c(f_string) result(c_string)
    3865              : 
    3866              :  use, intrinsic :: iso_c_binding, only : C_CHAR,C_NULL_CHAR
    3867              : !Arguments ------------------------------------
    3868              :  character(len=*),intent(in) :: f_string
    3869              :  character(kind=C_CHAR,len=1) :: c_string(len_trim(f_string)+1)
    3870              : !Local variables -------------------------------
    3871              :  integer :: ii,strlen
    3872              : !! *************************************************************************
    3873              :  strlen=len_trim(f_string)
    3874              :  forall(ii=1:strlen)
    3875              :    c_string(ii)=f_string(ii:ii)
    3876              :  end forall
    3877              :  c_string(strlen+1)=C_NULL_CHAR
    3878              : end function char_f2c
    3879              : !!***
    3880              : 
    3881              : !----------------------------------------------------------------------
    3882              : 
    3883              : !!****f* m_effpot_xml/char_c2f
    3884              : !! NAME
    3885              : !!  char_c_to_f
    3886              : !!
    3887              : !! FUNCTION
    3888              : !! Helper function to convert a C string to a Fortran string
    3889              : !! Based on a routine by Joseph M. Krahn
    3890              : !!
    3891              : !! INPUTS
    3892              : !!  c_string=C string
    3893              : !!
    3894              : !! OUTPUT
    3895              : !!  f_string=Fortran string
    3896              : !!
    3897              : !! SOURCE
    3898              : 
    3899              : subroutine char_c2f(c_string,f_string)
    3900              : 
    3901              :  use, intrinsic :: iso_c_binding, only : C_CHAR,C_NULL_CHAR
    3902              : !Arguments ------------------------------------
    3903              :  character(kind=C_CHAR,len=1),intent(in) :: c_string(*)
    3904              :  character(len=*),intent(out) :: f_string
    3905              : !Local variables -------------------------------
    3906              :  integer :: ii
    3907              : !! *************************************************************************
    3908              :  ii=1
    3909              :  do while(c_string(ii)/=C_NULL_CHAR.and.ii<=len(f_string))
    3910              :    f_string(ii:ii)=c_string(ii) ; ii=ii+1
    3911              :  end do
    3912              :  if (ii<len(f_string)) f_string(ii:)=' '
    3913              : end subroutine char_c2f
    3914              : !!***
    3915              : #endif
    3916              : 
    3917              : end module m_effective_potential_file
    3918              : !!***
        

Generated by: LCOV version 2.3-1