TABLE OF CONTENTS


ABINIT/m_effective_potential_file [ Modules ]

[ Top ] [ Modules ]

NAME

 m_effective_potential_file

FUNCTION

 This  module contains all routine to read the effective potential from files
 Can also read coefficients from XML
 (XML or DDB)

COPYRIGHT

 Copyright (C) 2000-2024 ABINIT group (AM)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

SOURCE

 19 #if defined HAVE_CONFIG_H
 20 #include "config.h"
 21 #endif
 22 
 23 #include "abi_common.h"
 24 
 25 module m_effective_potential_file
 26 
 27  use defs_basis
 28  use m_errors
 29  use m_abicore
 30  use m_xmpi
 31  use m_harmonics_terms
 32  use m_anharmonics_terms
 33  use m_effective_potential
 34  use m_ifc
 35  use m_ddb
 36  use m_ddb_hdr
 37 #if defined HAVE_NETCDF
 38  use netcdf
 39 #endif
 40 
 41  use m_io_tools,   only : open_file, get_unit
 42  use m_geometry,   only : xcart2xred, xred2xcart, metric
 43  use m_symfind,    only : symfind, symlatt
 44  use m_crystal,    only : crystal_t, crystal_init
 45  use m_dynmat,     only : dfpt_prtph
 46  use m_abihist,    only : abihist,abihist_init,abihist_free,abihist_copy,read_md_hist
 47  use m_ddb_internalstr, only : ddb_internalstr
 48 
 49  implicit none
 50 
 51  public :: effective_potential_file_getDimCoeff
 52  public :: effective_potential_file_getDimMD
 53  public :: effective_potential_file_getDimSystem
 54  public :: effective_potential_file_getDimStrainCoupling
 55  public :: effective_potential_file_getType
 56  public :: effective_potential_file_mapHistToRef
 57  public :: effective_potential_file_read
 58  public :: effective_potential_file_readDisplacement
 59  public :: effective_potential_file_readMDfile
 60  private :: coeffs_xml2effpot
 61  private :: system_getDimFromXML
 62  private :: system_xml2effpot
 63  private :: system_ddb2effpot
 64 
 65 #ifndef HAVE_XML
 66  private :: rdfromline
 67  private :: rmtabfromline
 68  private :: rdfromline_value
 69  private :: elementfromline
 70 #endif
 71 
 72 #if defined HAVE_XML
 73  public :: effpot_xml_checkXML
 74  public :: effpot_xml_getDimCoeff
 75  public :: effpot_xml_readSystem
 76  public :: effpot_xml_getValue
 77  public :: effpot_xml_getAttribute
 78  public :: effpot_xml_getDimSystem
 79 
 80  interface
 81    subroutine effpot_xml_readSystem(filename,natom,&
 82 &     ntypat,nrpt,nqpt,amu,atmfrc,cell,dynmat,elastic_constants,&
 83 &     energy,epsilon_inf,ewald_atmfrc,&
 84 &     phfrq,rprimd,qph1l,short_atmfrc,typat,xcart,zeff)&
 85 &                          bind(C,name="effpot_xml_readSystem")
 86      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
 87      integer(C_INT) :: natom,ntypat,nrpt,nqpt
 88      integer(C_INT) :: typat(natom)
 89      integer(C_INT) :: cell(3,nrpt)
 90      real(C_DOUBLE) :: energy
 91      real(C_DOUBLE) :: dynmat(2,3,natom,3,natom,nqpt)
 92      real(C_DOUBLE) :: phfrq(3*natom,nqpt),qph1l(3,nqpt)
 93      real(C_DOUBLE) :: atmfrc(3,natom,3,natom,nrpt)
 94      real(C_DOUBLE) :: short_atmfrc(3,natom,3,natom,nrpt)
 95      real(C_DOUBLE) :: ewald_atmfrc(3,natom,3,natom,nrpt)
 96      real(C_DOUBLE) :: amu(ntypat),rprimd(3,3),epsilon_inf(3,3)
 97      real(C_DOUBLE) :: zeff(3,3,natom)
 98      real(C_DOUBLE) :: elastic_constants(6,6),xcart(3,natom)
 99      character(kind=C_CHAR) :: filename(*)
100    end subroutine effpot_xml_readSystem
101  end interface
102 
103  interface
104    subroutine effpot_xml_readStrainCoupling(filename,natom,&
105 &     nrpt,voigt,elastic3rd,elastic_displacement,&
106 &     strain_coupling,phonon_strain_atmfrc,phonon_straincell)&
107 &                          bind(C,name="effpot_xml_readStrainCoupling")
108      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
109      integer(C_INT) :: natom
110      integer(C_INT) :: nrpt,voigt
111      integer(c_INT) :: phonon_straincell(3,nrpt)
112      real(C_DOUBLE) :: elastic3rd(6,6),elastic_displacement(6,3,natom)
113      real(C_DOUBLE) :: strain_coupling(3,natom)
114      real(C_DOUBLE) :: phonon_strain_atmfrc(3,natom,3,natom,nrpt)
115      character(kind=C_CHAR) :: filename(*)
116    end subroutine effpot_xml_readStrainCoupling
117  end interface
118 
119  interface
120    subroutine effpot_xml_readCoeff(filename,ncoeff,ndisp,nterm,&
121 &                                 coefficient,atindx,cell,direction,power_disp,&
122 &                                 power_strain,strain,weight)&
123 &                          bind(C,name="effpot_xml_readCoeff")
124      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT
125      character(kind=C_CHAR) :: filename(*)
126      integer(C_INT) :: ncoeff,ndisp,nterm
127      integer(C_INT) :: atindx(ncoeff,nterm,2,ndisp)
128      integer(C_INT) :: cell(ncoeff,nterm,3,2,ndisp)
129      integer(C_INT) :: direction(ncoeff,nterm,ndisp)
130      integer(C_INT) :: strain(ncoeff,nterm,ndisp)
131      integer(C_INT) :: power_disp(ncoeff,nterm,ndisp)
132      integer(C_INT) :: power_strain(ncoeff,nterm,ndisp)
133      real(C_DOUBLE) :: coefficient(ncoeff)
134      real(C_DOUBLE) :: weight(ncoeff,nterm)
135    end subroutine effpot_xml_readCoeff
136  end interface
137 
138  interface
139    subroutine effpot_xml_getDimSystem(filename,natom,ntypat,nqpt,nrpt1,nrpt2)&
140 &                          bind(C,name="effpot_xml_getDimSystem")
141      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
142      integer(C_INT) :: natom,ntypat,nqpt,nrpt1,nrpt2
143      character(kind=C_CHAR) :: filename(*)
144    end subroutine effpot_xml_getDimSystem
145  end interface
146 
147  interface
148    subroutine effpot_xml_getDimStrainCoupling(filename,nrpt,voigt)&
149 &                          bind(C,name="effpot_xml_getDimStrainCoupling")
150      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
151      integer(C_INT) :: voigt
152      integer(C_INT) :: nrpt
153      character(kind=C_CHAR) :: filename(*)
154    end subroutine effpot_xml_getDimStrainCoupling
155  end interface
156 
157  interface
158    subroutine effpot_xml_getDimCoeff(filename,ncoeff,nterm_max,ndisp_max)&
159 &                          bind(C,name="effpot_xml_getDimCoeff")
160      use, intrinsic :: iso_c_binding, only : C_CHAR,C_DOUBLE,C_INT,C_PTR
161      character(kind=C_CHAR) :: filename(*)
162 !     character(kind=C_CHAR) :: name(*)
163      type(C_PTR) :: name
164      integer(C_INT) :: ncoeff,ndisp_max,nterm_max
165    end subroutine effpot_xml_getDimCoeff
166  end interface
167 
168 
169  interface
170    subroutine effpot_xml_checkXML(filename,name_root) &
171 &                          bind(C,name="effpot_xml_checkXML")
172      use, intrinsic :: iso_c_binding, only : C_CHAR
173      character(kind=C_CHAR) :: filename(*),name_root(*)
174    end subroutine effpot_xml_checkXML
175  end interface
176 
177  interface
178    subroutine effpot_xml_getValue(filename,name_value,value_result) &
179  &                          bind(C,name="effpot_xml_getValue")
180       use, intrinsic :: iso_c_binding, only : C_CHAR
181       implicit none
182       character(kind=C_CHAR) :: filename(*),name_value(*)
183       character(kind=C_CHAR) :: value_result
184     end subroutine effpot_xml_getValue
185   end interface
186 
187  interface
188    subroutine effpot_xml_getAttribute(filename,name_value,name_attribute) &
189 &                          bind(C,name="effpot_xml_getAttribute")
190      use, intrinsic :: iso_c_binding, only : C_CHAR
191      character(kind=C_CHAR) :: filename(*),name_value(*),name_attribute(*)
192    end subroutine effpot_xml_getAttribute
193  end interface
194 
195  interface
196    subroutine effpot_xml_getNumberKey(filename,name_value,number) &
197 &                          bind(C,name="effpot_xml_getNumberKey")
198      use, intrinsic :: iso_c_binding, only : C_CHAR,C_INT
199      character(kind=C_CHAR) :: filename(*),name_value(*)
200      integer(C_INT) :: number
201    end subroutine effpot_xml_getNumberKey
202  end interface
203 
204 #endif
205 
206  integer,parameter :: XML_RECL = 50000

m_effective_potential_file/coeffs_xml2effpot [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 coeffs_xml2effpot

FUNCTION

 Open xml file of effective potentiel, then reads the variables
 and store them in effective potentential type

INPUTS

 filename = path of input or output file
 comm=MPI communicator

OUTPUT

 eff_pot<type(effective_potential_type)> = effective_potential datatype

SOURCE

2837 subroutine coeffs_xml2effpot(eff_pot,filename,comm)
2838 
2839  use m_atomdata
2840  use m_polynomial_coeff
2841  use m_polynomial_term
2842  use m_crystal, only : symbols_crystal
2843 #if defined HAVE_XML
2844  use, intrinsic :: iso_c_binding, only : C_CHAR,C_PTR,c_f_pointer
2845 #endif
2846 
2847  !Arguments ------------------------------------
2848  !scalars
2849  character(len=*),intent(in) :: filename
2850  integer, intent(in) :: comm
2851  !arrays
2852  type(effective_potential_type), intent(inout) :: eff_pot
2853 
2854  !Local variables-------------------------------
2855  !scalar
2856  integer :: ii,jj,my_rank,ndisp,ncoeff,nterm_max,nstrain,ndisp_max,nproc,nterm
2857 ! character(len=200),allocatable :: name(:)
2858  character(len=200) :: name
2859 #ifdef HAVE_XML
2860  integer :: icoeff,iterm
2861 #endif
2862 
2863 #ifndef HAVE_XML
2864  integer :: funit = 1,ios = 0
2865  integer :: icoeff,idisp,istrain,iterm,mu
2866  logical :: found,found2,displacement
2867  character (len=XML_RECL) :: line,readline
2868  character (len=XML_RECL) :: strg,strg1
2869 #endif
2870  character(len=500) :: message
2871  character(len=264) :: filename_tmp
2872  character(len=5),allocatable :: symbols(:)
2873  integer,parameter :: master=0
2874  logical :: iam_master
2875  logical :: debug
2876  !arrays
2877  real(dp),allocatable :: coefficient(:),weight(:,:)
2878  integer,allocatable :: atindx(:,:,:,:), cell(:,:,:,:,:),direction(:,:,:),power_disp(:,:,:)
2879  integer,allocatable :: strain(:,:,:),power_strain(:,:,:)
2880  type(polynomial_coeff_type),dimension(:),allocatable :: coeffs
2881  type(polynomial_term_type),dimension(:,:),allocatable :: terms
2882 
2883 ! *************************************************************************
2884 
2885  filename_tmp = trim(filename)
2886  !Open the atomicdata XML file for reading
2887  write(message,'(a,a)')'-Opening the file ',filename_tmp
2888 
2889  call wrtout(ab_out,message,'COLL')
2890  call wrtout(std_out,message,'COLL')
2891 
2892  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
2893  iam_master = (my_rank == master)
2894 
2895 !Get Dimention of system and allocation/initialisation of array
2896  ncoeff  = 0
2897  nterm   = 0
2898  ndisp   = 0
2899  nstrain = 0
2900  call effective_potential_file_getDimCoeff(filename,ncoeff,ndisp_max,nterm_max)
2901 
2902 !  Do some checks
2903  if (nterm_max<=0) then
2904    write(message, '(a,a,a)' )&
2905 &     ' Unable to read the number of terms in ',trim(filename),ch10
2906    ABI_ERROR(message)
2907  end if
2908 
2909   if (ndisp_max<=0) then
2910     write(message, '(a,a,a)' )&
2911 &    ' Unable to read the number of displacement in ',trim(filename),ch10
2912     ABI_ERROR(message)
2913   end if
2914 
2915 !Allocation ov the polynomial coeff type
2916  ABI_MALLOC(coeffs,(ncoeff))
2917 
2918  if(iam_master)then
2919 
2920 #if defined HAVE_XML
2921    write(message,'(3a)')'-Reading the file ',trim(filename),&
2922 &   ' with LibXML library'
2923 #else
2924    write(message,'(3a)')'-Reading the file ',trim(filename),&
2925 &   ' with Fortran'
2926 #endif
2927    call wrtout(ab_out,message,'COLL')
2928    call wrtout(std_out,message,'COLL')
2929 
2930 
2931    ABI_MALLOC(symbols,(eff_pot%crystal%natom))
2932 !  Get the symbols arrays
2933    call symbols_crystal(eff_pot%crystal%natom,eff_pot%crystal%ntypat,&
2934 &                       eff_pot%crystal%npsp,symbols,eff_pot%crystal%typat,eff_pot%crystal%znucl)
2935 
2936 
2937  !Read with libxml librarie
2938 #if defined HAVE_XML
2939 
2940    ABI_MALLOC(terms,(ncoeff,nterm_max))
2941    ABI_MALLOC(atindx,(ncoeff,nterm_max,2,ndisp_max))
2942    ABI_MALLOC(coefficient,(ncoeff))
2943    ABI_MALLOC(cell,(ncoeff,nterm_max,3,2,ndisp_max))
2944    ABI_MALLOC(direction,(ncoeff,nterm_max,ndisp_max))
2945    ABI_MALLOC(strain,(ncoeff,nterm_max,ndisp_max))
2946    ABI_MALLOC(power_disp,(ncoeff,nterm_max,ndisp_max))
2947    ABI_MALLOC(power_strain,(ncoeff,nterm_max,ndisp_max))
2948    ABI_MALLOC(weight,(ncoeff,nterm_max))
2949 
2950 !  Read the values of this term with libxml
2951    call effpot_xml_readCoeff(char_f2c(trim(filename)),ncoeff,ndisp_max,nterm_max,&
2952 &                            coefficient,atindx,cell,direction,power_disp,power_strain,&
2953 &                            strain,weight)
2954 !  In the XML the atom index begin to zero
2955 !  Need to shift for fortran array
2956    atindx(:,:,:,:) = atindx(:,:,:,:) + 1
2957 
2958    do icoeff=1,ncoeff
2959      do iterm=1,nterm_max
2960 !      Initialisation of the polynomial_term structure with the values from the
2961        call polynomial_term_init(atindx(icoeff,iterm,:,:),cell(icoeff,iterm,:,:,:),&
2962 &                                direction(icoeff,iterm,:),ndisp_max,ndisp_max,terms(icoeff,iterm),&
2963 &                                power_disp(icoeff,iterm,:),power_strain(icoeff,iterm,:),&
2964 &                                strain(icoeff,iterm,:),weight(icoeff,iterm),check=.true.)
2965      end do
2966 !    Initialisation of the polynomial_coefficent structure with the values
2967      call polynomial_coeff_init(coefficient(icoeff),nterm_max,coeffs(icoeff),&
2968 &                               terms(icoeff,:),check=.true.)
2969 
2970 !    Get the name of this coefficient  and set it
2971 !    Try to find the index of the term corresponding to the interation in the
2972 !    reference cell (000) in order to compute the name correctly...
2973 !    If this coeff is not in the ref cell, take by default the first term
2974      if(coeffs(icoeff)%nterm > 0)then
2975        call polynomial_coeff_getName(name,coeffs(icoeff),symbols,recompute=.true.)
2976        call polynomial_coeff_setName(name,coeffs(icoeff))
2977      end if
2978 
2979 !    Free them all
2980      do iterm=1,nterm_max
2981        call polynomial_term_free(terms(icoeff,iterm))
2982      end do
2983    end do
2984 
2985 #else
2986    ABI_MALLOC(terms,(1,nterm_max))
2987    ABI_MALLOC(atindx,(1,1,2,ndisp_max))
2988    ABI_MALLOC(coefficient,(1))
2989    ABI_MALLOC(cell,(1,1,3,2,ndisp_max))
2990    ABI_MALLOC(direction,(1,1,ndisp_max))
2991    ABI_MALLOC(strain,(1,1,ndisp_max))
2992    ABI_MALLOC(power_disp,(1,1,ndisp_max))
2993    ABI_MALLOC(power_strain,(1,1,ndisp_max))
2994    ABI_MALLOC(weight,(1,1))
2995 !  Loop over the file
2996 !  Read the values of all the terms with fortran
2997    if (open_file(filename,message,unit=funit,form="formatted",&
2998 &              status="old",action="read") /= 0) then
2999      ABI_ERROR(message)
3000    end if
3001 
3002 !    Start a reading loop in fortran
3003      rewind(unit=funit)
3004      ios  = 0
3005      found=.false.
3006 
3007 !    Initialisation of counter
3008      icoeff  = 0
3009 
3010 !    Parser
3011      do while (ios==0)
3012        read(funit,'(a)',iostat=ios) readline
3013        if (ios == 0) then
3014          call rmtabfromline(readline)
3015          line=adjustl(readline)
3016          if ((line(1:12)==char(60)//'coefficient')) then
3017 !          Read headers of coefficient
3018            call rdfromline('text',line,strg)
3019            if (strg/="") then
3020              name=trim(strg)
3021            end if
3022            call rdfromline('value',line,strg)
3023            if (strg/="") then
3024              strg1=trim(strg)
3025              read(strg1,*) coefficient(1)
3026            else
3027              coefficient(1) = zero
3028            end if
3029 !          End read headers of coefficient
3030 !          Reset counter
3031            found  = .false.
3032            atindx = 0;  cell   = 0 ;  direction = 0
3033            strain = 0; power_strain = 0;  power_disp  = 0
3034            iterm   = 0
3035            idisp   = 0
3036            istrain = 0
3037            nterm   = 0
3038            do while (.not.found)
3039              read(funit,'(a)',iostat=ios) readline
3040              call rmtabfromline(readline)
3041              line=adjustl(readline)
3042              if ((line(1:13)==char(60)//'/coefficient')) then
3043                found= .true.
3044                cycle
3045              end if
3046              if ((line(1:5)==char(60)//'term')) then
3047                nterm = nterm + 1
3048                ndisp = 0
3049                nstrain = 0
3050                idisp = 0
3051                istrain = 0
3052                displacement = .true.
3053                call rdfromline('weight',line,strg)
3054                if (strg/="") then
3055                  strg1=trim(strg)
3056                  read(strg1,*) weight
3057                end if
3058                do while(displacement)
3059                  read(funit,'(a)',iostat=ios) readline
3060                  call rmtabfromline(readline)
3061                  line=adjustl(readline)
3062                  if ((line(1:6)==char(60)//'/term')) then
3063                    displacement = .false.
3064                  end if
3065                  if ((line(1:7)==char(60)//'strain')) then
3066                    nstrain = nstrain + 1
3067                    istrain = istrain + 1
3068                    call rdfromline('power',line,strg)
3069                    if (strg/="") then
3070                      strg1=trim(strg)
3071                      read(strg1,*) power_strain(1,1,istrain)
3072                    end if
3073                    call rdfromline('voigt',line,strg)
3074                    if (strg/="") then
3075                      strg1=trim(strg)
3076                      read(strg1,*) strain(1,1,istrain)
3077                    end if
3078                  end if
3079                  if ((line(1:18)==char(60)//'displacement_diff')) then
3080                    ndisp = ndisp + 1
3081                    idisp = idisp + 1
3082                    found2=.true.
3083                    call rdfromline('atom_a',line,strg)
3084                    if (strg/="") then
3085                      strg1=trim(strg)
3086                      read(strg1,*) atindx(1,1,1,idisp)
3087                    end if
3088                    call rdfromline('atom_b',line,strg)
3089                    if (strg/="") then
3090                      strg1=trim(strg)
3091                      read(strg1,*) atindx(1,1,2,idisp)
3092                    end if
3093                    call rdfromline('direction',line,strg)
3094                    if (strg/="") then
3095                      strg1=trim(strg)
3096                      if (trim(strg1).eq."x") direction(1,1,idisp) = 1
3097                      if (trim(strg1).eq."y") direction(1,1,idisp) = 2
3098                      if (trim(strg1).eq."z") direction(1,1,idisp) = 3
3099                    end if
3100                    call rdfromline('power',line,strg)
3101                    if (strg/="") then
3102                      strg1=trim(strg)
3103                      read(strg1,*) power_disp(1,1,idisp)
3104                    end if
3105                    do while(found2)
3106                      read(funit,'(a)',iostat=ios) readline
3107                      call rmtabfromline(readline)
3108                      line=adjustl(readline)
3109                      if ((line(1:7)==char(60)//'cell_a')) then
3110                        call rdfromline_value('cell_a',line,strg)
3111                        if (strg/="") then
3112                          strg1=trim(strg)
3113                          read(strg1,*) (cell(1,1,mu,1,idisp),mu=1,3)
3114                        else
3115                          read(funit,'(a)',iostat=ios) readline
3116                          call rmtabfromline(readline)
3117                          line=adjustl(readline)
3118                          call rdfromline_value('cell_a',line,strg)
3119                          if (strg/="") then
3120                            strg1=trim(strg)
3121                            read(strg1,*)(cell(1,1,mu,1,idisp),mu=1,3)
3122                          else
3123                            strg1=trim(line)
3124                            read(strg1,*)(cell(1,1,mu,1,idisp),mu=1,3)
3125                          end if
3126                        end  if
3127                      end if
3128                      if ((line(1:7)==char(60)//'cell_b')) then
3129                        call rdfromline_value('cell_b',line,strg)
3130                        if (strg/="") then
3131                          strg1=trim(strg)
3132                          read(strg1,*) (cell(1,1,mu,2,idisp),mu=1,3)
3133                        else
3134                          read(funit,'(a)',iostat=ios) readline
3135                          call rmtabfromline(readline)
3136                          line=adjustl(readline)
3137                          call rdfromline_value('cell_b',line,strg)
3138                          if (strg/="") then
3139                            strg1=trim(strg)
3140                            read(strg1,*)(cell(1,1,mu,2,idisp),mu=1,3)
3141                          else
3142                            strg1=trim(line)
3143                            read(strg1,*)(cell(1,1,mu,2,idisp),mu=1,3)
3144                          end if
3145                        end  if
3146                      end if
3147                      if ((line(1:19)==char(60)//'/displacement_diff')) then
3148                        found2=.false.
3149                      end if
3150                    end do
3151                  end if
3152                end do!end do while displacement
3153 !              In the XML the atom index begin to zero
3154 !              Need to shift for fortran array
3155                atindx(1,1,:,:) = atindx(1,1,:,:) + 1
3156 !              Initialisation of the polynomial_term structure with the values from the
3157 !              previous step
3158                iterm = iterm + 1
3159                call polynomial_term_init(atindx(1,1,:,:),cell(1,1,:,:,:),&
3160 &                                        direction(1,1,:),ndisp,nstrain,terms(1,iterm),&
3161 &                                        power_disp(1,1,:),power_strain(1,1,:),&
3162 &                                        strain(1,1,:),weight(1,1),check=.true.)
3163              end if!end if term
3164            end do!end do while found (coeff)
3165 
3166 !          Initialisation of the polynomial_coefficent structure with the values from the
3167 !          previous step
3168            icoeff = icoeff + 1
3169            call polynomial_coeff_init(coefficient(1),nterm,coeffs(icoeff),terms(1,:))
3170            call polynomial_coeff_getName(name,coeffs(icoeff),symbols,recompute=.true.)
3171            call polynomial_coeff_setName(name,coeffs(icoeff))
3172 !          Deallocation of the terms array for this coefficient
3173            do jj=1,nterm_max
3174              call polynomial_term_free(terms(1,jj))
3175            end do
3176          end if!end if line = coefficient
3177        end if!end if ios==0
3178      end do!end do while on file
3179 
3180      close(unit=funit)
3181 
3182 #endif
3183      ABI_FREE(terms)
3184      ABI_FREE(atindx)
3185      ABI_FREE(coefficient)
3186      ABI_FREE(cell)
3187      ABI_FREE(direction)
3188      ABI_FREE(strain)
3189      ABI_FREE(power_disp)
3190      ABI_FREE(power_strain)
3191      ABI_FREE(weight)
3192      ABI_FREE(symbols)
3193    end if !End if master
3194 
3195 !9-MPI BROADCAST
3196  do ii=1,ncoeff
3197    call polynomial_coeff_broadcast(coeffs(ii),master, comm)
3198  end do
3199 
3200 !10-checks
3201 
3202 !11-debug print
3203  debug = .FALSE.
3204  if(debug)then
3205    do ii=1,ncoeff
3206      do jj=1,coeffs(ii)%nterm
3207 #if defined HAVE_XML
3208        write(200+my_rank,*)"ii,jj,ndisp,nterm",ii,jj,coeffs(ii)%nterm,coeffs(ii)%terms(jj)%ndisp
3209        write(200+my_rank,*)"atindx",coeffs(ii)%terms(jj)%atindx
3210        write(200+my_rank,*)"cell1",coeffs(ii)%terms(jj)%cell(:,1,:)
3211        write(200+my_rank,*)"cell2",coeffs(ii)%terms(jj)%cell(:,2,:)
3212        write(200+my_rank,*)"direction",coeffs(ii)%terms(jj)%direction
3213        write(200+my_rank,*)"power_disp",coeffs(ii)%terms(jj)%power_disp
3214        write(200+my_rank,*)"weight",coeffs(ii)%terms(jj)%weight
3215 #else
3216        write(300+my_rank,*)"ii,jj,ndisp,nterm",ii,jj,coeffs(ii)%nterm,coeffs(ii)%terms(jj)%ndisp
3217        write(300+my_rank,*)"atindx",coeffs(ii)%terms(jj)%atindx
3218        write(300+my_rank,*)"cell1",coeffs(ii)%terms(jj)%cell(:,1,:)
3219        write(300+my_rank,*)"cell2",coeffs(ii)%terms(jj)%cell(:,2,:)
3220        write(300+my_rank,*)"direction",coeffs(ii)%terms(jj)%direction
3221        write(300+my_rank,*)"power_disp",coeffs(ii)%terms(jj)%power_disp
3222        write(300+my_rank,*)"weight",coeffs(ii)%terms(jj)%weight
3223 #endif
3224      end do
3225    end do
3226 #if defined HAVE_XML
3227    close(200+my_rank)
3228 #else
3229    close(300+my_rank)
3230 #endif
3231  end if
3232 
3233 !12-Initialisation of eff_pot
3234  call effective_potential_setCoeffs(coeffs,eff_pot,ncoeff)
3235 
3236 !13-Deallocation of type
3237  do ii=1,ncoeff
3238    call polynomial_coeff_free(coeffs(ii))
3239  end do
3240  ABI_FREE(coeffs)
3241 
3242 end subroutine coeffs_xml2effpot

m_effective_potential_file/effective_potential_file_getDimCoeff [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_getDimCoeff

FUNCTION

 This routine test the xml with polynomial coefficients
 Return the number of coefficients and the maximum number of displacement/strain

INPUTS

 filename = names of the files

OUTPUT

 ncoeff = number of coefficient for the polynome
 nterm(ncoeff) = number terms per coefficient
 ndisp(nterm,ncoeff) = number displacement per term

SOURCE

670 subroutine effective_potential_file_getDimCoeff(filename,ncoeff,ndisp_max,nterm_max)
671 
672 !Arguments ------------------------------------
673 !scalars
674  character(len=fnlen),intent(in) :: filename
675  integer,intent(out) :: ncoeff,ndisp_max,nterm_max
676 !Local variables-------------------------------
677  !scalar
678  integer ::  filetype
679 #ifndef HAVE_XML
680  integer ::  count,count2
681  integer :: funit = 1,ios=0
682  logical :: found,found2
683 #endif
684 !arrays
685 #ifndef HAVE_XML
686  character (len=XML_RECL) :: line,readline
687 #endif
688  character(len=500) :: message
689 
690 ! *************************************************************************
691 
692  call effective_potential_file_getType(filename,filetype)
693 
694  if (filetype==3 .or. filetype==23) then
695    write(message, '(2a)' )' Extraction of the number of coefficient in the XML ',&
696 &                         trim(filename)
697    call wrtout(std_out,message,'COLL')
698 
699    ncoeff = 0
700    nterm_max = 0
701    ndisp_max = 0
702 
703 #if defined HAVE_XML
704 !  Read with libxml the number of coefficient
705    call effpot_xml_getDimCoeff(char_f2c(trim(filename)),ncoeff,nterm_max,ndisp_max)
706 #else
707 !  Read by hand
708 !  Start a reading loop
709    found=.false.
710    ncoeff = 0
711 
712    if (open_file(filename,message,unit=funit,form="formatted",status="old",&
713 &                action="read") /= 0) then
714      ABI_ERROR(message)
715    end if
716 
717 !  First parse to know the number of coefficients
718    ios = 0
719    do while (ios == 0)
720      read(funit,'(a)',iostat=ios) readline
721      if(ios == 0)then
722        call rmtabfromline(readline)
723        line=adjustl(readline)
724 !      Need test with char(9) because the old version of XML file
725 !      from old script includes tarbulation at the begining of each line
726        if (line(1:12)==char(60)//'coefficient') then
727          ncoeff=ncoeff+1
728          count = 0
729          found = .false.
730          do while(.not.found)
731            read(funit,'(a)',iostat=ios) readline
732            call rmtabfromline(readline)
733            line=adjustl(readline)
734            if (line(1:5)==char(60)//'term') then
735              count = count +1
736              found2 = .false.
737              count2 = 0
738              do while(.not.found2)
739                read(funit,'(a)',iostat=ios) readline
740                call rmtabfromline(readline)
741                line=adjustl(readline)
742                if (line(1:13)==char(60)//'displacement') then
743                  count2 = count2 + 1
744                else if (line(1:7)==char(60)//'strain') then
745                  count2 = count2 + 1
746                else if (line(1:6)==char(60)//'/term') then
747                  if (count2 > ndisp_max) ndisp_max = count2
748                  found2 = .true.
749                else
750                  cycle
751                end if
752              end do
753            else  if (line(1:13)==char(60)//'/coefficient') then
754              if (count > nterm_max) nterm_max = count
755              found = .true.
756            else
757              cycle
758            end if
759          end do
760          cycle
761        end if
762      end if
763    end do
764 
765    close(funit)
766 #endif
767 
768  else
769 !  Maybe one day add an other type of file...
770    write(message, '(a,a,a,a)' )&
771 &   ' The file ',trim(filename),' is not compatible with multibinit',ch10
772    ABI_ERROR(message)
773  end if
774 
775 ! Do some checks
776  if (ncoeff < 1) then
777    write(message, '(5a)' )&
778 &   ' Unable to read the number of coeff from ',trim(filename),ch10,&
779 &   ' This file is not compatible with multibinit',ch10
780    ABI_ERROR(message)
781  end if
782 
783 end subroutine effective_potential_file_getDimCoeff

m_effective_potential_file/effective_potential_file_getDimMD [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_getDimMD

FUNCTION

 Read MD FILE (HIST or ASCII) and return the dimensions
 (natom and nstep)

INPUTS

 filename = path of the file

OUTPUT

 natom = number of atoms
 nstep = number of MD steps

SOURCE

 899 subroutine effective_potential_file_getDimMD(filename,natom,nstep)
 900 
 901 !Arguments ------------------------------------
 902 !scalars
 903  integer,intent(out) :: natom,nstep
 904 !arrays
 905  character(len=fnlen),intent(in) :: filename
 906 !Local variables-------------------------------
 907 !scalar
 908  integer :: ia,natm_old,natm_new
 909  integer :: nenergy,nrprimd
 910  integer :: ios=0,ios2=0,ios3=0
 911  integer :: unit_md=24
 912  logical :: compatible,netcdf
 913 #if defined HAVE_NETCDF
 914  integer :: natom_id,time_id,xyz_id,six_id
 915  integer :: ncid,ncerr
 916  character(len=5) :: char_tmp
 917 #endif
 918 !arrays
 919  character (len=10000) :: readline,line
 920  character(len=500) :: msg
 921 
 922 ! *************************************************************************
 923 
 924  natom = 0
 925  nstep = 0
 926 !try to read netcdf
 927  netcdf = .false.
 928 #if defined HAVE_NETCDF
 929  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
 930  if(ncerr == NF90_NOERR) then
 931    netcdf = .TRUE.
 932    ncerr = nf90_inq_dimid(ncid,"natom",natom_id)
 933    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
 934    ncerr = nf90_inq_dimid(ncid,"xyz",xyz_id)
 935    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
 936    ncerr = nf90_inq_dimid(ncid,"time",time_id)
 937    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
 938    ncerr = nf90_inq_dimid(ncid,"six",six_id)
 939    if(ncerr /= NF90_NOERR)  netcdf = .FALSE.
 940    if(netcdf)then
 941      ncerr = nf90_inquire_dimension(ncid,natom_id,char_tmp,natom)
 942      NCF_CHECK_MSG(ncerr," inquire dimension ID for natom")
 943      ncerr = nf90_inquire_dimension(ncid,time_id,char_tmp,nstep)
 944      NCF_CHECK_MSG(ncerr," inquire dimension ID for time")
 945    end if
 946  end if
 947 #endif
 948 
 949  if(.not.netcdf) then
 950 !  try to read ASCII file...
 951    if (open_file(filename,msg,unit=unit_md,form="formatted",&
 952 &       status="old",action="read") /= 0) then
 953      ABI_ERROR(msg)
 954    end if
 955 
 956 !  Start a reading loop in fortran to get the dimension of the file
 957    rewind(unit=unit_md)
 958    ios = 0
 959    nstep   = 0
 960    nrprimd = 0
 961    natm_old= 0
 962    natm_new= 0
 963    nenergy = 0
 964    compatible = .TRUE.
 965 
 966    do while ((ios==0))
 967 !    special treatment of the first step
 968      if(nstep==0)then
 969        ios2 = 0
 970        do while ((ios2==0))
 971          read(unit_md,'(a)',iostat=ios) readline
 972          line=adjustl(readline)
 973          call elementfromline(line,ia)
 974          if (ia==1)then
 975            nstep = nstep + 1
 976            ios2 = 1
 977          end if
 978        end do
 979      end if
 980      read(unit_md,'(a)',iostat=ios) readline
 981      if(ios == 0)then
 982        line=adjustl(readline)
 983        call elementfromline(line,ia)
 984        if (ia==1)then
 985          nenergy = nenergy + 1
 986          nrprimd = 0
 987        else if(ia==3)then
 988          nrprimd = nrprimd + 1
 989        end if
 990        if(nrprimd == 3)then
 991          ios3 = 0
 992          natm_new = 0
 993          do while ((ios3==0))
 994            read(unit_md,'(a)',iostat=ios3) readline
 995            if(ios3==0)then
 996              line=adjustl(readline)
 997              call elementfromline(line,ia)
 998              if(ia==1)then
 999                if(nstep==1) then
1000                  natm_old = natm_new
1001                else
1002                  if(natm_old /= natm_new) compatible = .FALSE.
1003                end if
1004                ios3 = 1
1005                ios2 = 1
1006                nstep = nstep + 1
1007              end if
1008              if(ia==6)then
1009                natm_new = natm_new + 1
1010              end if
1011            end if!end if ios3
1012          end do
1013        end if ! end if nrprimd
1014      end if! end if os1
1015    end do
1016 
1017    natom = natm_new - 1
1018    if(nstep /= nenergy) compatible = .FALSE.
1019    if(natom <= 0) compatible = .FALSE.
1020    if(nstep <= 0) compatible = .FALSE.
1021 
1022    if(.not.compatible)then
1023      natom = 0
1024      nstep = 0
1025    end if
1026  end if! end if not netcdf
1027 
1028 end subroutine effective_potential_file_getDimMD

m_effective_potential_file/effective_potential_file_getDimStrainCoupling [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_getDimStrainCoupling

FUNCTION

 Return the number of nrpt for specific strain coupling from xml system file

INPUTS

 filename = names of the files
 voigt    = voigt notation of the strain

OUTPUT

 nrpt  = number of rpt points

SOURCE

804 subroutine effective_potential_file_getDimStrainCoupling(filename,nrpt,voigt)
805 
806 !Arguments ------------------------------------
807 !scalars
808  character(len=fnlen),intent(in) :: filename
809  integer,intent(in) :: voigt
810  integer,intent(out) :: nrpt
811 !Local variables-------------------------------
812  !scalar
813 #ifndef HAVE_XML
814  integer :: irpt,ivoigt
815  integer :: funit = 1,ios=0
816  logical :: found
817 #endif
818 !arrays
819 #ifndef HAVE_XML
820  character (len=XML_RECL) :: line,readline,strg,strg1
821  character(len=500) :: message
822 #endif
823 
824 ! *************************************************************************
825 
826    nrpt = 0
827 
828 #if defined HAVE_XML
829 !  Read with libxml the number of coefficient
830    call effpot_xml_getDimStrainCoupling(char_f2c(trim(filename)),nrpt,voigt)
831 #else
832 !  Read by hand
833 !  Start a reading loop
834    found=.false.
835 
836    if (open_file(filename,message,unit=funit,form="formatted",status="old",&
837 &                action="read") /= 0) then
838      ABI_ERROR(message)
839    end if
840 
841 !  First parse to know the number of atoms
842    do while (ios == 0.and.(.not.found))
843      read(funit,'(a)',iostat=ios) readline
844      if(ios == 0)then
845        call rmtabfromline(readline)
846        line=adjustl(readline)
847        if ((line(1:16)=='<strain_coupling')) then
848          read(funit,'(a)',iostat=ios) readline
849          call rdfromline("voigt",line,strg)
850          strg1=trim(strg)
851          read(strg1,*) ivoigt
852          if (ivoigt == voigt)then
853            irpt = 0
854            do while (.not.found)
855              read(funit,'(a)',iostat=ios) readline
856              call rmtabfromline(readline)
857              line=adjustl(readline)
858              if ((line(1:26)=='<correction_force_constant')) then
859                irpt = irpt + 1
860                cycle
861              end if
862              if ((line(1:17)=='</strain_coupling')) then
863                found = .TRUE.
864                nrpt = irpt
865                cycle
866              end if
867            end do
868          else
869            cycle
870          end if
871        end if
872      end if
873    end do
874 
875    close(funit)
876 #endif
877 
878 end subroutine effective_potential_file_getDimStrainCoupling

m_effective_potential_file/effective_potential_file_getDimSystem [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_getDimSystem

FUNCTION

 This routine test the xml or ddb file
 Return the number of atoms/ntypat in the unit cell from ddb and xml
 Return natom/ntypat/nqpt and nrpt if the file is XML file
 In case of DDB file, you have to run bigbx9 to get nrpt

INPUTS

 filename = names of the files
 comm = MPI communicator

OUTPUT

 natom = number of atoms
 ntypat= number of type of atoms
 nqpt  = number of q points
 nrpt  = number of rpt points

SOURCE

561 subroutine effective_potential_file_getDimSystem(filename,comm,natom,ntypat,nqpt,nrpt)
562 
563 !Arguments ------------------------------------
564 !scalars
565  character(len=fnlen),intent(in) :: filename
566  integer,intent(out) :: natom,ntypat,nqpt,nrpt
567  integer,intent(in) :: comm
568 !arrays
569 
570 !Local variables-------------------------------
571  !scalar
572  integer :: filetype
573 ! integer :: dimekb,lmnmax,mband,mtyp,msym,nblok,nkpt,usepaw
574  character(len=500) :: message
575  type(ddb_hdr_type) :: ddb_hdr
576 !arrays
577 ! *************************************************************************
578 
579  natom = 0
580  ntypat= 0
581  nqpt = 0
582  nrpt  = 0
583 
584  call effective_potential_file_getType(filename,filetype)
585 
586  if(filetype==1)then
587    write(message, '(6a)' )ch10,' The file ',trim(filename),ch10,&
588 &                  ' is DDB file (extraction of the number of atoms)',ch10
589    call wrtout(std_out,message,'COLL')
590 
591    write(message, '(8a)' )&
592 &   ' The file ',trim(filename),ch10,' is ddb file only the number of atoms is read,',&
593 &    'if you want to predic the number of cell (nrpt)',ch10,' use bigbx9 routines',ch10
594    call wrtout(std_out,message,'COLL')
595 
596    call ddb_hdr%open_read(filename,comm,dimonly=1)
597    natom = ddb_hdr%natom
598    ntypat = ddb_hdr%ntypat
599    call ddb_hdr%free()
600 
601 !  Must read some value to initialze  array (nprt for ifc)
602 !   call bigbx9(inp%brav,dummy_cell,0,1,inp%ngqpt,inp%nqshft,nrpt,ddb%rprim,dummy_rpt)
603 
604  else if (filetype==2 .or. filetype==23) then
605    write(message, '(5a)' )ch10,' The file ',trim(filename),&
606 &                ' is XML file (extraction of all information)'
607    call wrtout(std_out,message,'COLL')
608 
609    call system_getDimFromXML(filename,natom,ntypat,nqpt,nrpt)
610 
611  else
612    write(message, '(a,a,a,a)' )&
613 &   ' The file ',trim(filename),' is not compatible with multibinit',ch10
614    ABI_ERROR(message)
615  end if
616 
617 ! TODO hexu: temporarily disabled. Discuss with alex how to do this properly.
618 ! Do some checks
619 ! if (natom < 1) then
620 !   write(message, '(a,a,a,a,a)' )&
621 !&   ' Unable to read the number of atom from ',trim(filename),ch10,&
622 !&   'This file  is not compatible with multibinit',ch10
623 !   ABI_ERROR(message)
624 ! end if
625 !
626 ! if (filetype==2 .or. filetype==23) then
627 !
628 !   if (natom < 1) then
629 !     write(message, '(a,a,a)' )&
630 !&     ' Unable to read the number of atom from ',trim(filename),ch10
631 !     ABI_ERROR(message)
632 !   end if
633 !
634 !   if (nrpt < 1) then
635 !     write(message, '(a,a,a)' )&
636 !&     ' Unable to read the number of rpt points ',trim(filename),ch10
637 !     ABI_ERROR(message)
638 !   end if
639 !
640 !   if (ntypat < 1) then
641 !     write(message, '(a,a,a)' )&
642 !&     ' Unable to read the number of type of atoms ',trim(filename),ch10
643 !     ABI_ERROR(message)
644 !   end if
645 !
646 ! end if
647 
648 end subroutine effective_potential_file_getDimSystem

m_effective_potential_file/effective_potential_file_getType [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_getType

FUNCTION

 This routine test the xml or ddb file

INPUTS

 filename = names of the files

OUTPUT

 type_file  = 0 no type found
              1 DDB file
              2 XML file the system definition and harmonic part
              3 XML file with polynomial coefficients
             23 XML file with both system definition and polynomial coefficients
             40 NetCDF file with history of MD or snapshot
             41 ASCII file with history of MD or snapshot

SOURCE

427 subroutine effective_potential_file_getType(filename,filetype)
428 
429 !Arguments ------------------------------------
430 !scalars
431  character(len=fnlen),intent(in) :: filename
432  integer, intent(out) :: filetype
433 !arrays
434 !Local variables-------------------------------
435 !scalar
436  integer :: natom,nstep
437  integer :: ddbun = 666,ios=0
438  character(len=500) :: message
439  character (len=1000) :: line,readline
440 #if defined HAVE_NETCDF
441  integer :: natom_id,time_id,xyz_id,six_id,ddb_version
442  integer :: ncid,ncerr
443  logical :: md_file
444 #endif
445 
446 !arrays
447 ! *************************************************************************
448 
449  filetype = 0
450 
451  ddbun = get_unit()
452 
453  if (open_file(filename,message,unit=ddbun,form="formatted",status="old",action="read") /= 0) then
454    ABI_ERROR(message)
455  end if
456 
457 !Check if the file is a XML file or a DDB and in this case, store the DDB code.
458  ios = 0
459  do while ((ios==0))
460    read(ddbun,'(a)',iostat=ios) readline
461    call rmtabfromline(readline)
462    line=adjustl(readline)
463    if(line(3:13)=="xml version") then
464      do while ((ios==0))
465        read(ddbun,'(a)',iostat=ios) readline
466        call rmtabfromline(readline)
467        line=adjustl(readline)
468        if(line(1:16)==char(60)//"Heff_definition".or.&
469 &         line(1:17)==char(60)//"Terms_definition")then
470          filetype = 3
471          ios = -1
472        end if
473        if(line(1:18)==char(60)//"System_definition") then
474          filetype = 2
475          do while ((ios==0))
476            read(ddbun,'(a)',iostat=ios) readline
477            call rmtabfromline(readline)
478            line=adjustl(readline)
479            if(line(1:16)==char(60)//"Heff_definition".or.&
480 &             line(1:17)==char(60)//"Terms_definition")then
481              filetype = 23
482              ios = -1
483            end if
484          end do
485        end if
486      end do
487    else  if(line(6:24)=="DERIVATIVE DATABASE") then
488      filetype = 1
489      ios = -1
490    end if
491  end do
492  close(ddbun)
493 
494  if(filetype/=0) return
495 
496 !try to read netcdf HIST file
497 #if defined HAVE_NETCDF
498  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
499  if(ncerr == NF90_NOERR) then
500    md_file = .TRUE.
501    ncerr = nf90_inq_dimid(ncid,"natom",natom_id)
502    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
503    ncerr = nf90_inq_dimid(ncid,"xyz",xyz_id)
504    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
505    ncerr = nf90_inq_dimid(ncid,"time",time_id)
506    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
507    ncerr = nf90_inq_dimid(ncid,"six",six_id)
508    if(ncerr /= NF90_NOERR)  md_file = .FALSE.
509    if (md_file) then
510      filetype = 40
511      return
512    end if
513  end if
514  ncerr = nf90_close(ncid)
515 #endif
516 
517  if(filetype/=0) return
518 
519 ! Try to read netcdf DDB file
520 #if defined HAVE_NETCDF
521  ncerr=nf90_open(path=trim(filename),mode=NF90_NOWRITE,ncid=ncid)
522  if(ncerr==NF90_NOERR) then
523    ncerr = nf90_get_var(ncid, nctk_idname(ncid, 'ddb_version'), ddb_version)
524    if (ncerr==NF90_NOERR) then
525      filetype = 1
526      return
527    end if
528  end if
529 #endif
530 
531 !Try to get the dim of MD ASCII file
532  call effective_potential_file_getDimMD(filename,natom,nstep)
533  if(natom /= 0 .and. nstep/=0) filetype = 41
534 
535 end subroutine effective_potential_file_getType

m_effective_potential_file/effective_potential_file_mapHistToRef [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_mapHistToRef

FUNCTION

 Generate the supercell in the effective potential according to the size of the
 supercell in the hist file
 Check if the hist file match to reference supercell in the effective potential
 If not, the hist file is reordering

INPUTS

 eff_pot<type(effective_potential)> = effective potential
 hist<type(abihist)> = The history of the MD
 comm = MPI communicator

OUTPUT

 hist<type(abihist)> = The history of the MD

SOURCE

3372 subroutine effective_potential_file_mapHistToRef(eff_pot,hist,comm,iatfix,verbose,sc_size)
3373 
3374 !Arguments ------------------------------------
3375 !scalars
3376  integer,intent(in) :: comm
3377  logical,optional,intent(in) :: verbose
3378 !arrays
3379  type(effective_potential_type),intent(inout) :: eff_pot
3380  type(abihist),intent(inout) :: hist
3381  integer,optional,allocatable,intent(inout) :: iatfix(:,:)
3382  integer,optional,intent(in) :: sc_size(3)
3383 !Local variables-------------------------------
3384 !scalar
3385  integer :: factE_hist,ia,ib,ii,jj,natom_hist,ncells,nstep_hist
3386  real(dp):: factor,ratio
3387  logical :: revelant_factor,need_map,need_verbose,need_fixmap
3388 !arrays
3389  real(dp) :: rprimd_hist(3,3),rprimd_ref(3,3)
3390  integer :: ncell(3),scale_cell(3)
3391  integer,allocatable  :: shift(:,:),iatfix_tmp(:,:)
3392  integer,allocatable  :: list_map(:) !blkval(:),
3393  real(dp),allocatable :: xred_ref(:,:) ! xred_hist(:,:),
3394  real(dp),allocatable :: list_dist(:),list_reddist(:,:),list_absdist(:,:)
3395  character(len=500) :: msg
3396  type(abihist) :: hist_tmp
3397 ! *************************************************************************
3398 
3399 !Set optional values
3400  need_verbose = .false.
3401  need_fixmap = .FALSE.
3402  if (present(verbose)) need_verbose = verbose
3403  if (present(iatfix)) need_fixmap = .TRUE.
3404 
3405  natom_hist = size(hist%xred,2)
3406  nstep_hist = size(hist%xred,3)
3407 
3408 ! Try to set the supercell according to the hist file
3409  rprimd_ref(:,:)  = eff_pot%crystal%rprimd
3410  rprimd_hist(:,:) = hist%rprimd(:,:,1)
3411 
3412  if(present(sc_size))then
3413     ncell(:) = sc_size
3414  else
3415     do ia=1,3
3416       scale_cell(:) = 0
3417       do ii=1,3
3418         if(abs(rprimd_ref(ii,ia)) > tol10)then
3419           scale_cell(ii) = nint(rprimd_hist(ii,ia) / rprimd_ref(ii,ia))
3420         end if
3421       end do
3422 !     Check if the factor for the supercell is revelant
3423       revelant_factor = .TRUE.
3424       do ii=1,3
3425         if(abs(scale_cell(ii)) < tol10) cycle
3426         factor = abs(scale_cell(ii))
3427         do jj=ii,3
3428           if(abs(scale_cell(jj)) < tol10) cycle
3429           if(abs(abs(scale_cell(ii))-abs(scale_cell(jj))) > tol10) revelant_factor = .FALSE.
3430         end do
3431       end do
3432       if(.not.revelant_factor)then
3433         write(msg, '(3a)' )&
3434 &            'unable to map the hist file ',ch10,&
3435 &            'Action: check/change your MD file'
3436         ABI_ERROR(msg)
3437       else
3438         ncell(ia) = int(factor)
3439       end if
3440     end do
3441  end if
3442 
3443  ncells = product(ncell)
3444 
3445 !Check if the energy stored in the hist is revelant, sometimes some MD files gives
3446 !the energy of the unit cell... This is not suppose to happen... But just in case...
3447  do ii=1,nstep_hist
3448    if(abs(eff_pot%energy)>tol12)then
3449      ratio=hist%etot(ii) / eff_pot%energy
3450      if(abs(ratio)<real(huge(factE_hist))*half)then
3451        factE_hist = nint(ratio)
3452        if(factE_hist == 1) then
3453 !      In this case we mutiply the energy of the hist by the number of cell
3454          hist%etot(ii) = hist%etot(ii)  * ncells
3455        end if
3456        if(factE_hist /=1 .and. factE_hist /= ncells)then
3457          write(msg, '(4a,I0,a,I0,2a,I0,3a,I0,3a)' )ch10,&
3458 &            ' --- !WARNING',ch10,&
3459 &            '     The energy of the history step ',ii,' seems to be with multiplicity of ',factE_hist,ch10,&
3460 &            '     However, the multiplicity of the cell is ',ncells,'.',ch10,&
3461 &            '     Please check the energy of the step ',ii,ch10,&
3462 &            ' ---',ch10
3463          if(need_verbose) call wrtout(std_out,msg,'COLL')
3464        endif
3465      else
3466        write(msg, '(4a,i0,3a,es16.6,5a)' )ch10,&
3467 &          ' --- !WARNING',ch10,&
3468 &          '     The energy of the history step ',ii,' is apparently not initialized.',ch10,&
3469 &          '     Its current value is',hist%etot(ii),ch10,&
3470 &          '     This does not allow to perform checking on the multiplicity of the cell ',ch10,&
3471 &          ' ---',ch10
3472        if(need_verbose) call wrtout(std_out,msg,'COLL')
3473      end if
3474    end if
3475  end do
3476 
3477 
3478 !Set the new supercell datatype into the effective potential reference
3479  call effective_potential_setSupercell(eff_pot,comm,ncell)
3480 
3481 !allocation
3482  ABI_MALLOC(shift,(3,natom_hist))
3483  ABI_MALLOC(list_map,(natom_hist))
3484  ABI_MALLOC(list_reddist,(3,natom_hist))
3485  ABI_MALLOC(list_absdist,(3,natom_hist))
3486  ABI_MALLOC(list_dist,(natom_hist))
3487  ABI_MALLOC(xred_ref,(3,natom_hist))
3488 
3489  !Putting maping list to zero
3490  list_map = 0
3491 
3492  !Fill xcart_ref/hist and xred_ref/hist
3493 
3494  call xcart2xred(eff_pot%supercell%natom,eff_pot%supercell%rprimd,&
3495 &                eff_pot%supercell%xcart,xred_ref)                   ! Get xred_ref
3496 
3497 
3498 do ia=1,natom_hist !Loop over all reference atoms
3499    ! Put temporary lists to zero
3500    list_reddist = 0
3501    list_absdist = 0
3502    list_dist = 0
3503    shift = 0
3504    do ib=1,natom_hist !Loop over all atoms of distorted structure
3505       !Calculate list of reduced distance between reference atom ia and all others
3506       list_reddist(:,ib) = hist%xred(:,ib,1) - xred_ref(:,ia)
3507       !If the distorted atom is further away than half the unit cell shift it.
3508       if(list_reddist(1,ib) > 0.5)then
3509          list_reddist(1,ib) = 1 -  list_reddist(1,ib)
3510          shift(1,ib) = -1
3511       end if
3512       if(list_reddist(2,ib) > 0.5)then
3513          list_reddist(2,ib) = 1 -  list_reddist(2,ib)
3514          shift(2,ib) = -1
3515       end if
3516       if(list_reddist(3,ib) > 0.5)then
3517          list_reddist(3,ib) = 1 -  list_reddist(3,ib)
3518          shift(3,ib) = -1
3519       end if
3520       if(list_reddist(1,ib) < -0.5)then
3521          list_reddist(1,ib) = -1 -  list_reddist(1,ib)
3522          shift(1,ib) = 1
3523       end if
3524       if(list_reddist(2,ib) < -0.5)then
3525          list_reddist(2,ib) = -1 -  list_reddist(2,ib)
3526          shift(2,ib) = 1
3527       end if
3528       if(list_reddist(3,ib) < -0.5)then
3529          list_reddist(3,ib) = -1 -  list_reddist(3,ib)
3530          shift(3,ib) = 1
3531       end if
3532       list_absdist(1,ib) = (rprimd_hist(1,1)+rprimd_hist(2,1)+rprimd_hist(3,1))*list_reddist(1,ib)
3533       list_absdist(2,ib) = (rprimd_hist(1,2)+rprimd_hist(2,2)+rprimd_hist(3,2))*list_reddist(2,ib)
3534       list_absdist(3,ib) = (rprimd_hist(1,3)+rprimd_hist(2,3)+rprimd_hist(3,3))*list_reddist(3,ib)
3535       list_dist(ib) = sqrt(abs(list_absdist(1,ib))**2 + abs(list_absdist(2,ib))**2 + abs(list_absdist(3,ib))**2 )
3536    end do !ib
3537    !find the closest atom ib
3538    list_map(ia) = minloc(list_dist,DIM=1)
3539    !If the closest atom ib was shifted, apply and store the shift
3540    if(any(shift(:,list_map(ia)) /= 0))then
3541       hist%xred(1,list_map(ia),:)= hist%xred(1,list_map(ia),:) + 1*shift(1,list_map(ia))
3542       hist%xred(2,list_map(ia),:)= hist%xred(2,list_map(ia),:) + 1*shift(2,list_map(ia))
3543       hist%xred(3,list_map(ia),:)= hist%xred(3,list_map(ia),:) + 1*shift(3,list_map(ia))
3544    end if
3545    !TEST MS
3546    !write(*,*) 'Atom', ia,' of reference is matche with', list_map(ia)
3547    !write(*,*) 'xred_ref(',xred_ref(:,ia),'), xred_hist(',hist%(:,list_map(ia)),')'
3548 end do  ! ia
3549 
3550  if(need_verbose) then
3551    write(msg,'(2a,I3,a,I3,a,I3)') ch10,&
3552 &       ' The size of the supercell for the fit is ',ncell(1),' ',ncell(2),' ',ncell(3)
3553    call wrtout(std_out,msg,'COLL')
3554    call wrtout(ab_out,msg,'COLL')
3555  end if
3556 
3557 
3558    if(any(list_map(:)==0))then
3559        write(msg, '(5a)' )&
3560 &         'Unable to map the molecular dynamic file  ',ch10,&
3561 &         'on the reference supercell structure',ch10,&
3562 &         'Action: change the MD file'
3563        ABI_ERROR(msg)
3564    end if
3565 
3566  need_map = .FALSE.
3567  do ia=1,natom_hist
3568    if(list_map(ia) /= ia) need_map = .TRUE.
3569  end do
3570  if(need_map)then
3571    if(need_verbose) then
3572      write(msg, '(11a)' )ch10,&
3573 &      ' --- !WARNING',ch10,&
3574 &      '     The ordering of the atoms in the _HIST.nc file is different,',ch10,&
3575 &      '     of the one built by multibinit. The _HIST.nc file will be mapped,',ch10,&
3576 &      '     to the ordering of multibinit.',ch10,&
3577 &      ' ---',ch10
3578      call wrtout(ab_out,msg,'COLL')
3579      call wrtout(std_out,msg,'COLL')
3580    end if
3581 
3582 ! Allocate hist datatype
3583    call abihist_init(hist_tmp,natom_hist,nstep_hist,.false.,.false.)
3584 ! copy all the information
3585    do ia=1,nstep_hist
3586      hist%ihist = ia
3587      hist_tmp%ihist = ia
3588      call abihist_copy(hist,hist_tmp)
3589    end do
3590    hist_tmp%mxhist = nstep_hist
3591 
3592 ! reoder array
3593    do ia=1,natom_hist
3594      hist_tmp%xred(:,ia,:)  = hist%xred(: ,list_map(ia),:)
3595      hist_tmp%fcart(:,ia,:) = hist%fcart(:,list_map(ia),:)
3596      hist_tmp%vel(:,ia,:)   = hist%vel(:,list_map(ia),:)
3597    end do
3598 
3599 ! free the old hist and reinit
3600    call abihist_free(hist)
3601    call abihist_init(hist,natom_hist,nstep_hist,.false.,.false.)
3602 ! copy the temporary hist into output
3603    do ia=1,nstep_hist
3604      hist%ihist = ia
3605      hist_tmp%ihist = ia
3606      call abihist_copy(hist_tmp,hist)
3607    end do
3608    hist_tmp%mxhist = nstep_hist
3609    call abihist_free(hist_tmp)
3610 
3611    !map also fixes if present
3612    if(need_fixmap)then
3613      ABI_MALLOC(iatfix_tmp,(3,natom_hist))
3614      do ia=1,natom_hist
3615         iatfix_tmp(:,ia) = iatfix(:,list_map(ia))
3616      end do
3617      iatfix = iatfix_tmp
3618      ABI_FREE(iatfix_tmp)
3619    end if
3620  end if !need map
3621 
3622 !deallocation
3623  ABI_FREE(shift)
3624  ABI_FREE(list_map)
3625  ABI_FREE(list_dist)
3626  ABI_FREE(list_reddist)
3627  ABI_FREE(list_absdist)
3628  ABI_FREE(xred_ref)
3629 end subroutine effective_potential_file_mapHistToRef

m_effective_potential_file/effective_potential_file_readMDfile [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 effective_potential_file_readMDfile

FUNCTION

 Read MD FILE (HIST or ASCII)

INPUTS

 filename = path of the file
 option,optional   = 0 (default), the stress is printed in the MD File
                     1, the force on the cell is printed in the MD File (-1 * stress),
                        in this case, we multiply the stress by -1 in order to get the stresse

OUTPUT

 hist<type(abihist)> = datatype with the  history of the MD

SOURCE

3264 subroutine effective_potential_file_readMDfile(filename,hist,option)
3265 
3266 !Arguments ------------------------------------
3267 !scalars
3268  integer,optional :: option
3269 !arrays
3270  type(abihist),intent(inout) :: hist
3271  character(len=fnlen),intent(in) :: filename
3272 !Local variables-------------------------------
3273 !scalar
3274  integer :: ia,ii,mu,nu,natom,nstep,type,option_in
3275  integer :: ios=0, unit_md=24
3276 !arrays
3277  character (len=10000) :: readline,line
3278  real(dp) :: tmp(6)
3279  real(dp),allocatable :: xcart(:,:)
3280 
3281 ! *************************************************************************
3282 
3283  call effective_potential_file_getType(filename,type)
3284 
3285  option_in = 0
3286  if(present(option))then
3287    option_in = option
3288  end if
3289  if(type==40)then
3290 !  Netcdf type
3291    call read_md_hist(filename,hist,.FALSE.,.FALSE.,.FALSE.)
3292 
3293  else if(type==41)then
3294 
3295 !  ASCII file
3296    call  effective_potential_file_getDimMD(filename,natom,nstep)
3297 
3298    ii  = 1
3299    ios = 0
3300 
3301    ABI_MALLOC(xcart,(3,natom))
3302    call abihist_free(hist)
3303    call abihist_init(hist,natom,nstep,.FALSE.,.FALSE.)
3304 
3305 !  Start a reading loop in fortran
3306    rewind(unit=unit_md)
3307    do while ((ios==0).and.ii<=nstep)
3308      read(unit_md,'(a)',iostat=ios) readline
3309      read(unit_md,'(a)',iostat=ios) readline
3310      line=adjustl(readline)
3311      read(line,*) hist%etot(ii)
3312      hist%etot(ii) = hist%etot(ii)
3313      do mu=1,3
3314        read(unit_md,'(a)',iostat=ios) readline
3315        line=adjustl(readline)
3316        read(line,*) (hist%rprimd(nu,mu,ii),nu=1,3)
3317      end do
3318      do ia=1,natom
3319        read(unit_md,'(a)',iostat=ios) readline
3320        line=adjustl(readline)
3321        read(line,*) (tmp(mu),mu=1,6)
3322        xcart(:,ia) = tmp(1:3)
3323        hist%fcart(:,ia,ii) = tmp(4:6)
3324      end do
3325      call xcart2xred(natom,hist%rprimd(:,:,ii),xcart(:,:),hist%xred(:,:,ii))
3326      read(unit_md,'(a)',iostat=ios) readline
3327      line=adjustl(readline)
3328      read(line,*) (hist%strten(mu,ii),mu=1,6)
3329      ii = ii + 1
3330    end do
3331    do ii=1,nstep
3332      do mu=1,3
3333        hist%acell(mu,:) = hist%rprimd(mu,mu,ii)
3334      end do
3335    end do
3336    close(unit_md)
3337    ABI_FREE(xcart)
3338 
3339  end if!end if type
3340 
3341    if((type==40 .or. type==41).and.option == 1)then
3342 !    multiply by -1 if the current strten -1*stress, we need only stress...
3343      hist%strten(:,:) = -1 * hist%strten(:,:)
3344    end if
3345 
3346 
3347 
3348 end subroutine effective_potential_file_readMDfile

m_effective_potential_file/elementfromline [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 elementfromline

FUNCTION

 Read the number of element of a line

INPUTS

  line= string from which the data are read

OUTPUT

  nelement = number of element in the line

SOURCE

3708 subroutine elementfromline(line,nelement)
3709 
3710 !Arguments ---------------------------------------------
3711  character(len=*), intent(in) :: line
3712  integer, intent(out) :: nelement
3713 !Local variables ---------------------------------------
3714  integer :: ii,n
3715  logical :: element
3716 ! *********************************************************************
3717 
3718 !Set the output
3719  nelement = 0
3720  n = len_trim(line)
3721  element = .false.
3722  do ii=1,n
3723    if(.not.element.and.line(ii:ii) /="")  then
3724      element=.true.
3725    else
3726      if((element.and.line(ii:ii) =="")) then
3727        element=.false.
3728        nelement = nelement + 1
3729      end if
3730    end if
3731    if((element.and.ii==n)) nelement = nelement + 1
3732  end do
3733 
3734  end subroutine elementfromline

m_effective_potential_file/rdfromline [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 rdfromline

FUNCTION

 Read the value of a keyword from a XML line
 Same function than m_pawxmlps/paw_rdfromline.F90

INPUTS

  keyword= keyword which value has to be read
  line= string from which the data are read (line from a XML)

OUTPUT

  output= (string) value of the keyword

SOURCE

3754  subroutine rdfromline(keyword,line,output)
3755 
3756 !Arguments ---------------------------------------------
3757   character(len=*), intent(in) :: keyword,line
3758   character(len=*), intent(out) :: output
3759 !Local variables ---------------------------------------
3760   character(len=len(line)) :: temp
3761   integer :: pos,pos2
3762 
3763 ! *********************************************************************
3764 
3765  output=""
3766  pos=index(line,trim(keyword))
3767  if (pos>0) then
3768    temp=line(pos+len_trim(keyword):len_trim(line))
3769    pos=index(temp,char(34))
3770    if (pos>0) then
3771      pos2=index(temp(pos+1:len_trim(temp)),char(34))
3772      if (pos2>0) then
3773        output=temp(pos+1:pos+pos2-1)
3774      end if
3775    end if
3776  end if
3777 
3778  end subroutine rdfromline

m_effective_potential_file/rdfromline_value [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 rdfromline

FUNCTION

 Read the value of a keyword from a XML line

INPUTS

  keyword= keyword which value has to be read
  line= string from which the data are read (line from a XML)

OUTPUT

  output= (string) value of the keyword

SOURCE

3833  subroutine rdfromline_value(keyword,line,output)
3834 
3835 !Arguments ---------------------------------------------
3836   character(len=*), intent(in) :: keyword,line
3837   character(len=*), intent(out) :: output
3838 !Local variables ---------------------------------------
3839   character(len=len(line)) :: temp
3840   integer :: pos,pos2
3841 
3842 ! *********************************************************************
3843 
3844  output=""
3845  pos=index(line,trim(keyword))
3846  if (pos==2) then
3847    pos=pos+len_trim(keyword)
3848    pos=pos+index(line(pos:len_trim(line)),char(62))
3849    temp=line(pos:len_trim(line))
3850    pos2=index(temp,char(60))
3851    if (pos2>0) then
3852      output=line(pos:pos+pos2-2)
3853    else
3854      output=line(pos:len_trim(line))
3855    end if
3856  else
3857    if(pos>2)then
3858      output=line(1:pos-3)
3859    end if
3860  end if
3861 end subroutine rdfromline_value

m_effective_potential_file/rmtabfromline [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 rmtabfromline

FUNCTION

 Read remove tab from the begining of line

INPUTS

  line= string from which the data are read (line from a XML)

OUTPUT

  output= line without tab

SOURCE

3797 recursive subroutine rmtabfromline(line)
3798 
3799 !Arguments ---------------------------------------------
3800   character(len=*), intent(inout) :: line
3801 !Local variables ---------------------------------------
3802   integer :: pos
3803 
3804 ! *********************************************************************
3805 
3806  pos=index(line,char(9))
3807  if (pos==1) then
3808    line = line(2:len_trim(line))//" "
3809    call rmtabfromline(line)
3810  end if
3811 
3812  end subroutine rmtabfromline

m_effective_potential_file/system_ddb2effpot [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 system_ddb2effpot

FUNCTION

  Transfert ddb into effective potential structure.
  Also calculate the IFC

INPUTS

 crytal<type(crystal_t)> = datatype with all the information for the crystal
 ddb<type(ddb_type)> = datatype with the ddb
 inp<type(multibinit_dtset_type)> = datatype with the input variables of multibinit
 comm = MPI communicator

OUTPUT

 effective_potantial<type(effective_potential_type)> = effective_potential datatype to be initialized

SOURCE

2162 subroutine system_ddb2effpot(crystal,ddb, effective_potential,inp,comm)
2163 
2164  use m_dynmat
2165 
2166  use m_copy,            only : alloc_copy
2167  use m_crystal,         only : crystal_t
2168  use m_multibinit_dataset, only : multibinit_dtset_type
2169 
2170 !Arguments ------------------------------------
2171 !scalars
2172  integer,intent(in) :: comm
2173 !arrays
2174  type(ddb_type),intent(inout) :: ddb
2175  type(effective_potential_type), intent(inout) :: effective_potential
2176  type(crystal_t),intent(in) :: crystal
2177  type(multibinit_dtset_type),intent(in) :: inp
2178 
2179 !Local variables-------------------------------
2180 !scalar
2181  real(dp):: wcount1,wcount2
2182  integer :: chneut,i1,i2,i3,ia,ib,iblok,idir1,idir2,ierr,ii,ipert1,iphl1
2183  integer :: ipert2,irpt,irpt2,ivarA,ivarB,max1,max2,max3,min1,min2,min3
2184  integer :: msize,mpert,natom,nblok,nrpt_new,nrpt_new2,rftyp,selectz
2185  integer :: my_rank,nproc,prt_internalstr
2186  logical :: iam_master
2187  integer,parameter :: master=0
2188  integer :: nptsym,nsym
2189  integer :: msym = 384,  use_inversion = 1, space_group
2190  real(dp):: max_phfq,tolsym = tol8
2191 !arrays
2192  integer :: bravais(11),cell_number(3),cell2(3)
2193  integer :: shift(3),rfelfd(4),rfphon(4),rfstrs(4)
2194  integer,allocatable :: cell_red(:,:)
2195  real(dp):: dielt(3,3),elast_clamped(6,6),fact
2196  real(dp):: red(3,3),qphnrm(3),qphon(3,3)
2197  real(dp),allocatable :: blkval(:,:,:,:,:,:),d2asr(:,:,:,:,:)
2198  real(dp),allocatable :: instrain(:,:),zeff(:,:,:),qdrp_cart(:,:,:,:)
2199  real(dp),pointer :: atmfrc_red(:,:,:,:,:),wghatm_red(:,:,:)
2200  character(len=500) :: message
2201  type(asrq0_t) :: asrq0
2202  type(ifc_type) :: ifc
2203  real(dp),allocatable :: d2cart(:,:,:,:,:),displ(:)
2204  real(dp),allocatable :: eigval(:,:),eigvec(:,:,:,:,:),phfrq(:)
2205  real(dp),allocatable :: spinat(:,:),tnons(:,:)
2206  integer,allocatable  :: symrel(:,:,:),symafm(:),ptsymrel(:,:,:)
2207 
2208 ! *************************************************************************
2209 
2210 !0 MPI variables
2211  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
2212  iam_master=.FALSE.
2213  iam_master = (my_rank == master)
2214 
2215 !Free the eff_pot before filling
2216  call effective_potential_free(effective_potential)
2217 
2218 !Initialisation of usefull values
2219   natom = ddb%natom
2220   nblok = ddb%nblok
2221   mpert= ddb%mpert
2222   msize=3*mpert*3*mpert;
2223 
2224 !Tranfert the ddb into usable array (ipert and idir format like in abinit)
2225   ABI_MALLOC(blkval,(2,3,mpert,3,mpert,nblok))
2226   blkval = 0
2227   blkval = reshape(ddb%val,(/2,3,mpert,3,mpert,nblok/))
2228 
2229 !**********************************************************************
2230 ! Transfert crystal values
2231 !**********************************************************************
2232 ! Re-generate symmetry operations from the lattice and atomic coordinates
2233   ABI_MALLOC(spinat,(3,natom))
2234   ABI_MALLOC(ptsymrel,(3,3,msym))
2235   ABI_MALLOC(symafm,(msym))
2236   ABI_MALLOC(symrel,(3,3,msym))
2237   ABI_MALLOC(tnons,(3,msym))
2238   spinat = zero;  symrel = 0;  symafm = 0;  tnons = zero ; space_group = 0;
2239   call symlatt(bravais,std_out,msym,nptsym,ptsymrel,crystal%rprimd,tolsym)
2240   call symfind(crystal%gprimd,msym,crystal%natom,nptsym,0,nsym,&
2241 &              0,ptsymrel,spinat,symafm,symrel,tnons,tolsym,&
2242 &              crystal%typat,use_inversion,crystal%xred)
2243   if(crystal%nsym/=nsym)then
2244     write(message,'(4a,I0,3a,I0,3a)') ch10,&
2245 &          ' --- !WARNING:',ch10,&
2246 &          '     There is ',nsym,' found for the crystal',ch10,&
2247 &          '     but ',crystal%nsym,' found in the DDB',ch10,&
2248 &          ' ---'
2249       call wrtout(std_out,message,'COLL')
2250   end if
2251   call crystal_init(ddb%amu,effective_potential%crystal,&
2252 &                   space_group,crystal%natom,crystal%npsp,&
2253 &                   crystal%ntypat,nsym,crystal%rprimd,&
2254 &                   crystal%typat,crystal%xred,crystal%zion,&
2255 &                   crystal%znucl,crystal%timrev,crystal%use_antiferro,&
2256 &                   .FALSE.,crystal%title,&
2257 &                   symrel=symrel,tnons=tnons,&
2258 &                   symafm=symafm)
2259 
2260   ABI_FREE(spinat)
2261   ABI_FREE(ptsymrel)
2262   ABI_FREE(symafm)
2263   ABI_FREE(symrel)
2264   ABI_FREE(tnons)
2265 
2266 !**********************************************************************
2267 ! Transfert energy from input file
2268 !**********************************************************************
2269   write(message, '(2a,(80a),6a)') ch10,('=',ii=1,80),ch10,ch10,&
2270 &     ' Extraction of the energy of the structure (unit: Hartree)',ch10
2271   call wrtout(std_out,message,'COLL')
2272   call wrtout(ab_out,message,'COLL')
2273   if (ddb%get_etotal(effective_potential%energy) == 0) then
2274     if(abs(inp%energy_reference) < tol16)then
2275       write(message,'(5a)')&
2276 &      ' Warning : Energy of the reference structure is not specify in',&
2277 &      ' the input file.',ch10,' Energy will set to zero',ch10
2278       call wrtout(std_out,message,'COLL')
2279       effective_potential%energy = zero
2280     else
2281       effective_potential%energy = inp%energy_reference
2282     end if
2283   else
2284     if(abs(inp%energy_reference) > tol16)then
2285       write(message,'(6a)')&
2286 &      ' Warning : Energy of the reference structure is specify in',&
2287 &      ' the input file.',ch10,' and in the DDB.',&
2288 &      ' The value of the energy is set with the value from the input file',ch10
2289       call wrtout(std_out,message,'COLL')
2290       effective_potential%energy = inp%energy_reference
2291     end if
2292   end if
2293   write(message,'(a,es25.12)') ' Energy  = ',&
2294 &                    effective_potential%energy
2295   call wrtout(std_out,message,'COLL')
2296   call wrtout(ab_out,message,'COLL')
2297 
2298 !**********************************************************************
2299 ! Dielectric Tensor and Effective Charges
2300 !**********************************************************************
2301   ABI_MALLOC(zeff,(3,3,natom))
2302   ABI_MALLOC(qdrp_cart,(3,3,3,natom))
2303   ABI_MALLOC(effective_potential%harmonics_terms%zeff,(3,3,natom))
2304 
2305   rftyp   = 1 ! Blocks obtained by a non-stationary formulation.
2306   chneut  = 1 ! The ASR for effective charges is imposed
2307   selectz = 0 ! No selection of some parts of the effective charge tensor
2308   iblok = ddb%get_dielt_zeff(crystal,rftyp,chneut,selectz,dielt,zeff)
2309   qdrp_cart = zero
2310   if (iblok /=0 .and. maxval(abs(dielt)) < 10000) then
2311     effective_potential%harmonics_terms%epsilon_inf = dielt
2312     effective_potential%harmonics_terms%zeff = zeff
2313   else
2314     effective_potential%harmonics_terms%epsilon_inf(1,1) = one
2315     effective_potential%harmonics_terms%epsilon_inf(2,2) = one
2316     effective_potential%harmonics_terms%epsilon_inf(3,3) = one
2317     effective_potential%harmonics_terms%zeff = zero
2318   end if
2319 
2320 !**********************************************************************
2321 ! Look after the blok no. that contains the stress tensor
2322 !**********************************************************************
2323   write(message, '(a,a,(80a),a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
2324 &   ' Extraction of the stress tensor (unit: GPa) and forces (unit: Ha/bohr)'
2325   call wrtout(std_out,message,'COLL')
2326   call wrtout(ab_out,message,'COLL')
2327 
2328   ABI_MALLOC(effective_potential%fcart,(3,natom))
2329   effective_potential%fcart = zero
2330   effective_potential%strten = zero
2331 
2332   qphon(:,1)=zero
2333   qphnrm(1)=zero
2334   rfphon(1:2)=0
2335   rfelfd(1:2)=0
2336   rfstrs(1:2)=0
2337   rftyp=4
2338 
2339   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
2340 
2341   if (iblok /=0) then
2342    if(any(abs(inp%strten_reference)>tol16))then
2343      write(message,'(10a)') ch10,&
2344 &          ' --- !WARNING:',ch10,&
2345 &          '     The stress tensor of the reference structure is specify in the',ch10,&
2346 &          '     input file and in the DDB. The value of the stress tensor is set',ch10,&
2347 &          '     with the value from the input file',ch10,&
2348 &          ' ---'
2349      call wrtout(std_out,message,'COLL')
2350      call wrtout(ab_out,message,'COLL')
2351      effective_potential%strten = inp%strten_reference
2352    else
2353 !    firts give the corect stress values store in hartree
2354 !    diagonal parts
2355      effective_potential%strten(1)=blkval(1,1,natom+3,1,1,iblok) *  crystal%ucvol
2356      effective_potential%strten(2)=blkval(1,2,natom+3,1,1,iblok) *  crystal%ucvol
2357      effective_potential%strten(3)=blkval(1,3,natom+3,1,1,iblok) *  crystal%ucvol
2358 !    the shear parts
2359      effective_potential%strten(4)=blkval(1,1,natom+4,1,1,iblok) *  crystal%ucvol
2360      effective_potential%strten(5)=blkval(1,2,natom+4,1,1,iblok) *  crystal%ucvol
2361      effective_potential%strten(6)=blkval(1,3,natom+4,1,1,iblok) *  crystal%ucvol
2362    end if
2363 !  Get forces
2364    effective_potential%fcart(:,1:natom) = blkval(1,:,1:natom,1,1,iblok)
2365  else
2366    if(all(abs(inp%strten_reference(:))<tol16))then
2367      write(message,'(8a)') ch10,&
2368 &          ' --- !WARNING:',ch10,&
2369 &          '     The stress tensor of the reference structure is not specify',ch10,&
2370 &          '     The stress tensor will be set to zero',ch10,&
2371 &          ' ---'
2372      call wrtout(std_out,message,'COLL')
2373      call wrtout(ab_out,message,'COLL')
2374      effective_potential%strten = zero
2375    else
2376      effective_potential%strten = inp%strten_reference
2377    end if
2378  end if
2379 
2380  if(any(abs(effective_potential%strten(:)) >tol16))then
2381    write(message, '(3a)' )ch10,&
2382 &   ' Cartesian components of forces (hartree/bohr)',ch10
2383    call wrtout(ab_out,message,'COLL')
2384    call wrtout(std_out,  message,'COLL')
2385    do ii = 1, natom
2386      write(message, '(I4,a,3(e16.8))' ) &
2387 &     ii,'   ',effective_potential%fcart(:,ii)
2388 
2389      call wrtout(ab_out,message,'COLL')
2390      call wrtout(std_out,  message,'COLL')
2391    end do
2392 
2393    write(message, '(a,a)' )ch10,&
2394 &   ' Cartesian components of stress tensor (hartree/bohr^3)'
2395    call wrtout(ab_out,message,'COLL')
2396    call wrtout(std_out,  message,'COLL')
2397    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
2398 &   '  sigma(1 1)=',effective_potential%strten(1) / crystal%ucvol,&
2399 &   '  sigma(3 2)=',effective_potential%strten(4) / crystal%ucvol
2400    call wrtout(ab_out,message,'COLL')
2401    call wrtout(std_out,  message,'COLL')
2402    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
2403 &   '  sigma(2 2)=',effective_potential%strten(2) / crystal%ucvol,&
2404 &   '  sigma(3 1)=',effective_potential%strten(5) / crystal%ucvol
2405    call wrtout(ab_out,message,'COLL')
2406    call wrtout(std_out,  message,'COLL')
2407    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
2408 &   '  sigma(3 3)=',effective_potential%strten(3) / crystal%ucvol,&
2409 &   '  sigma(2 1)=',effective_potential%strten(6) / crystal%ucvol
2410    call wrtout(ab_out,message,'COLL')
2411    call wrtout(std_out,  message,'COLL')
2412    write(message, '(a)' ) ' '
2413    call wrtout(ab_out,message,'COLL')
2414    call wrtout(std_out,  message,'COLL')
2415  end if
2416 
2417 !**********************************************************************
2418 ! Elastic tensors at Gamma Point
2419 !**********************************************************************
2420   write(message, '(a,a,(80a),a,a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
2421 &   ' Extraction of the clamped elastic tensor (unit:10^2GPa)',ch10
2422   call wrtout(std_out,message,'COLL')
2423   call wrtout(ab_out,message,'COLL')
2424 
2425 ! look after the blok no.iblok that contains the elastic tensor
2426   qphon(:,1)=zero
2427   qphnrm(1)=zero
2428   rfphon(1:2)=0
2429   rfelfd(1:2)=0
2430   rfstrs(1:2)=3 ! Need uniaxial  both stresses and  shear stresses
2431   rftyp=1 ! Blocks obtained by a non-stationary formulation.
2432 ! for both diagonal and shear parts
2433   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
2434 
2435   if (iblok /=0) then
2436 !   extraction of the elastic constants from the blkvals (GPa)
2437     do ivarA=1,6
2438       do ivarB=1,6
2439 !       because the elastic constant is 6*6,
2440 !       so we should judge if the idir is larger than 3
2441 !       or not
2442         if(ivarA>3) then
2443           idir1=ivarA-3
2444           ipert1=natom+4  !for the shear modulus
2445         else if(ivarA<=3) then
2446           idir1=ivarA
2447           ipert1=natom+3  !for the diagonal part
2448         end if
2449         if(ivarB>3) then
2450           idir2=ivarB-3
2451           ipert2=natom+4  !for the shear modulus
2452         else if(ivarB<=3) then
2453           idir2=ivarB
2454           ipert2=natom+3  !for the diagonal part
2455         end if
2456         elast_clamped(ivarA,ivarB) = blkval(1,idir1,ipert1,idir2,ipert2,iblok)
2457       end do
2458     end do
2459     fact=HaBohr3_GPa / crystal%ucvol
2460     do ivarA=1,6
2461       write(message,'(6f12.7)')elast_clamped(ivarA,1)*fact/100.00_dp,&
2462 &                              elast_clamped(ivarA,2)*fact/100.00_dp,&
2463 &                              elast_clamped(ivarA,3)*fact/100.00_dp,&
2464 &                              elast_clamped(ivarA,4)*fact/100.00_dp,&
2465 &                              elast_clamped(ivarA,5)*fact/100.00_dp,&
2466 &                              elast_clamped(ivarA,6)*fact/100.00_dp
2467     call wrtout(std_out,message,'COLL')
2468     call wrtout(ab_out,message,'COLL')
2469     end do
2470 
2471 !   Set the clamped tensor into the effective potentiel
2472     effective_potential%harmonics_terms%elastic_constants = elast_clamped
2473 
2474   else
2475 
2476     write(message,'(3a)')ch10,&
2477 &    ' Warning : Elastic Tensor is set to zero (not available in the DDB)'
2478     call wrtout(std_out,message,'COLL')
2479     call wrtout(ab_out,message,'COLL')
2480 
2481 !   Set the clamped tensor to zero into the effective potentiel (not available in the DDB)
2482     effective_potential%harmonics_terms%elastic_constants = zero
2483   end if
2484 
2485 !**********************************************************************
2486 !   Acoustic Sum Rule
2487 !***************************************************************************
2488 ! ASR-correction (d2asr) has to be determined here from the Dynamical matrix at Gamma.
2489   ABI_MALLOC(d2asr,(2,3,natom,3,natom))
2490 
2491   write(message, '(a,a,(80a),a,a,a,a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
2492 &   ' Calculation of acoustic sum rule',ch10
2493   call wrtout(std_out,message,'COLL')
2494   call wrtout(ab_out,message,'COLL')
2495 
2496 ! Find the Gamma block in the DDB (no need for E-field entries)
2497   qphon(:,1)=zero
2498   qphnrm(1)=zero
2499   rfphon(1:2)=1
2500   rfelfd(:)=0
2501   rfstrs(:)=0
2502   rftyp=inp%rfmeth
2503 
2504   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
2505 
2506   d2asr = zero
2507   if (iblok /=0) then
2508     call asria_calc(inp%asr,d2asr,ddb%val(:,:,iblok),ddb%mpert,ddb%natom)
2509   end if
2510 
2511   ! Acoustic Sum Rule
2512   ! In case the interatomic forces are not calculated, the
2513   ! ASR-correction (asrq0%d2asr) has to be determined here from the Dynamical matrix at Gamma.
2514   asrq0 = ddb%get_asrq0(inp%asr, inp%rfmeth, crystal%xcart)
2515 
2516 !**********************************************************************
2517 ! Interatomic Forces Calculation
2518 !**********************************************************************
2519 ! ifc to be calculated for interpolation
2520   write(message, '(a,a,(80a),a,a,a,a)' ) ch10,('=',ii=1,80),ch10,ch10,&
2521 &   ' Calculation of the interatomic forces from DDB',ch10
2522   call wrtout(std_out,message,'COLL')
2523   call wrtout(ab_out,message,'COLL')
2524 
2525   call ifc%init(crystal,ddb,inp%brav,inp%asr,inp%symdynmat,inp%dipdip,inp%rfmeth,&
2526 &   inp%ngqpt(1:3),inp%nqshft,inp%q1shft,dielt,effective_potential%harmonics_terms%zeff,qdrp_cart,&
2527 &   inp%nsphere,inp%rifcsph,inp%prtsrlr,inp%enunit,comm)
2528 
2529 !***************************************************************************
2530 ! Interpolation of the dynamical matrix for each qpoint from ifc
2531 !***************************************************************************
2532 
2533   ABI_MALLOC(d2cart,(2,3,mpert,3,mpert))
2534   ABI_MALLOC(displ,(2*3*natom*3*natom))
2535   ABI_MALLOC(eigval,(3,natom))
2536   ABI_MALLOC(eigvec,(2,3,natom,3,natom))
2537   ABI_MALLOC(phfrq,(3*natom))
2538 
2539   ABI_MALLOC(effective_potential%harmonics_terms%dynmat,(2,3,natom,3,natom,inp%nph1l))
2540   ABI_MALLOC(effective_potential%harmonics_terms%phfrq,(3*natom,inp%nph1l))
2541   ABI_MALLOC(effective_potential%harmonics_terms%qpoints,(3,inp%nph1l))
2542 
2543   write(message,'(a,(80a),3a)')ch10,('=',ii=1,80),ch10,ch10,&
2544 &     ' Calculation of dynamical matrix for each ph1l points '
2545   call wrtout(ab_out,message,'COLL')
2546   call wrtout(std_out,message,'COLL')
2547 
2548 !Transfer value in effective_potential structure
2549   effective_potential%harmonics_terms%nqpt         = inp%nph1l
2550   effective_potential%harmonics_terms%qpoints(:,:) = inp%qph1l(:,:)
2551 
2552 ! Store the highest frequency
2553   max_phfq = zero
2554 
2555   do iphl1=1,inp%nph1l
2556 
2557    ! Initialisation of the phonon wavevector
2558     qphon(:,1)=inp%qph1l(:,iphl1)
2559     if (inp%nph1l /= 0) qphnrm(1) = inp%qnrml1(iphl1)
2560 
2561     ! Get d2cart using the interatomic forces and the
2562     ! long-range coulomb interaction through Ewald summation
2563     call gtdyn9(ddb%acell,ifc%atmfrc,ifc%dielt,ifc%dipdip,ifc%dyewq0,d2cart,crystal%gmet,&
2564 &     ddb%gprim,mpert,natom,ifc%nrpt,qphnrm(1),qphon(:,1),crystal%rmet,ddb%rprim,ifc%rpt,&
2565 &     ifc%trans,crystal%ucvol,ifc%wghatm,crystal%xred,zeff,qdrp_cart,ifc%ewald_option,xmpi_comm_self)
2566 
2567     ! Calculation of the eigenvectors and eigenvalues of the dynamical matrix
2568     call dfpt_phfrq(ddb%amu,displ,d2cart,eigval,eigvec,crystal%indsym,&
2569 &     mpert,crystal%nsym,natom,crystal%nsym,crystal%ntypat,phfrq,qphnrm(1),qphon,&
2570 &     crystal%rprimd,inp%symdynmat,crystal%symrel,crystal%symafm,crystal%typat,crystal%ucvol)
2571 
2572     ! Write the phonon frequencies
2573     call dfpt_prtph(displ,inp%eivec,inp%enunit,ab_out,natom,phfrq,qphnrm(1),qphon)
2574 
2575 !   Store the highest frequency in cmm-1
2576     max_phfq = max(maxval(phfrq*Ha_cmm1),max_phfq)
2577 
2578     effective_potential%harmonics_terms%dynmat(:,:,:,:,:,iphl1) = d2cart(:,:,:natom,:,:natom)
2579     effective_potential%harmonics_terms%phfrq(:,iphl1) = phfrq(:) * Ha_cmm1
2580 
2581   end do
2582 
2583   write(message, '(2a,f15.7,a)' ) ch10,&
2584 &   ' The highest frequency found is ',max_phfq,' cm-1'
2585   call wrtout(std_out,message,'COLL')
2586 
2587   ABI_FREE(d2cart)
2588   ABI_FREE(displ)
2589   ABI_FREE(eigval)
2590   ABI_FREE(eigvec)
2591   ABI_FREE(phfrq)
2592 
2593 !**********************************************************************
2594 ! Transfert inter-atomic forces constants in reduced coordinates
2595 !**********************************************************************
2596 
2597 !Reorder cell from canonical coordinates to reduced coordinates (for multibinit)
2598 !store the number of ifc before rearrangement
2599 
2600 ! Store the sum of the weight of IFC for the final check
2601   wcount1 = 0
2602   do irpt=1,ifc%nrpt
2603     wcount1 = wcount1 + sum(ifc%wghatm(:,:,irpt))
2604   end do
2605 
2606 !Set the maximum and the miminum for the bound of the cell
2607   max1 = maxval(ifc%cell(1,:));  min1 = minval(ifc%cell(1,:))
2608   max2 = maxval(ifc%cell(2,:));  min2 = minval(ifc%cell(2,:))
2609   max3 = maxval(ifc%cell(3,:));  min3 = minval(ifc%cell(3,:))
2610   cell_number(1) = max1 - min1 + 1
2611   cell_number(2) = max2 - min2 + 1
2612   cell_number(3) = max3 - min3 + 1
2613 
2614 ! set the new number of cell, sometimes, in canonical coordinates,
2615 ! some cell are delete but they exist in reduced coordinates.
2616   nrpt_new = product(cell_number(:))
2617 
2618 ! Allocate temporary array
2619   ABI_MALLOC(atmfrc_red,(3,natom,3,natom,nrpt_new))
2620   ABI_MALLOC(wghatm_red,(natom,natom,nrpt_new))
2621   ABI_MALLOC(cell_red,(3,nrpt_new))
2622 
2623   wghatm_red(:,:,:) = zero
2624 
2625   if(iam_master)then
2626     do ia=1,natom
2627       do ib=1,natom
2628 
2629 !       Simple Lattice
2630         if (inp%brav==1) then
2631 !          In this case, it is better to work in reduced coordinates
2632 !          As rcan is in canonical coordinates, => multiplication by gprim
2633            do ii=1,3
2634              red(1,ii)=  ifc%rcan(1,ia)*ddb%gprim(1,ii) + &
2635  &                       ifc%rcan(2,ia)*ddb%gprim(2,ii) + &
2636  &                       ifc%rcan(3,ia)*ddb%gprim(3,ii)
2637              red(2,ii)=  ifc%rcan(1,ib)*ddb%gprim(1,ii) + &
2638                          ifc%rcan(2,ib)*ddb%gprim(2,ii) + &
2639  &                       ifc%rcan(3,ib)*ddb%gprim(3,ii)
2640            end do
2641          end if
2642 
2643 !       Get the shift of cell
2644         shift(:) = int(anint(red(2,:) - crystal%xred(:,ib)) - anint(red(1,:) - crystal%xred(:,ia)))
2645 
2646         do irpt=1,ifc%nrpt
2647 
2648           cell2(:)= int(ifc%cell(:,irpt) + shift(:))
2649 
2650 !         Use boundary condition to get the right cell
2651           if (cell2(1) < min1 .and. cell2(1) < max1) then
2652             cell2(1) = cell2(1) + cell_number(1)
2653           else if (cell2(1) > min1 .and. cell2(1) > max1) then
2654             cell2(1) = cell2(1) - cell_number(1)
2655           end if
2656 
2657           if (cell2(2) < min2 .and. cell2(2) < max2) then
2658             cell2(2) = cell2(2) + cell_number(2)
2659           else if (cell2(2) > min2 .and. cell2(2) > max2) then
2660             cell2(2) = cell2(2) - cell_number(2)
2661           end if
2662 
2663           if (cell2(3) < min3 .and. cell2(3) < max3) then
2664             cell2(3) = cell2(3) + cell_number(3)
2665           else if (cell2(3) > min3 .and. cell2(3) > max3) then
2666             cell2(3) = cell2(3) - cell_number(3)
2667           end if
2668 
2669            irpt2=1
2670            do i1=min1,max1
2671              do i2=min2,max2
2672                do i3=min3,max3
2673                  if (i1  ==  cell2(1)  .and.&
2674                      i2  ==  cell2(2)  .and.&
2675                      i3  ==  cell2(3)) then
2676                    wghatm_red(ia,ib,irpt2) =  ifc%wghatm(ia,ib,irpt)
2677                    atmfrc_red(:,ia,:,ib,irpt2) = ifc%atmfrc(:,ia,:,ib,irpt)
2678                    cell_red(1,irpt2) = i1
2679                    cell_red(2,irpt2) = i2
2680                    cell_red(3,irpt2) = i3
2681                  end if
2682                  irpt2 = irpt2 + 1
2683                end do
2684              end do
2685           end do
2686         end do
2687       end do
2688     end do
2689   end if
2690 
2691   call xmpi_bcast(atmfrc_red,master, comm, ierr)
2692   call xmpi_bcast(wghatm_red,master, comm, ierr)
2693   call xmpi_bcast(cell_red,master, comm, ierr)
2694 
2695 !  Copy ifc into effective potential
2696 ! !!Warning eff_pot%ifcs only contains atmfrc,short_atmfrc,ewald_atmfrc,,nrpt and cell!!
2697 ! rcan,ifc%rpt,wghatm and other quantities
2698 ! are not needed for effective potential!!!
2699   call ifc%free()
2700   call effective_potential%harmonics_terms%ifcs%free()
2701 
2702 ! Only conserve the necessary points in rpt
2703   nrpt_new2 = 0
2704   do irpt = 1, nrpt_new
2705     if (abs(sum(wghatm_red(:,:,irpt))) >tol16) then
2706       nrpt_new2 = nrpt_new2 + 1
2707     end if
2708   end do
2709 
2710 ! Set the new number of rpt
2711   effective_potential%harmonics_terms%ifcs%nrpt = nrpt_new2
2712 
2713 ! Allocation of the final arrays
2714   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%atmfrc,(3,natom,3,natom,nrpt_new2))
2715   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%short_atmfrc,(3,natom,3,natom,nrpt_new2))
2716   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%ewald_atmfrc,(3,natom,3,natom,nrpt_new2))
2717   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%cell,(3,nrpt_new2))
2718   ABI_MALLOC(effective_potential%harmonics_terms%ifcs%wghatm,(natom,natom,nrpt_new2))
2719 
2720   irpt2 = 0
2721   do irpt = 1,nrpt_new
2722     if (abs(sum(wghatm_red(:,:,irpt))) > tol16) then
2723       irpt2 = irpt2 + 1
2724 !     Apply weight on each R point
2725       do ia=1,effective_potential%crystal%natom
2726         do ib=1,effective_potential%crystal%natom
2727           atmfrc_red(:,ia,:,ib,irpt) = atmfrc_red(:,ia,:,ib,irpt)*wghatm_red(ia,ib,irpt)
2728         end do
2729       end do
2730       effective_potential%harmonics_terms%ifcs%cell(:,irpt2) = cell_red(:,irpt)
2731       effective_potential%harmonics_terms%ifcs%atmfrc(:,:,:,:,irpt2) = atmfrc_red(:,:,:,:,irpt)
2732       if (inp%dipdip == 1) then
2733         effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2)=&
2734 &                                                                     atmfrc_red(:,:,:,:,irpt)
2735       else
2736         effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2) = zero
2737       end if
2738       effective_potential%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt2)=atmfrc_red(:,:,:,:,irpt)
2739       effective_potential%harmonics_terms%ifcs%ewald_atmfrc(:,:,:,:,irpt2) = zero
2740       effective_potential%harmonics_terms%ifcs%wghatm(:,:,irpt2) =  wghatm_red(:,:,irpt)
2741     end if
2742   end do
2743 
2744 
2745   ABI_FREE(atmfrc_red)
2746   ABI_FREE(wghatm_red)
2747   ABI_FREE(cell_red)
2748 
2749 ! Final check
2750   wcount2 = 0
2751   do irpt = 1, effective_potential%harmonics_terms%ifcs%nrpt
2752     wcount2 = wcount2 + sum(effective_potential%harmonics_terms%ifcs%wghatm(:,:,irpt))
2753   end do
2754 
2755   if (abs(wcount1-wcount2)/(wcount1+wcount2)>tol8) then
2756     write(message,'(2a,es15.4,a,es15.4,a,es15.4)')'The total wghatm has changed',ch10,&
2757 &    wcount1,' before and ', wcount2, ' now, difference being ',wcount1-wcount2
2758     ABI_BUG(message)
2759   end if
2760 
2761 
2762 !**********************************************************************
2763 ! Internal strain tensors at Gamma point
2764 !**********************************************************************
2765   write(message, '(a,a,(80a),a,a,a)') ch10,('=',ii=1,80),ch10,ch10,&
2766 &   ' Calculation of the internal-strain  tensor'
2767   call wrtout(std_out,message,'COLL')
2768   call wrtout(ab_out,message,'COLL')
2769   ABI_MALLOC(instrain,(3*natom,6))
2770 ! looking after the no. of blok that contains the internal strain tensor
2771   qphon(:,1)=zero
2772   qphnrm(1)=zero
2773   rfphon(1:2)=0
2774   rfelfd(1:2)=0
2775   rfstrs(1:2)=3
2776   rftyp=1
2777   call ddb%get_block(iblok,qphon,qphnrm,rfphon,rfelfd,rfstrs,rftyp)
2778 
2779   ABI_MALLOC(effective_potential%harmonics_terms%strain_coupling,(6,3,natom))
2780   effective_potential%harmonics_terms%strain_coupling = zero
2781 
2782   if (iblok /=0) then
2783 
2784 !   then print the internal strain tensor (only the force one)
2785     prt_internalstr=1
2786     call ddb_internalstr(inp%asr,ddb%val,d2asr,iblok,instrain,&
2787 &                        ab_out,mpert,natom,nblok,prt_internalstr)
2788 
2789     do ipert1=1,6
2790       do ipert2=1,natom
2791         do idir2=1,3
2792           ii=3*(ipert2-1)+idir2
2793             effective_potential%harmonics_terms%strain_coupling(ipert1,idir2,ipert2)=&
2794 &                                                            (-1.0_dp)*instrain(ii,ipert1)
2795         end do
2796       end do
2797     end do
2798   else
2799     write(message,'(3a)')ch10,&
2800 &    ' Warning : Internal strain is set to zero (not available in the DDB)'
2801     call wrtout(std_out,message,'COLL')
2802     call wrtout(ab_out,message,'COLL')
2803   end if
2804 !-------------------------------------------------------------------------------------
2805 ! DEALLOCATION OF ARRAYS
2806   ABI_FREE(blkval)
2807   ABI_FREE(zeff)
2808   ABI_FREE(qdrp_cart)
2809   ABI_FREE(instrain)
2810   ABI_FREE(d2asr)
2811   call asrq0%free()
2812 
2813   write(message,'(a)')ch10
2814   call wrtout(std_out,message,'COLL')
2815   call wrtout(ab_out,message,'COLL')
2816 
2817 end subroutine system_ddb2effpot

m_effective_potential_file/system_getDimFromXML [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 system_getDimFromXML

FUNCTION

 Open xml file of effective potentiel, then reads the variables that
 must be known in order to dimension the arrays before complete reading

INPUTS

 character(len=*) filnam: name of input or output file

OUTPUT

 natom=number of atoms
 ntypat=number of atom types
 nrpt  =number of real space points used to integrate IFC

SOURCE

1050 subroutine system_getDimFromXML(filename,natom,ntypat,nph1l,nrpt)
1051 
1052  !Arguments ------------------------------------
1053  !scalars
1054   character(len=fnlen),intent(in) :: filename
1055   integer, intent(out) :: natom,ntypat,nph1l,nrpt
1056  !arrays
1057  !Local variables-------------------------------
1058  !scalar
1059   integer :: nrpt1,nrpt2
1060   real :: itypat
1061   character(len=500) :: message
1062 #ifndef HAVE_XML
1063   integer :: funit = 1,ios = 0
1064   integer :: iatom
1065   logical :: found
1066   character (len=XML_RECL) :: line,readline
1067   character (len=XML_RECL) :: strg,strg1
1068 #endif
1069   !arrays
1070 #ifndef HAVE_XML
1071   integer,allocatable :: typat(:)
1072 #endif
1073 
1074  ! *************************************************************************
1075 
1076 !Open the atomicdata XML file for reading
1077  write(message,'(5a)') ' system_getDimFromXML :',&
1078 &    '-Opening the file ',trim(filename),' to read dimensions',&
1079 &    ' (before initialisation)'
1080 
1081  call wrtout(std_out,message,'COLL')
1082 
1083  natom = 0
1084  ntypat= 0
1085  nph1l = 0
1086  nrpt  = 0
1087  nrpt1 = 0
1088  nrpt2 = 0
1089  itypat= 0
1090 
1091 !Open the atomicdata XML file for reading
1092 
1093 #if defined HAVE_XML
1094 !Read with libxml
1095  call effpot_xml_getDimSystem(char_f2c(trim(filename)),natom,ntypat,nph1l,nrpt1,nrpt2)
1096 #else
1097 !Read by hand
1098 
1099 !Start a reading loop
1100  found=.false.
1101 
1102  if (open_file(filename,message,unit=funit,form="formatted",status="old",&
1103 &              action="read") /= 0) then
1104    ABI_ERROR(message)
1105  end if
1106 
1107 !First parse to know the number of atoms
1108  do while ((ios==0).and.(.not.found))
1109    read(funit,'(a)',iostat=ios) readline
1110    if(ios ==0)then
1111      call rmtabfromline(readline)
1112      line=adjustl(readline)
1113 
1114 !Need test with char(9) because the old version of XML file
1115 !from old script includes tarbulation at the begining of each line
1116      if (line(1:5)==char(60)//'atom') then
1117        natom=natom+1
1118        cycle
1119      end if
1120 
1121      if (line(1:21)==char(60)//'local_force_constant') then
1122        nrpt1 = nrpt1+1
1123        cycle
1124      end if
1125 
1126      if (line(1:21)==char(60)//'total_force_constant') then
1127        nrpt2 = nrpt2+1
1128        cycle
1129      end if
1130 
1131      if (line(1:7)==char(60)//'qpoint') then
1132        nph1l =  nph1l+1
1133        cycle
1134      end if
1135    end if
1136  end do
1137 
1138 !second parse to get the number of typat
1139  ABI_MALLOC(typat,(natom))
1140  typat = 0
1141  iatom = 0
1142 
1143  rewind(funit)
1144 !Start a reading loop
1145  ios   = 0
1146  found = .false.
1147 
1148  do while ((ios==0).and.(.not.found))
1149    read(funit,'(a)',iostat=ios) readline
1150    if(ios == 0)then
1151      call rmtabfromline(readline)
1152      line=adjustl(readline)
1153 
1154      if (line(1:5)==char(60)//'atom') then
1155        iatom = iatom + 1
1156        call rdfromline("mass",line,strg)
1157        strg1=trim(strg)
1158        read(unit=strg1,fmt=*) itypat
1159        if (.not.any(typat==int(itypat))) then
1160          ntypat= ntypat+1
1161        end if
1162        typat(iatom) = int(itypat)
1163      end if
1164 
1165      if (line(1:6)==char(60)//'local') then
1166        found=.true.
1167      end if
1168    end if
1169  end do
1170 
1171  close(funit)
1172  ABI_FREE(typat)
1173 
1174 #endif
1175 
1176 !Check the RPT
1177  if (nrpt2/=nrpt1) then
1178    if(nrpt1> 0 .and. nrpt2== 0) then
1179      continue;
1180    else if (nrpt1==0.and.nrpt2>=0) then
1181      write(message, '(5a)' )ch10,&
1182 &   ' WARNING: the number of local IFC is set to 0  ',ch10,&
1183 &   '          Dipdip must be set to zero',ch10
1184      call wrtout(std_out,message,'COLL')
1185    else if (nrpt2 > nrpt1) then
1186      write(message, '(2a,I0,3a,I0,5a)' )ch10,&
1187 &   ' WARNING: the number of total IFC  (',nrpt2,') is not equal to the  ',ch10,&
1188 &   '          the number of short range IFC (',nrpt1,') in ',filename,ch10,&
1189 &   '          the missing ifc will be set to zero',ch10
1190      call wrtout(std_out,message,'COLL')
1191    else if(nrpt1>nrpt2)then
1192      write(message, '(2a,I0,3a,I0,5a)' )ch10,&
1193 &   ' The number of total IFC  (',nrpt2,') is inferior to  ',ch10,&
1194 &   ' the number of short range IFC (',nrpt1,') in ',filename,ch10,&
1195 &   ' This is not possible',ch10
1196      ABI_BUG(message)
1197    end if
1198  end if
1199 
1200 !nrpt is the max between local and total:
1201  nrpt = max(nrpt1,nrpt2)
1202 
1203 
1204 end subroutine system_getDimFromXML

m_effective_potential_file/system_xml2effpot [ Functions ]

[ Top ] [ m_effective_potential_file ] [ Functions ]

NAME

 system_xml2effpot

FUNCTION

 Open xml file of effective potentiel, then reads the variables
 and store them in effective potentential type

INPUTS

 eff_pot<type(effective_potential_type)> = datatype with all the information for effective potential
 comm=MPI communicator
 character(len=*) filnam: name of input or output file
 strcpling = optional,logical to disable the strcpling

OUTPUT

 eff_pot<type(effective_potential_type)> = datatype with all the information for effective potential

SOURCE

1226  subroutine system_xml2effpot(eff_pot,filename,comm,strcpling)
1227 
1228  use m_atomdata
1229  use m_multibinit_dataset, only : multibinit_dtset_type
1230  use m_ab7_symmetry
1231 
1232  !Arguments ------------------------------------
1233  !scalars
1234  character(len=*),intent(in) :: filename
1235  integer, intent(in) :: comm
1236  integer, optional,intent(in) :: strcpling
1237  !arrays
1238  type(effective_potential_type), intent(inout) :: eff_pot
1239 
1240  !Local variables-------------------------------
1241  !scalar
1242  integer :: ierr,ii,itypat,my_rank,msym,natom,ncoeff,nrpt,nrpt_scoupling
1243  integer :: ntypat,nph1l,nptsym,npsp,nproc,nsym,space_group,timrev,use_inversion,voigt
1244  real(dp):: energy,tolsym,ucvol
1245  character(len=500) :: message
1246  integer,parameter :: master=0
1247  logical :: has_anharmonics
1248  logical :: iam_master
1249 #ifndef HAVE_XML
1250  integer :: funit = 1,ios=0
1251  integer :: iatom,iamu,iph1l,irpt,irpt1,irpt2,irpt3,jj,mu,nu
1252  real(dp):: amu
1253  logical :: found,found2,short_range,total_range
1254  character (len=XML_RECL) :: line,readline
1255  character (len=XML_RECL) :: strg,strg1
1256  logical :: has_straincoupling
1257 #endif
1258  !arrays
1259  integer :: bravais(11)
1260  integer,allocatable :: typat(:)
1261  integer,allocatable  :: symrel(:,:,:),symafm(:),ptsymrel(:,:,:)
1262  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
1263  real(dp) :: elastic_constants(6,6),elastic3rd(6,6,6),epsilon_inf(3,3)
1264  real(dp),allocatable :: all_amu(:),cell_local(:,:),cell_total(:,:)
1265  real(dp),allocatable :: elastic_displacement(:,:,:,:),dynmat(:,:,:,:,:,:)
1266  real(dp),allocatable :: local_atmfrc(:,:,:,:,:),total_atmfrc(:,:,:,:,:)
1267  real(dp),allocatable :: spinat(:,:),strain_coupling(:,:,:),phfrq(:,:),qph1l(:,:),tnons(:,:)
1268  real(dp),allocatable :: xcart(:,:),xred(:,:),zeff(:,:,:),znucl(:),zion(:)
1269  character(len=132),allocatable :: title(:)
1270  type(ifc_type) :: ifcs
1271  type(ifc_type),dimension(:),allocatable :: phonon_strain
1272  type(crystal_t)  :: crystal
1273  type(atomdata_t) :: atom
1274 #ifdef HAVE_XML
1275  real(dp),allocatable :: phonon_strain_atmfrc(:,:,:,:,:)
1276  integer,allocatable  :: phonon_straincell(:,:)
1277 #endif
1278 #ifndef HAVE_XML
1279  real(dp),allocatable :: work2(:,:)
1280 #endif
1281 
1282 ! *************************************************************************
1283 
1284 
1285  !Open the atomicdata XML file for reading
1286  write(message,'(a,a)')'-Opening the file ',filename
1287 
1288  call wrtout(ab_out,message,'COLL')
1289  call wrtout(std_out,message,'COLL')
1290 
1291  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1292  iam_master = (my_rank == master)
1293 
1294 !Get Dimention of system and allocation/initialisation of array
1295  call effective_potential_file_getDimSystem(filename,comm,natom,ntypat,nph1l,nrpt)
1296  gmet= zero; gprimd = zero; rmet = zero; rprimd = zero
1297  elastic_constants = zero; epsilon_inf = zero; ncoeff = 0
1298  ABI_MALLOC(all_amu,(ntypat))
1299  ABI_MALLOC(cell_local,(3,nrpt))
1300  ABI_MALLOC(cell_total,(3,nrpt))
1301  ABI_MALLOC(elastic_displacement,(6,6,3,natom))
1302  ABI_MALLOC(ifcs%atmfrc,(3,natom,3,natom,nrpt))
1303  ABI_MALLOC(ifcs%cell,(3,nrpt))
1304  ABI_MALLOC(ifcs%short_atmfrc,(3,natom,3,natom,nrpt))
1305  ABI_MALLOC(ifcs%ewald_atmfrc,(3,natom,3,natom,nrpt))
1306  ABI_MALLOC(strain_coupling,(6,3,natom))
1307  ABI_MALLOC(total_atmfrc,(3,natom,3,natom,nrpt))
1308  ABI_MALLOC(local_atmfrc,(3,natom,3,natom,nrpt))
1309  ABI_MALLOC(dynmat,(2,3,natom,3,natom,nph1l))
1310  ABI_MALLOC(typat,(natom))
1311  ABI_MALLOC(phfrq,(3*natom,nph1l))
1312  ABI_MALLOC(qph1l,(3,nph1l))
1313  ABI_MALLOC(xcart,(3,natom))
1314  ABI_MALLOC(xred,(3,natom))
1315  ABI_MALLOC(zeff,(3,3,natom))
1316  ABI_MALLOC(zion,(ntypat))
1317  ABI_MALLOC(znucl,(ntypat))
1318 
1319  ABI_MALLOC(phonon_strain,(6))
1320  nrpt_scoupling = 0
1321  do ii = 1,6
1322 !  Get The size of the strainPhonon-coupling
1323    call effective_potential_file_getDimStrainCoupling(filename,nrpt_scoupling,ii-1)
1324    ABI_MALLOC(phonon_strain(ii)%atmfrc,(3,natom,3,natom,nrpt_scoupling))
1325    ABI_MALLOC(phonon_strain(ii)%cell,(3,nrpt_scoupling))
1326    phonon_strain(ii)%nrpt   = nrpt_scoupling
1327    phonon_strain(ii)%atmfrc = zero
1328    phonon_strain(ii)%cell   = 0
1329  end do
1330 
1331  all_amu(:) = zero
1332  dynmat(:,:,:,:,:,:)  = zero
1333  cell_local(:,:) = 99D99
1334  cell_total(:,:) = 99D99
1335  elastic3rd(:,:,:) = zero
1336  elastic_displacement(:,:,:,:) = zero
1337  ifcs%nrpt = nrpt
1338  ifcs%atmfrc(:,:,:,:,:)  = zero
1339  ifcs%cell(:,:)  = 0
1340  ifcs%ewald_atmfrc(:,:,:,:,:) = zero
1341  ifcs%short_atmfrc(:,:,:,:,:) = zero
1342  strain_coupling(:,:,:) = zero
1343  phfrq = zero
1344  qph1l = 0
1345  xcart = zero
1346  zeff  = zero
1347  znucl = zero
1348 
1349  if(iam_master)then
1350 !Open the atomicdata XML file for reading
1351 #if defined HAVE_XML
1352 
1353    write(message,'(a,a,a,a)')'-Reading the file ',trim(filename),&
1354 &   ' with LibXML library'
1355 
1356    call wrtout(ab_out,message,'COLL')
1357    call wrtout(std_out,message,'COLL')
1358 
1359 !  Read with libxml library
1360    call effpot_xml_readSystem(char_f2c(trim(filename)),natom,ntypat,nrpt,nph1l,all_amu,&
1361 &                       ifcs%atmfrc,ifcs%cell,dynmat,elastic_constants,energy,&
1362 &                       epsilon_inf,ifcs%ewald_atmfrc,phfrq,rprimd,qph1l,&
1363 &                       ifcs%short_atmfrc,typat,xcart,zeff)
1364 
1365 !  convert atomic mass unit to znucl
1366    do itypat=1,ntypat
1367      do ii=1,103
1368        call atomdata_from_znucl(atom,real(ii,dp))
1369        if (abs((real(atom%amu,sp)-real(all_amu(itypat),sp))&
1370 &         /real(all_amu(itypat),sp)*100)<0.1) then
1371          znucl(itypat) = atom%znucl
1372          exit
1373        end if
1374      end do
1375    end do
1376 
1377 !  Get the Phonon Strain coupling
1378    do voigt = 1,6
1379      nrpt_scoupling = phonon_strain(voigt)%nrpt
1380      ABI_MALLOC(phonon_straincell,(3,nrpt_scoupling))
1381      ABI_MALLOC(phonon_strain_atmfrc,(3,natom,3,natom,nrpt_scoupling))
1382 
1383 !      Get The value
1384        call effpot_xml_readStrainCoupling(char_f2c(trim(filename)),natom,nrpt_scoupling,(voigt-1),&
1385 &                                         elastic3rd(voigt,:,:),elastic_displacement(voigt,:,:,:),&
1386 &                                         strain_coupling(voigt,:,:),&
1387 &                                         phonon_strain_atmfrc,phonon_straincell)
1388 
1389 !      Check if the 3rd order strain_coupling is present
1390        has_anharmonics = .FALSE.
1391        if(any(elastic3rd>tol10).or.any(elastic_displacement>tol10)) has_anharmonics = .TRUE.
1392        phonon_strain(voigt)%atmfrc(:,:,:,:,:) = phonon_strain_atmfrc(:,:,:,:,:)
1393        phonon_strain(voigt)%cell(:,:)   = phonon_straincell(:,:)
1394        if(any(phonon_strain(voigt)%atmfrc > tol10)) has_anharmonics = .TRUE.
1395 
1396        ABI_FREE(phonon_straincell)
1397        ABI_FREE(phonon_strain_atmfrc)
1398    end do
1399 #else
1400 
1401 ! Read by hand
1402    write(message,'(a,a,a,a)')'-Reading the file ',trim(filename),&
1403 & ' with Fortran'
1404 
1405    call wrtout(ab_out,message,'COLL')
1406    call wrtout(std_out,message,'COLL')
1407 
1408    if (open_file(filename,message,unit=funit,form="formatted",&
1409 &               status="old",action="read") /= 0) then
1410      ABI_ERROR(message)
1411    end if
1412 
1413 !Start a reading loop in fortran
1414    rewind(unit=funit)
1415    found=.false.
1416 
1417    iatom  = 1
1418    iamu   = 1
1419    itypat = 1
1420    irpt   = 1
1421    irpt1  = 0
1422    irpt2  = 0
1423    iph1l  = 1
1424    amu    = zero
1425    short_range  = .false.
1426    total_range  = .false.
1427    has_straincoupling = .FALSE.
1428    do while ((ios==0).and.(.not.found))
1429      read(funit,'(a)',iostat=ios) readline
1430      if(ios == 0)then
1431        call rmtabfromline(readline)
1432        line=adjustl(readline)
1433        if (.not.has_straincoupling) then
1434 
1435          if ((line(1:7)=='<energy')) then
1436            call rdfromline_value('energy',line,strg)
1437            if (strg/="") then
1438              strg1=trim(strg)
1439              read(strg1,*) energy
1440            else
1441              read(funit,'(a)',iostat=ios) readline
1442              call rmtabfromline(readline)
1443              line=adjustl(readline)
1444              call rdfromline_value('energy',line,strg)
1445              if (strg/="") then
1446                strg1=trim(strg)
1447              else
1448                strg1=trim(line)
1449              end if
1450              read(strg1,*) energy
1451            end if
1452            cycle
1453          end if
1454 
1455          if ((line(1:10)=='<unit_cell')) then
1456            call rdfromline_value('unit_cell',line,strg)
1457            if (strg/="") then
1458              strg1=trim(strg)
1459              read(strg1,*) (rprimd(1,mu),mu=1,3)
1460              read(funit,*) (rprimd(2,mu),mu=1,3)
1461            else
1462              do nu=1,2
1463                read(funit,*) (rprimd(nu,mu),mu=1,3)
1464              end do
1465            end if
1466            read(funit,'(a)',iostat=ios) readline
1467            call rmtabfromline(readline)
1468            line=adjustl(readline)
1469            call rdfromline_value('unit_cell',line,strg)
1470            if (strg/="") then
1471              strg1=trim(strg)
1472            else
1473              strg1=trim(line)
1474            end if
1475            read(strg1,*) (rprimd(3,mu),mu=1,3)
1476            cycle
1477          end if
1478 
1479          if ((line(1:12)=='<epsilon_inf')) then
1480            call rdfromline_value('epsilon_inf',line,strg)
1481            if (strg/="") then
1482              strg1=trim(strg)
1483              read(strg1,*) (epsilon_inf(mu,1),mu=1,3)
1484              read(funit,*) (epsilon_inf(mu,2),mu=1,3)
1485            else
1486              do nu=1,2
1487                read(funit,*) (epsilon_inf(mu,nu),mu=1,3)
1488              end do
1489            end if
1490            read(funit,'(a)',iostat=ios) readline
1491            call rmtabfromline(readline)
1492            line=adjustl(readline)
1493            call rdfromline_value('epsilon_inf',line,strg)
1494            if (strg/="") then
1495              strg1=trim(strg)
1496            else
1497              strg1=trim(line)
1498            end if
1499            read(strg1,*) (epsilon_inf(mu,3),mu=1,3)
1500            cycle
1501          end  if
1502 
1503          if ((line(1:8)=='<elastic')) then
1504            call rdfromline_value('elastic',line,strg)
1505            if (strg/="") then
1506              strg1=trim(strg)
1507              read(strg1,*) (elastic_constants(mu,1),mu=1,6)
1508              do nu=2,5
1509                read(funit,*) (elastic_constants(mu,nu),mu=1,6)
1510              end do
1511            else
1512              do nu=1,5
1513                read(funit,*) (elastic_constants(mu,nu),mu=1,6)
1514              end do
1515            end if
1516            read(funit,'(a)',iostat=ios) readline
1517            call rmtabfromline(readline)
1518            line=adjustl(readline)
1519            call rdfromline_value('elastic',line,strg)
1520            if (strg/="") then
1521              strg1=trim(strg)
1522            else
1523              strg1=trim(line)
1524            end if
1525            read(strg1,*) (elastic_constants(mu,6),mu=1,6)
1526            cycle
1527          end if
1528 
1529          if ((line(1:5)=='<atom')) then
1530            call rdfromline("mass",line,strg)
1531            strg1=trim(strg)
1532            read(strg1,*) amu
1533            if (.not.any(abs(all_amu-amu)<tol16)) then
1534              all_amu(iamu) = amu
1535              typat(iatom) = int(amu)
1536              !convert atomic mass unit to znucl
1537              do ii=1,103
1538                call atomdata_from_znucl(atom,real(ii,dp))
1539                if (abs((real(atom%amu,sp)-real(amu,sp))&
1540 &                 /real(amu,sp)*100)<0.1) then
1541                  znucl(iamu) = atom%znucl
1542                  exit
1543                end if
1544              end do
1545              iamu = iamu +1
1546            end if
1547            do itypat=1,ntypat
1548              if(abs(amu-all_amu(itypat))<tol16) then
1549                typat(iatom) = itypat
1550              end if
1551            end do
1552            cycle
1553          end if
1554 
1555          if ((line(1:9)=='<position')) then
1556            call rdfromline_value('position',line,strg)
1557            if (strg/="") then
1558              strg1=trim(strg)
1559              read(strg1,*)(xcart(mu,iatom),mu=1,3)
1560            else
1561              read(funit,'(a)',iostat=ios) readline
1562              call rmtabfromline(readline)
1563              line=adjustl(readline)
1564              call rdfromline_value('position',line,strg)
1565              if (strg/="") then
1566                strg1=trim(strg)
1567              else
1568                strg1=trim(line)
1569              end if
1570              read(strg1,*)(xcart(mu,iatom),mu=1,3)
1571            end if
1572            cycle
1573          end if
1574 
1575          if ((line(1:11)=='<borncharge')) then
1576            call rdfromline_value('borncharge',line,strg)
1577            if (strg/="") then
1578              strg1=trim(strg)
1579              read(strg1,*) (zeff(mu,1,iatom),mu=1,3)
1580              read(funit,*) (zeff(mu,2,iatom),mu=1,3)
1581            else
1582              do nu=1,2
1583                read(funit,*) (zeff(mu,nu,iatom),mu=1,3)
1584              end do
1585            end if
1586            read(funit,'(a)',iostat=ios) readline
1587            line=adjustl(readline)
1588            call rdfromline_value('borncharge',line,strg)
1589            if (strg/="") then
1590              strg1=trim(strg)
1591            else
1592              strg1=trim(line)
1593            end if
1594              read(strg1,*) (zeff(mu,3,iatom),mu=1,3)
1595            cycle
1596          end if
1597 
1598          if ((line(1:7)==char(60)//char(47)//'atom'//char(62))) then
1599            iatom=iatom+1
1600            cycle
1601          end if
1602 
1603          if ((line(1:12)=='<local_force')) then
1604            found2 = .False.
1605            irpt1 = irpt1 + 1
1606            do while (.not.found2)
1607              read(funit,'(a)',iostat=ios) readline
1608              call rmtabfromline(readline)
1609              line=adjustl(readline)
1610              if ((line(1:5)=='<data')) then
1611                call rdfromline_value('data',line,strg)
1612                if (strg/="") then
1613                  ABI_MALLOC(work2,(3*natom,3*natom))
1614                  strg1=trim(strg)
1615                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
1616                  do mu=2,3*natom-1
1617                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1618                  end do
1619                  read(funit,'(a)',iostat=ios) readline
1620                  call rmtabfromline(readline)
1621                  line=adjustl(readline)
1622                  call rdfromline_value('data',line,strg)
1623                  if (strg/="") then
1624                    strg1=trim(strg)
1625                  else
1626                    strg1=trim(line)
1627                  end if
1628                  read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
1629                  local_atmfrc(:,:,:,:,irpt1) = reshape(work2,(/3,natom,3,natom/))
1630                  ABI_FREE(work2)
1631                else
1632                  ABI_MALLOC(work2,(3*natom,3*natom))
1633                  do mu=1,3*natom
1634                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1635                  end do
1636                  local_atmfrc(:,:,:,:,irpt1) =  reshape(work2,(/3,natom,3,natom/))
1637                  ABI_FREE(work2)
1638                end if
1639              end if
1640              if ((line(1:5)=='<cell')) then
1641                call rdfromline_value('cell',line,strg)
1642                if (strg/="") then
1643                  strg1=trim(strg)
1644                  read(strg1,*)(cell_local(mu,irpt1),mu=1,3)
1645                else
1646                  read(funit,*)(cell_local(mu,irpt1),mu=1,3)
1647                end if
1648                found2 = .TRUE.
1649                cycle
1650              end if
1651            end do
1652          end if
1653 
1654          if ((line(1:12)=='<total_force')) then
1655            irpt2 = irpt2 + 1
1656            found2 = .False.
1657            do while (.not.found2)
1658              read(funit,'(a)',iostat=ios) readline
1659              call rmtabfromline(readline)
1660              line=adjustl(readline)
1661              if ((line(1:5)=='<data')) then
1662                call rdfromline_value('data',line,strg)
1663                if (strg/="") then
1664                  ABI_MALLOC(work2,(3*natom,3*natom))
1665                  strg1=trim(strg)
1666                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
1667                  do mu=2,3*natom-1
1668                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1669                  end do
1670                  read(funit,'(a)',iostat=ios) readline
1671                  call rmtabfromline(readline)
1672                  line=adjustl(readline)
1673                  call rdfromline_value('data',line,strg)
1674                  if (strg/="") then
1675                    strg1=trim(strg)
1676                  else
1677                    strg1=trim(line)
1678                  end if
1679                  read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
1680                  total_atmfrc(:,:,:,:,irpt2) = reshape(work2,(/3,natom,3,natom/))
1681                  ABI_FREE(work2)
1682                else
1683                  ABI_MALLOC(work2,(3*natom,3*natom))
1684                  do mu=1,3*natom
1685                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1686                  end do
1687                  total_atmfrc(:,:,:,:,irpt2) = reshape(work2,(/3,natom,3,natom/))
1688                  ABI_FREE(work2)
1689                end if
1690              end if
1691              if ((line(1:5)=='<cell')) then
1692                call rdfromline_value('cell',line,strg)
1693                if (strg/="") then
1694                  strg1=trim(strg)
1695                  read(strg1,*)(cell_total(mu,irpt2),mu=1,3)
1696                else
1697                  read(funit,*)(cell_total(mu,irpt2),mu=1,3)
1698                end if
1699                found2 = .TRUE.
1700                cycle
1701              end if
1702            end do
1703          end if
1704 
1705          if ((line(1:7)=='<qpoint')) then
1706            call rdfromline_value('qpoint',line,strg)
1707            if (strg/="") then
1708              strg1=trim(strg)
1709              read(strg1,*)(qph1l(mu,iph1l),mu=1,3)
1710            else
1711              read(funit,*) (qph1l(mu,iph1l),mu=1,3)
1712            end if
1713          end if
1714 
1715          if ((line(1:12)=='<frequencies')) then
1716            call rdfromline_value('frequencies',line,strg)
1717            if (strg/="") then
1718              strg1=trim(strg)
1719              read(strg1,*)(phfrq(mu,iph1l),mu=1,3*natom)
1720            else
1721              do nu=1,natom
1722                read(funit,*) (phfrq(((nu-1)*3)+mu,iph1l),mu=1,3)
1723              end do
1724            end if
1725          end if
1726 
1727          if ((line(1:17)=='<dynamical_matrix')) then
1728            call rdfromline_value('dynamical_matrix',line,strg)
1729            if (strg/="") then
1730              ABI_MALLOC(work2,(3*natom,3*natom))
1731              strg1=trim(strg)
1732              read(strg1,*) (work2(nu,1),nu=1,3*natom)
1733              do mu=2,3*natom-1
1734                read(funit,*)(work2(nu,mu),nu=1,3*natom)
1735              end do
1736              read(funit,'(a)',iostat=ios) readline
1737              call rmtabfromline(readline)
1738              line=adjustl(readline)
1739              call rdfromline_value('dynamical_matrix',line,strg)
1740              if (strg/="") then
1741                strg1=trim(strg)
1742              else
1743                strg1=trim(line)
1744              end if
1745              read(strg1,*) (work2(nu,3*natom),nu=1,3*natom)
1746              dynmat(1,:,:,:,:,iph1l) = reshape(work2,(/3,natom,3,natom/))
1747              ABI_FREE(work2)
1748            else
1749              ABI_MALLOC(work2,(3*natom,3*natom))
1750              do mu=1,3*natom
1751                read(funit,*)(work2(nu,mu),nu=1,3*natom)
1752              end do
1753              dynmat(1,:,:,:,:,iph1l) = reshape(work2,(/3,natom,3,natom/))
1754              ABI_FREE(work2)
1755            end if
1756          end if
1757 
1758          if ((line(1:8)==char(60)//char(47)//'phonon')) then
1759            iph1l = iph1l +1
1760          end if
1761 
1762          if ((line(1:16)=='<strain_coupling')) then
1763            read(funit,'(a)',iostat=ios) readline
1764            call rdfromline("voigt",line,strg)
1765            strg1=trim(strg)
1766            read(strg1,*) voigt
1767            voigt = voigt + 1 ! 0 to 5 in the xml
1768            has_straincoupling = .true.
1769            irpt = 1
1770          end if
1771 
1772        else
1773 !        Now treat the strain phonon coupling part
1774          if ((line(1:16)=='<strain_coupling')) then
1775            read(funit,'(a)',iostat=ios) readline
1776            call rdfromline("voigt",line,strg)
1777            strg1=trim(strg)
1778            read(strg1,*) voigt
1779            voigt = voigt + 1 ! 0 to 5 in the xml
1780            irpt = 1
1781            cycle
1782          end if
1783 
1784          if(voigt>6)then
1785            write(message, '(4a)' )ch10,&
1786 &               ' WARNING: the number of strain phonon coupling is superior to 6 in ',filename,ch10
1787            call wrtout(std_out,message,'COLL')
1788            exit
1789          end if
1790 
1791          if ((line(1:22)=='<correction_force unit')) then
1792            call rdfromline_value('correction_force',line,strg)
1793            if (strg/="") then
1794              ABI_MALLOC(work2,(3,natom))
1795              strg1=trim(strg)
1796              read(strg1,*) (work2(nu,1),nu=1,3)
1797              do mu=2,natom-1
1798                read(funit,*)(work2(nu,mu),nu=1,3)
1799              end do
1800              read(funit,'(a)',iostat=ios) readline
1801              call rmtabfromline(readline)
1802              line=adjustl(readline)
1803              call rdfromline_value('correction_force',line,strg)
1804              if (strg/="") then
1805                strg1=trim(strg)
1806                read(strg1,*) (work2(nu,natom),nu=1,3)
1807              else
1808                strg1=trim(line)
1809                read(strg1,*) (work2(nu,natom),nu=1,3)
1810              end if
1811              strain_coupling(voigt,:,:) = work2(:,:)
1812              ABI_FREE(work2)
1813            else
1814              ABI_MALLOC(work2,(3,natom))
1815              do mu=1,natom
1816                read(funit,*)(work2(nu,mu),nu=1,3)
1817              end do
1818              strain_coupling(voigt,:,:) = work2(:,:)
1819              ABI_FREE(work2)
1820            end if
1821          end if
1822 
1823          if ((line(1:11)=='<elastic3rd')) then
1824            call rdfromline_value('elastic3rd',line,strg)
1825            if (strg/="") then
1826              strg1=trim(strg)
1827              read(strg1,*) (elastic3rd(voigt,mu,1),mu=1,6)
1828              do nu=2,5
1829                read(funit,*) (elastic3rd(voigt,mu,nu),mu=1,6)
1830              end do
1831            else
1832              do nu=1,5
1833                read(funit,*) (elastic3rd(voigt,mu,nu),mu=1,6)
1834              end do
1835            end if
1836            read(funit,'(a)',iostat=ios) readline
1837            call rmtabfromline(readline)
1838            line=adjustl(readline)
1839            call rdfromline_value('elastic3rd',line,strg)
1840            if (strg/="") then
1841              strg1=trim(strg)
1842              read(strg1,*) (elastic3rd(voigt,mu,6),mu=1,6)
1843            else
1844              strg1=trim(line)
1845              read(strg1,*) (elastic3rd(voigt,mu,6),mu=1,6)
1846            end if
1847            has_anharmonics = .true.
1848            cycle
1849          end if
1850 
1851          if ((line(1:29)=='<correction_strain_force unit')) then
1852            call rdfromline_value('correction_strain_force',line,strg)
1853            if (strg/="") then
1854              ABI_MALLOC(work2,(3*6,natom))
1855              strg1=trim(strg)
1856              read(strg1,*) (work2(nu,1),nu=1,3*6)
1857              do mu=2,natom-1
1858                read(funit,*)(work2(nu,mu),nu=1,3*6)
1859              end do
1860              read(funit,'(a)',iostat=ios) readline
1861              call rmtabfromline(readline)
1862              line=adjustl(readline)
1863              call rdfromline_value('correction_strain_force',line,strg)
1864              if (strg/="") then
1865                strg1=trim(strg)
1866                read(strg1,*) (work2(nu,natom),nu=1,3*6)
1867              else
1868                strg1=trim(line)
1869                read(strg1,*) (work2(nu,natom),nu=1,3*6)
1870              end if
1871              elastic_displacement(voigt,:,:,:) = reshape(work2(:,:),(/6,3,natom/))
1872              ABI_FREE(work2)
1873            else
1874              ABI_MALLOC(work2,(3*6,natom))
1875              do mu=1,natom
1876                read(funit,*)(work2(nu,mu),nu=1,3*6)
1877              end do
1878              elastic_displacement(voigt,:,:,:) = reshape(work2(:,:),(/6,3,natom/))
1879              ABI_FREE(work2)
1880            end if
1881          end if
1882 
1883          if ((line(1:26)=='<correction_force_constant')) then
1884            found2=.false.
1885            do while (.not.found2)
1886              read(funit,'(a)',iostat=ios) readline
1887              call rmtabfromline(readline)
1888              line=adjustl(readline)
1889              if ((line(1:5)=='<data')) then
1890                call rdfromline_value('data',line,strg)
1891                if (strg/="") then
1892                  ABI_MALLOC(work2,(3*natom,3*natom))
1893                  strg1=trim(strg)
1894                  read(strg1,*) (work2(1,nu),nu=1,3*natom)
1895                  do mu=2,3*natom-1
1896                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1897                  end do
1898                  read(funit,'(a)',iostat=ios) readline
1899                  call rmtabfromline(readline)
1900                  line=adjustl(readline)
1901                  call rdfromline_value('data',line,strg)
1902                  if (strg/="") then
1903                    strg1=trim(strg)
1904                    read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
1905                  else
1906                    strg1=trim(line)
1907                    read(strg1,*) (work2(3*natom,nu),nu=1,3*natom)
1908                  end if
1909                  phonon_strain(voigt)%atmfrc(:,:,:,:,irpt) = &
1910 &                           reshape(work2,(/3,natom,3,natom/))
1911                  ABI_FREE(work2)
1912                else
1913                  ABI_MALLOC(work2,(3*natom,3*natom))
1914                  do mu=1,3*natom
1915                    read(funit,*)(work2(mu,nu),nu=1,3*natom)
1916                  end do
1917                  phonon_strain(voigt)%atmfrc(:,:,:,:,irpt) =&
1918 &              reshape(work2,(/3,natom,3,natom/))
1919                  ABI_FREE(work2)
1920                end if
1921                has_anharmonics = .true.
1922              end if
1923              if ((line(1:5)=='<cell')) then
1924                call rdfromline_value('cell',line,strg)
1925                if (strg/="") then
1926                  strg1=trim(strg)
1927                  read(strg1,*)(phonon_strain(voigt)%cell(mu,irpt),mu=1,3)
1928                else
1929                  read(funit,*)(phonon_strain(voigt)%cell(mu,irpt),mu=1,3)
1930                end if
1931                irpt = irpt + 1
1932                found2=.true.
1933                cycle
1934              end if
1935            end do
1936          end if
1937 
1938          if ((line(1:17)==char(60)//char(47)//'strain_coupling')) then
1939 !          set nrpt for the previous value of strain
1940            phonon_strain(voigt)%nrpt = irpt - 1
1941 !         restart the calculation of nrpt
1942          end if
1943        end if
1944      end if
1945    end do
1946 
1947 
1948 ! Reorder the ATMFRC
1949 ! Case 1: only local in the xml
1950    if (irpt1>0 .and. irpt2==0) then
1951      ifcs%cell(:,:) = int(cell_local(:,:))
1952      ifcs%atmfrc(:,:,:,:,:)  = local_atmfrc(:,:,:,:,:)
1953      ifcs%short_atmfrc(:,:,:,:,:) = local_atmfrc(:,:,:,:,:)
1954      ifcs%ewald_atmfrc(:,:,:,:,:) = zero
1955 
1956 ! Case 2: only total in the xml
1957    else if(irpt1==0 .and. irpt2>0)then
1958      ifcs%cell(:,:) = int(cell_total(:,:))
1959      ifcs%atmfrc(:,:,:,:,:)  = total_atmfrc(:,:,:,:,:)
1960      ifcs%short_atmfrc(:,:,:,:,:) = zero
1961      ifcs%ewald_atmfrc(:,:,:,:,:) = total_atmfrc(:,:,:,:,:)
1962 
1963 ! Case 3: local + total in the xml
1964    else if (irpt1>0 .and. irpt2>0)then
1965      if(irpt1 <= irpt2)then
1966        irpt3 = 0
1967        do ii=1,irpt2
1968          ifcs%cell(:,ii) = int(cell_total(:,ii))
1969          ifcs%atmfrc(:,:,:,:,ii)  = total_atmfrc(:,:,:,:,ii)
1970          do jj=1,irpt1
1971            if (all(abs(int(cell_local(:,jj))-ifcs%cell(:,ii))<tol16)) then
1972              ifcs%short_atmfrc(:,:,:,:,ii) = local_atmfrc(:,:,:,:,jj)
1973              irpt3 = irpt3 + 1
1974            end if
1975          end do
1976        end do
1977        if(irpt3 /= irpt1)then
1978          write(message, '(4a)' )ch10,&
1979 &         ' There is several similar short IFC in ',filename,ch10
1980          ABI_BUG(message)
1981        end if
1982      else
1983        write(message, '(2a,I5,3a,I5,5a)' )ch10,&
1984 &     ' The number of total IFC  (',irpt2,') is inferior to  ',ch10,&
1985 &     ' the number of short range IFC (',irpt1,') in ',filename,ch10,&
1986 &     ' This is not possible',ch10
1987        ABI_BUG(message)
1988      end if
1989    end if
1990 
1991 !  Do some checks
1992    if (any(typat==0)) then
1993      write(message, '(a,a,a)' )&
1994 &      ' Unable to read the type of atoms ',trim(filename),ch10
1995      ABI_ERROR(message)
1996    end if
1997 
1998    if (any(abs(znucl)<tol16)) then
1999      write(message, '(a,a,a)' )&
2000 &      ' Unable to read the atomic number ',trim(filename),ch10
2001      ABI_ERROR(message)
2002    end if
2003 
2004    if (any(abs(all_amu)<tol16)) then
2005      write(message, '(a,a,a)' )&
2006 &     ' Unable to read the atomic mass ',trim(filename),ch10
2007      ABI_ERROR(message)
2008    end if
2009 
2010    close(unit=funit)
2011 
2012 #endif
2013 
2014  end if !End if master
2015 
2016 !MPI BROADCAST
2017  call xmpi_bcast(energy,master, comm, ierr)
2018  call xmpi_bcast(all_amu,master, comm, ierr)
2019  call xmpi_bcast(dynmat,master, comm, ierr)
2020  call xmpi_bcast(elastic_constants,master, comm, ierr)
2021  call xmpi_bcast(epsilon_inf,master, comm, ierr)
2022  call xmpi_bcast(ifcs%nrpt,master, comm, ierr)
2023  call xmpi_bcast(ifcs%atmfrc,master, comm, ierr)
2024  call xmpi_bcast(ifcs%cell,master, comm, ierr)
2025  call xmpi_bcast(ifcs%ewald_atmfrc,master, comm, ierr)
2026  call xmpi_bcast(ifcs%short_atmfrc,master, comm, ierr)
2027  call xmpi_bcast(strain_coupling,master, comm, ierr)
2028  call xmpi_bcast(phfrq,master, comm, ierr)
2029  call xmpi_bcast(qph1l,master, comm, ierr)
2030  call xmpi_bcast(typat,master, comm, ierr)
2031  call xmpi_bcast(rprimd,master, comm, ierr)
2032  call xmpi_bcast(xcart,master, comm, ierr)
2033  call xmpi_bcast(zeff,master, comm, ierr)
2034  call xmpi_bcast(znucl,master, comm, ierr)
2035  do ii = 1,6
2036    call xmpi_bcast(phonon_strain(ii)%nrpt   ,master, comm, ierr)
2037    call xmpi_bcast(phonon_strain(ii)%atmfrc ,master, comm, ierr)
2038    call xmpi_bcast(phonon_strain(ii)%cell   ,master, comm, ierr)
2039  end do
2040  call xmpi_bcast(elastic3rd   ,master, comm, ierr)
2041  call xmpi_bcast(elastic_displacement ,master, comm, ierr)
2042  call xmpi_bcast(has_anharmonics ,master, comm, ierr)
2043 
2044 !Fill somes others variables
2045  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
2046  call xcart2xred(natom,rprimd,xcart,xred)
2047 
2048 !Re-generate symmetry operations from the lattice and atomic coordinates
2049  tolsym=tol8
2050  msym = 384
2051  ABI_MALLOC(spinat,(3,natom))
2052  ABI_MALLOC(ptsymrel,(3,3,msym))
2053  ABI_MALLOC(symafm,(msym))
2054  ABI_MALLOC(symrel,(3,3,msym))
2055  ABI_MALLOC(tnons,(3,msym))
2056  use_inversion=1
2057  spinat = 0;
2058  symrel = 0;
2059  symafm = 0;
2060  tnons = 0 ;
2061  space_group = 0;
2062  call symlatt(bravais,std_out,msym,nptsym,ptsymrel,rprimd,tolsym)
2063  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
2064  call symfind(gprimd,msym,natom,nptsym,0,nsym,&
2065 &  0,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred)
2066 
2067 !Initialisation of crystal
2068  npsp = ntypat; timrev = 1
2069  ABI_MALLOC(title, (ntypat))
2070  do ii=1,ntypat
2071    write(title(ii),'(a,i0)')"No title for typat ",ii
2072  end do
2073 
2074 !Warning znucl is dimension with ntypat = nspsp hence alchemy is not supported here
2075  call crystal_init(all_amu,Crystal,space_group,natom,npsp,ntypat,nsym,rprimd,typat,xred,&
2076 &  zion,znucl,timrev,.FALSE.,.FALSE.,title,&
2077 &  symrel=symrel(:,:,1:nsym),tnons=tnons(:,1:nsym),symafm=symafm(1:nsym))
2078 
2079 !amu is not fill in crystal_init...
2080  Crystal%amu(:) = all_amu(:)
2081 
2082  ABI_FREE(symrel)
2083  ABI_FREE(symafm)
2084  ABI_FREE(tnons)
2085  ABI_FREE(spinat)
2086  ABI_FREE(ptsymrel)
2087 
2088 !if strcpling is set to 0 by the user, need to set the flag to false for
2089 !the initialisation of the effective potential
2090  if (present(strcpling))then
2091    if(strcpling == 0 )then
2092      has_anharmonics = .FALSE.
2093    end if
2094  end if
2095 
2096 !Initialisation of eff_pot
2097  call effective_potential_init(crystal,eff_pot,energy,ifcs,ncoeff,nph1l,comm,&
2098 &                              dynmat=dynmat,elastic_constants=elastic_constants,&
2099 &                              elastic3rd=elastic3rd,elastic_displacement=elastic_displacement,&
2100 &                              epsilon_inf=epsilon_inf,strain_coupling=strain_coupling,&
2101 &                              phonon_strain=phonon_strain,phfrq=phfrq,qpoints=qph1l,&
2102 &                              has_anharmonicsTerms=has_anharmonics,zeff=zeff)
2103 
2104 !DEALLOCATION OF ARRAYS
2105  ABI_FREE(all_amu)
2106  ABI_FREE(cell_local)
2107  ABI_FREE(cell_total)
2108  ABI_FREE(total_atmfrc)
2109  ABI_FREE(local_atmfrc)
2110  ABI_FREE(ifcs%atmfrc)
2111  ABI_FREE(ifcs%cell)
2112  ABI_FREE(ifcs%short_atmfrc)
2113  ABI_FREE(ifcs%ewald_atmfrc)
2114  ABI_FREE(dynmat)
2115  ABI_FREE(strain_coupling)
2116  ABI_FREE(phfrq)
2117  ABI_FREE(qph1l)
2118  ABI_FREE(title)
2119  ABI_FREE(typat)
2120  ABI_FREE(xcart)
2121  ABI_FREE(xred)
2122  ABI_FREE(zeff)
2123  ABI_FREE(zion)
2124  ABI_FREE(znucl)
2125  do ii = 1,6
2126    phonon_strain(ii)%nrpt   = nrpt
2127    phonon_strain(ii)%atmfrc = zero
2128    phonon_strain(ii)%cell   = 0
2129    ABI_FREE(phonon_strain(ii)%atmfrc)
2130    ABI_FREE(phonon_strain(ii)%cell)
2131  end do
2132  ABI_FREE(phonon_strain)
2133  ABI_FREE(elastic_displacement)
2134 
2135 !DEALLOCATION OF TYPES
2136  call ifcs%free()
2137  call crystal%free()
2138 
2139 end subroutine system_xml2effpot

m_effpot_xml/char_c2f [ Functions ]

[ Top ] [ Functions ]

NAME

  char_c_to_f

FUNCTION

 Helper function to convert a C string to a Fortran string
 Based on a routine by Joseph M. Krahn

INPUTS

  c_string=C string

OUTPUT

  f_string=Fortran string

SOURCE

3918 subroutine char_c2f(c_string,f_string)
3919 
3920  use, intrinsic :: iso_c_binding, only : C_CHAR,C_NULL_CHAR
3921 !Arguments ------------------------------------
3922  character(kind=C_CHAR,len=1),intent(in) :: c_string(*)
3923  character(len=*),intent(out) :: f_string
3924 !Local variables -------------------------------
3925  integer :: ii
3926 !! *************************************************************************
3927  ii=1
3928  do while(c_string(ii)/=C_NULL_CHAR.and.ii<=len(f_string))
3929    f_string(ii:ii)=c_string(ii) ; ii=ii+1
3930  end do
3931  if (ii<len(f_string)) f_string(ii:)=' '
3932 end subroutine char_c2f

m_effpot_xml/char_f2c [ Functions ]

[ Top ] [ Functions ]

NAME

  char_f_to_c

FUNCTION

 Helper function to convert a Fortran string to a C string
 Based on a routine by Joseph M. Krahn

INPUTS

  f_string=Fortran string

OUTPUT

  c_string=C string

SOURCE

3881 #if defined HAVE_XML
3882 
3883 function char_f2c(f_string) result(c_string)
3884 
3885  use, intrinsic :: iso_c_binding, only : C_CHAR,C_NULL_CHAR
3886 !Arguments ------------------------------------
3887  character(len=*),intent(in) :: f_string
3888  character(kind=C_CHAR,len=1) :: c_string(len_trim(f_string)+1)
3889 !Local variables -------------------------------
3890  integer :: ii,strlen
3891 !! *************************************************************************
3892  strlen=len_trim(f_string)
3893  forall(ii=1:strlen)
3894    c_string(ii)=f_string(ii:ii)
3895  end forall
3896  c_string(strlen+1)=C_NULL_CHAR
3897 end function char_f2c