TABLE OF CONTENTS
- ABINIT/m_effective_potential
- m_effective_potential/effective_potential_checkDEV
- m_effective_potential/effective_potential_copy
- m_effective_potential/effective_potential_init
- m_effective_potential/effective_potential_initmpi
- m_effective_potential/effective_potential_setConfinement
- m_effective_potential/effective_potential_setSupercell
- m_effective_potential/effective_potential_type
- m_effective_potential/effective_potential_writeAbiInput
- m_effective_potential/effective_potential_writeNETCDF
- m_effective_potential/effective_potential_writeXML
- m_effective_potential/equal
ABINIT/m_effective_potential [ Modules ]
NAME
m_effective_potential
FUNCTION
Module for the effective potential Container type is defined, and destruction, print subroutines Contain also routine to evaluate the energy,forces and stresses
COPYRIGHT
Copyright (C) 2010-2024 ABINIT group (AM) This file is distributed under the terms of the GNU General Public Licence, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
SOURCE
20 #if defined HAVE_CONFIG_H 21 #include "config.h" 22 #endif 23 24 #include "abi_common.h" 25 26 module m_effective_potential 27 28 use defs_basis 29 use defs_abitypes 30 use m_errors 31 use m_abicore 32 use m_strain 33 use m_ifc 34 use m_supercell 35 use m_phonons 36 use m_ddb 37 use m_polynomial_conf 38 use m_polynomial_coeff 39 use m_anharmonics_terms 40 use m_harmonics_terms 41 use m_xmpi 42 use m_ewald 43 use m_nctk 44 #if defined HAVE_NETCDF 45 use netcdf 46 #endif 47 #if defined DEV_MS_SCALEUP 48 use scup_global, only : global_calculate_energy, global_calculate_forces 49 #endif 50 51 use m_fstrings, only : replace, ftoa, itoa 52 use m_io_tools, only : open_file, get_unit 53 use m_dtfil, only : isfile 54 use m_symtk, only : matr3inv 55 use m_effpot_mpi, only : effpot_mpi_init,effpot_mpi_type,effpot_mpi_free 56 use m_abihist, only : abihist 57 use m_geometry, only : gred2fcart,fcart2gred, xcart2xred, xred2xcart, metric 58 use m_crystal, only : crystal_t, crystal_init 59 !use m_anaddb_dataset, only : anaddb_dataset_type, anaddb_dtset_free, outvars_anaddb, invars9 60 61 implicit none 62 63 public :: effective_potential_distributeResidualForces 64 public :: effective_potential_evaluate 65 public :: effective_potential_free 66 public :: effective_potential_freeCoeffs 67 public :: effective_potential_freempi 68 public :: effective_potential_generateDipDip 69 public :: effective_potential_getDisp 70 public :: effective_potential_init 71 public :: effective_potential_initmpi 72 public :: effective_potential_copy 73 public :: effective_potential_print 74 public :: effective_potential_printSupercell 75 public :: effective_potential_setCoeffs 76 public :: effective_potential_setConfinement 77 public :: effective_potential_setElastic3rd 78 public :: effective_potential_setElastic4th 79 public :: effective_potential_setElasticDispCoupling 80 public :: effective_potential_setStrainPhononCoupling 81 public :: effective_potential_setSupercell 82 public :: effective_potential_writeAbiInput 83 public :: effective_potential_writeXML 84 public :: effective_potential_writeAnhHead 85 !AM_EXPERIMENTAL 86 public :: effective_potential_computeGradient 87 ! public :: effective_potential_effpot2ddb 88 ! public :: effective_potential_printPDOS 89 public :: effective_potential_checkDEV 90 public :: effective_potential_writeNETCDF 91 public :: OPERATOR(==) 92 !AM_EXPERIMENTAL
m_effective_potential/effective_potential_checkDEV [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_checkDEV
FUNCTION
Routine for develloper Check by finite differences the equations in effective_potential_evaluate need to provide HIST file, so you need to activate the fit_process or bound_process to activate the reading of the HIST
INPUTS
eff_pot<type(effective_potential)> = effective potential hist<type(abihist)> = The history of the MD natom = number of atom ntime = number of time in the hist
OUTPUT
SOURCE
3411 subroutine effective_potential_checkDEV(eff_pot,hist,natom,ntime) 3412 3413 !Arguments ------------------------------------ 3414 !scalars 3415 integer, intent(in) :: natom,ntime 3416 !arrays 3417 type(effective_potential_type),intent(in) :: eff_pot 3418 type(abihist),intent(in) :: hist 3419 !Local variables------------------------------- 3420 !scalar 3421 integer :: ii,jj,ia,mu,npt,istep 3422 ! integer :: ifirst 3423 real(dp):: energy,delt,delta,ucvol 3424 !arrays 3425 real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),mat_def(3,3),identity(3,3) 3426 real(dp):: fcart(3,natom),gred(3,natom),strten(6),rprimd(3,3) 3427 real(dp):: rprimd_def(3,3),rprimd_ref(3,3),deltalist(5) 3428 real(dp):: disp(3,natom),disp_red(3,natom),strain(6),du_delta(6,3,natom),diff(5) 3429 real(dp),allocatable :: xred(:,:) 3430 integer,parameter :: alpha(9)=(/1,2,3,3,3,2,2,1,1/),beta(9)=(/1,2,3,2,1,1,3,3,2/) 3431 character(len=500) :: msg 3432 3433 ! ************************************************************************* 3434 3435 !Do some checks 3436 if(ntime /= hist%mxhist)then 3437 write(msg,'(a)')'ntime is not correct' 3438 ABI_BUG(msg) 3439 end if 3440 3441 if(natom /= size(hist%xred,2)) then 3442 write(msg,'(a)')'natom is not correct' 3443 ABI_BUG(msg) 3444 end if 3445 3446 3447 ABI_MALLOC(xred,(3,natom)) 3448 xred = zero 3449 3450 !option 1 => set the reference for the test 3451 ! call xcart2xred(eff_pot%supercell%natom,eff_pot%supercell%rprimd,& 3452 !& eff_pot%supercell%xcart,xred) 3453 ! rprimd = eff_pot%supercell%rprimd 3454 3455 !option 2 => set a specific step for the test 3456 istep = 4 3457 xred = hist%xred(:,:,istep) 3458 rprimd = hist%rprimd(:,:,istep) 3459 3460 rprimd_ref = eff_pot%supercell%rprimd 3461 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 3462 3463 npt=5 3464 delta = 0.001 3465 deltalist = (/-2*delta,-delta,real(0.0,dp),delta,2*delta/) 3466 strain = zero 3467 3468 do ia=1,natom 3469 do mu=1,3 3470 write(std_out,*) "atm: ",ia," dir: ",mu 3471 do ii=1,npt 3472 delt = deltalist(ii) 3473 3474 ! Get the initial displacement 3475 call effective_potential_getDisp(disp,du_delta,natom,rprimd,& 3476 & eff_pot%supercell%rprimd,1,xred_hist=xred,& 3477 & xcart_ref=eff_pot%supercell%xcart,& 3478 & compute_displacement = .true.,compute_duDelta = .true.) 3479 3480 ! Add the delta 3481 call xcart2xred(natom, rprimd, disp, disp_red) 3482 disp_red(mu,ia) = disp_red(mu,ia) + delt 3483 call xred2xcart(natom, rprimd, disp, disp_red) 3484 3485 call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd,& 3486 & xred=xred,du_delta=du_delta,& 3487 & displacement=disp,compute_anharmonic=.true.,verbose=.false.) 3488 diff(ii) = energy 3489 3490 end do 3491 3492 ! Get the initial displacement 3493 call effective_potential_getDisp(disp,du_delta,natom,rprimd,& 3494 & eff_pot%supercell%rprimd,1,xred_hist=xred,& 3495 & xcart_ref=eff_pot%supercell%xcart,& 3496 & compute_displacement = .true.,compute_duDelta = .true.) 3497 3498 call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd,& 3499 & xred=xred,du_delta=du_delta,& 3500 & displacement=disp,compute_anharmonic=.true.,verbose=.false.) 3501 3502 write(std_out,*) "Analyti:",gred(mu,ia) 3503 write(std_out,*) "FD :",(-diff(5)+8*diff(4)-8*diff(2)+diff(1)) / (12*delta) 3504 write(std_out,*) "Diff(%):",abs(100*(gred(mu,ia)-((-diff(5)+8*diff(4)-8*diff(2)+diff(1))& 3505 & / (12*delta) )) / ((-diff(5)+8*diff(4)-8*diff(2)+diff(1)) / (12*delta) )) 3506 3507 end do 3508 end do 3509 3510 3511 ! Fill the identity matrix 3512 identity = zero 3513 forall(ii=1:3)identity(ii,ii)=1 3514 3515 npt=5 3516 delta = 0.0005 3517 deltalist = (/-2*delta,-delta,real(0.0,dp),delta,2*delta/) 3518 3519 do jj=1,6 3520 write(std_out,*) "strain ",jj 3521 do ii=1,npt 3522 strain = zero 3523 delt = deltalist(ii) 3524 mat_def = zero 3525 strain(jj) = strain(jj) + delt 3526 3527 mat_def(alpha(jj),beta(jj)) = mat_def(alpha(jj),beta(jj)) + half * strain(jj) 3528 mat_def(beta(jj),alpha(jj)) = mat_def(beta(jj),alpha(jj)) + half * strain(jj) 3529 3530 rprimd_def = matmul(identity(:,:)+mat_def(:,:),rprimd) 3531 3532 ! The two options should give the same result 3533 ! Option 1 => compute the disps and provide them to evaluate 3534 ! call effective_potential_getDisp(disp,du_delta,natom,rprimd_def,& 3535 ! & rprimd_ref,1,xred_hist=xred,& 3536 ! & xcart_ref=eff_pot%supercell%xcart,& 3537 ! & compute_displacement = .true.,compute_duDelta = .true.) 3538 3539 ! call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd_def,& 3540 ! & xred=xred,du_delta=du_delta,& 3541 ! & displacement=disp,strain=strain,& 3542 ! & compute_anharmonic=.true.,verbose=.false.) 3543 3544 ! Option 2 => compute the disps within evaluate 3545 call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd_def,& 3546 & xred=xred,compute_anharmonic=.true.,verbose=.false.) 3547 3548 3549 3550 diff(ii) = energy 3551 3552 end do 3553 3554 ! The two options should give the same result 3555 ! Option 1 => compute the disps and provide them to evaluate 3556 ! call effective_potential_getDisp(disp,du_delta,natom,rprimd,& 3557 ! & rprimd_ref,1,xred_hist=xred,& 3558 ! & xcart_ref=eff_pot%supercell%xcart,& 3559 ! & compute_displacement = .true.,compute_duDelta = .true.) 3560 3561 ! call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd,& 3562 ! & xred=xred,du_delta=du_delta,& 3563 ! & displacement=disp,& 3564 ! & compute_anharmonic=.true.,verbose=.false.) 3565 3566 ! Option 2 => compute the disps within evaluate 3567 call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd,& 3568 & xred=xred,compute_anharmonic=.true.,verbose=.false.) 3569 3570 write(std_out,*) "Analyti:",strten(jj) 3571 write(std_out,*) "FD :",(-diff(5)+8*diff(4)-8*diff(2)+diff(1)) / (12*delta) / ucvol 3572 write(std_out,*) "Diff(%):",abs(100*(strten(jj)-((-diff(5)+8*diff(4)-8*diff(2)+diff(1))& 3573 & / (12*delta) / ucvol)) / ((-diff(5)+8*diff(4)-8*diff(2)+diff(1)) / (12*delta) / ucvol)) 3574 3575 end do 3576 3577 end subroutine effective_potential_checkDEV
m_effective_potential/effective_potential_copy [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_copy
FUNCTION
Copy one effective potential to another i.e. initialize the output effective potentiale eff_pot_out with the values the input effective potential eff_pot_in
INPUTS
eff_pot_in<type(effective_potential_type)> = effective_potential datatype to be initialized
OUTPUT
eff_pot_out<type(effective_potential_type)> = effective_potential datatype to be initialized
SOURCE
453 subroutine effective_potential_copy(eff_pot_out,eff_pot_in,comm) 454 455 !Arguments ------------------------------------ 456 !scalars 457 type(effective_potential_type),intent(out) :: eff_pot_out 458 type(effective_potential_type),intent(in) :: eff_pot_in 459 integer,intent(in) :: comm 460 ! *********************************************************************** 461 462 call effective_potential_init(eff_pot_in%crystal,eff_pot_out,eff_pot_in%energy,eff_pot_in%harmonics_terms%ifcs,& 463 & eff_pot_in%anharmonics_terms%ncoeff,eff_pot_in%harmonics_terms%nqpt,comm,& 464 & coeffs=eff_pot_in%anharmonics_terms%coefficients,dynmat=eff_pot_in%harmonics_terms%dynmat,& 465 & elastic_constants=eff_pot_in%harmonics_terms%elastic_constants,& 466 & elastic3rd=eff_pot_in%anharmonics_terms%elastic3rd,& 467 & elastic_displacement=eff_pot_in%anharmonics_terms%elastic_displacement,& 468 & epsilon_inf=eff_pot_in%harmonics_terms%epsilon_inf,& 469 & fcart=eff_pot_in%fcart,strain_coupling=eff_pot_in%harmonics_terms%strain_coupling,& 470 & strten=eff_pot_in%strten,name=eff_pot_in%name,& 471 & phonon_strain=eff_pot_in%anharmonics_terms%phonon_strain,phfrq=eff_pot_in%harmonics_terms%phfrq,& 472 & qpoints=eff_pot_in%harmonics_terms%qpoints,has_anharmonicsTerms=eff_pot_in%has_anharmonicsTerms,& 473 & supercell=eff_pot_in%supercell,& 474 & zeff=eff_pot_in%harmonics_terms%zeff) 475 476 477 end subroutine effective_potential_copy
m_effective_potential/effective_potential_init [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_init
FUNCTION
Initialize effective_potential datatype
INPUTS
crytal<type(crystal_t)> = datatype with all the information for the crystal energy = energy of the reference structure ifcs <type(ifc_type)> = ifc type with cell,ewald short and total range of the ifcs ncoeff = number of coefficients in the polynomial nqpt = number of qpoints comm = mpi comunicator coeffs(ncoeff)<type(polynomial_coeff_type)> = optional,list of coefficients for the anharmonic part dynmat(2,3,natom,3,natom,nqpt) = optional,dynamical matrix for each qpoints epsilon_inf(3,3) = optional,dielectric tensor elastic_constants(6,6) = optional,elastic constants tensor elastic3rd(6,6,6) = optional,3 order derivatives with respect to to 3 strain elastic_displacement(6,6,3,natom)=optional, 3 order derivatives with respect to 2 strain and 1 Atom disp fcart(3,natom) = optional,optional,initial fcart in the structure strain_coupling(6,natom,3) = optional, internal strain coupling parameters strten(6) = optional,optional,initial strain in the structure name = optional, name of the structure phonon_strain(6) = optional,ifc type for the phonon-strain coupling (should be in anharmonics_terms) phfrq(3*natom,nqpt) = optional,phonons frequencies for each q points in Hartree/cm qpoints(3,nqpt) = optional,list of qpoints wavevectors has_anharmonicsTerms = optional, (default false) flag to set the anharmonics terms supercell<type(supercell_type)> = optional, supercell type to define zeff(3,natom) = optional,effective charges
OUTPUT
eff_pot<type(effective_potential_type)> = effective_potential datatype to be initialized
SOURCE
195 subroutine effective_potential_init(crystal,eff_pot,energy,ifcs,ncoeff,nqpt,comm,& 196 & coeffs,dynmat,elastic_constants,elastic3rd,& 197 & elastic_displacement,epsilon_inf,& 198 & fcart,strain_coupling,strten,name,phonon_strain,& 199 & polynomial_conf,phfrq,qpoints,has_anharmonicsTerms,& 200 & supercell,zeff) 201 202 !Arguments ------------------------------------ 203 !scalars 204 integer,intent(in) :: comm,ncoeff,nqpt 205 real(dp),intent(in):: energy 206 logical,optional,intent(in) :: has_anharmonicsTerms 207 !arrays 208 type(crystal_t),intent(in) :: crystal 209 type(effective_potential_type), intent(out) :: eff_pot 210 type(ifc_type),intent(in) :: ifcs 211 character(len=fnlen), optional,intent(in) :: name 212 real(dp),optional,intent(in) :: epsilon_inf(3,3),elastic_constants(6,6) 213 real(dp),optional,intent(in) :: dynmat(:,:,:,:,:,:),qpoints(:,:),phfrq(:,:) 214 real(dp),optional,intent(in) :: strain_coupling(:,:,:),zeff(:,:,:) 215 type(supercell_type),optional,intent(in) :: supercell 216 type(ifc_type),optional,intent(in) :: phonon_strain(6) 217 real(dp),optional,intent(in) :: elastic3rd(6,6,6) 218 real(dp),optional,intent(in) :: elastic_displacement(6,6,3,crystal%natom) 219 type(polynomial_coeff_type),optional,intent(in) :: coeffs(:) 220 real(dp),optional,intent(in) :: strten(6) 221 real(dp),optional,intent(in) :: fcart(3,crystal%natom) 222 type(polynomial_conf_type),optional,intent(in) :: polynomial_conf 223 224 !Local variables------------------------------- 225 !scalar 226 character(len=500) :: msg 227 !arrays 228 229 ! ************************************************************************* 230 231 !1-Free the effective potential before filling it 232 call effective_potential_free(eff_pot) 233 234 if (present(name)) then 235 eff_pot%name = name 236 else 237 eff_pot%name = '' 238 end if 239 240 !2-Perform some checks 241 if (crystal%natom < 1) then 242 write(msg, '(a,a,a,i10,a)' )& 243 & 'The cell must have at least one atom.',ch10,& 244 & 'The number of atom is ',crystal%natom,'.' 245 ABI_BUG(msg) 246 end if 247 248 if (crystal%ntypat < 1) then 249 write(msg, '(a,a,a,i10,a)' )& 250 & 'The cell must have at least one type of atom.',ch10,& 251 & 'The number of type of atom is ',crystal%ntypat,'.' 252 ABI_BUG(msg) 253 end if 254 255 !3-Fill energy of the crystal (hartree) 256 eff_pot%energy = energy 257 258 !1-Fill the crystal 259 !Warning znucl is dimension with ntypat = nspsp hence alchemy is not supported here 260 call crystal_init(crystal%amu,eff_pot%crystal,crystal%space_group,crystal%natom,& 261 & crystal%npsp,crystal%ntypat,crystal%nsym,crystal%rprimd,& 262 & crystal%typat,crystal%xred,crystal%zion,crystal%znucl,& 263 & crystal%timrev,.FALSE.,.FALSE.,crystal%title,& 264 & symrel=crystal%symrel,tnons=crystal%tnons,symafm=crystal%symafm) 265 266 !4-Fill harmonic part 267 call harmonics_terms_init(eff_pot%harmonics_terms,ifcs,crystal%natom,ifcs%nrpt) 268 269 !5-Init the anharmonics_terms to set the flag to false 270 call anharmonics_terms_init(eff_pot%anharmonics_terms,crystal%natom,ncoeff) 271 272 !5-Fill optional inputs 273 ABI_MALLOC(eff_pot%fcart,(3,eff_pot%crystal%natom)) 274 eff_pot%fcart = zero 275 if(present(fcart))then 276 eff_pot%fcart = fcart 277 end if 278 279 if(present(elastic_constants))then 280 eff_pot%harmonics_terms%elastic_constants(:,:) = elastic_constants 281 end if 282 283 if(present(epsilon_inf))then 284 eff_pot%harmonics_terms%epsilon_inf(:,:) = epsilon_inf(:,:) 285 end if 286 287 if(present(dynmat).and.present(qpoints).and.present(phfrq))then 288 call harmonics_terms_setDynmat(dynmat,eff_pot%harmonics_terms,crystal%natom,nqpt,phfrq,qpoints) 289 end if 290 291 if(present(strain_coupling))then 292 call harmonics_terms_setInternalStrain(eff_pot%harmonics_terms,crystal%natom,strain_coupling) 293 end if 294 295 if(present(zeff))then 296 call harmonics_terms_setEffectiveCharges(eff_pot%harmonics_terms,crystal%natom,zeff) 297 end if 298 299 eff_pot%strten = zero 300 if(present(strten))then 301 eff_pot%strten(:) = strten(:) 302 end if 303 304 !Set the flag for the strain coupling 305 if(present(has_anharmonicsTerms)) then 306 eff_pot%has_anharmonicsTerms = has_anharmonicsTerms 307 else 308 eff_pot%has_anharmonicsTerms = .false. 309 end if 310 311 !Allocation of phonon strain coupling array (3rd order) 312 if(present(phonon_strain).and.has_anharmonicsTerms) then 313 call anharmonics_terms_setStrainPhononCoupling(eff_pot%anharmonics_terms,crystal%natom,& 314 & phonon_strain) 315 end if 316 317 !Set the 3rd order elastic tensor 318 if(present(elastic3rd).and.has_anharmonicsTerms)then 319 call anharmonics_terms_setElastic3rd(eff_pot%anharmonics_terms,elastic3rd) 320 end if 321 322 !TODO Comment Marcus: Uncomment and implement below if you want to use the elastic4th implementation, which is there, but 323 ! not used anywere 324 ! Below I just ensured that the has_elastic4th variable is set to FALSE as it was causing problems on some builders 325 ! in the test farm 326 ! Set the 4th order elastic tensor 327 ! if(present(elastic4th).and.has_anharmonicsTerms)then 328 ! call anharmonics_terms_setElastic3rd(eff_pot%anharmonics_terms,elastic4th) 329 ! end if 330 331 !MS Ensure has_elastic4th is .FALSE. 332 ! eff_pot%anharmonics_terms%has_elastic4th=.FALSE. 333 334 335 !Allocation of 3rd order with respecto to 2 strain and 1 atomic displacement 336 if(present(elastic_displacement).and.has_anharmonicsTerms)then 337 call anharmonics_terms_setElasticDispCoupling(eff_pot%anharmonics_terms,crystal%natom,& 338 & elastic_displacement) 339 end if 340 341 !Allocation of the coefficients 342 if(present(coeffs))then 343 if(ncoeff /= size(coeffs))then 344 ABI_BUG('ncoeff has not the same size than coeffs array') 345 end if 346 call effective_potential_setCoeffs(coeffs,eff_pot,ncoeff) 347 end if 348 349 if(present(supercell))then 350 call effective_potential_setSupercell(eff_pot,comm,supercell=supercell) 351 else 352 ! call init_supercell(eff_pot%crystal%natom, (/1,0,0, 0,1,0, 0,0,1/), eff_pot%crystal%rprimd,& 353 !& eff_pot%crystal%typat, eff_pot%crystal%xcart, eff_pot%crystal%znucl, eff_pot%supercell) 354 call effective_potential_setSupercell(eff_pot,comm,ncell=(/1,1,1/)) 355 end if 356 357 !Set the confinement potential 358 if(present(polynomial_conf)) then 359 call effective_potential_setConfinement(polynomial_conf%cutoff_disp,polynomial_conf%cutoff_strain,& 360 & eff_pot,polynomial_conf%factor_disp,& 361 & polynomial_conf%factor_strain,polynomial_conf%ndisp,& 362 & polynomial_conf%power_disp,polynomial_conf%power_strain,& 363 & polynomial_conf%need_confinement) 364 end if 365 366 end subroutine effective_potential_init
m_effective_potential/effective_potential_initmpi [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_initmpi
FUNCTION
Initializes the mpi information for parallelism over supercell. Only the parallelisation over cell is done here. The parallelisation over cell and coeff is disable for now (experimental)
INPUTS
eff_pot<type(effective_potential_type)> = datatype for the effective potential comm = MPI communicator
OUTPUT
This is for the parallelisation over the supercell eff_pot%mpi_ifc%me_supercell = Index of my processor in the comm. over one cell eff_pot%mpi_ifc%my_ncell = Number of cell treated by current proc eff_pot%mpi_ifc%my_cells(:) = Number of the cells in the supercell treat by this CPU eff_pot%mpi_ifc%my_index_cells(:,:) = indexes of the cells in the supercell treat by this CPU
SOURCE
392 subroutine effective_potential_initmpi(eff_pot,comm) 393 394 !Arguments ------------------------------------ 395 !scalars 396 type(effective_potential_type),intent(inout) :: eff_pot 397 integer,intent(in) :: comm 398 !arrays 399 400 !Local variables------------------------------- 401 !scalars 402 integer :: ndiv 403 integer :: ncell 404 !array 405 integer :: cell_number(3) 406 !character(len=500) :: msg 407 ! *********************************************************************** 408 409 !Set the number of cell in the supercell 410 cell_number(1) = eff_pot%supercell%rlatt(1,1) 411 cell_number(2) = eff_pot%supercell%rlatt(2,2) 412 cell_number(3) = eff_pot%supercell%rlatt(3,3) 413 ncell = product(cell_number(:)) 414 415 !Do some checks 416 if (any(cell_number <= 0).or.ncell<=0) then 417 ABI_ERROR('No supercell found for setting') 418 end if 419 420 !First mpi_ifc 421 ndiv = 1 422 call effpot_mpi_free(eff_pot%mpi_ifc) 423 call effpot_mpi_init(eff_pot%harmonics_terms%ifcs%cell,cell_number,eff_pot%mpi_ifc,& 424 & eff_pot%crystal%natom,ndiv,eff_pot%harmonics_terms%ifcs%nrpt,comm) 425 426 !Second mpi_coeff 427 ndiv = 1 428 call effpot_mpi_free(eff_pot%mpi_coeff) 429 call effpot_mpi_init(eff_pot%harmonics_terms%ifcs%cell,cell_number,eff_pot%mpi_coeff,& 430 & eff_pot%crystal%natom,ndiv,eff_pot%harmonics_terms%ifcs%nrpt,comm) 431 432 end subroutine effective_potential_initmpi
m_effective_potential/effective_potential_setConfinement [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_setConfinement
FUNCTION
Set the confinement in the effective_potential datatype
INPUTS
cutoff_disp(6) = Cutoff array for the strain cutoff_strain(ndisp) = Cutoff array for the atomic displacement factor_disp = Factor to appy to the polynomial term of the confinement (displacement) factor_strain = Factor to appy to the polynomial term of the confinement (strain) ndisp = Number of displacement (atoms) for the cut off power_disp = Power of the polynome related to the displacement power_strain = Power of the polynome related to the strain need_confinement = optional,Logical related to the necessity of the confinement
OUTPUT
eff_pot<type(effective_potential_type)> = datatype for effective potential
SOURCE
1307 subroutine effective_potential_setConfinement(cutoff_disp,cutoff_strain,eff_pot,factor_disp,& 1308 & factor_strain,ndisp,power_disp,power_strain,& 1309 & need_confinement) 1310 1311 !Arguments ------------------------------------ 1312 !scalars 1313 integer, intent(in) :: power_disp,power_strain,ndisp 1314 real(dp),intent(in) :: factor_disp,factor_strain 1315 logical,optional,intent(in) :: need_confinement 1316 !arrays 1317 real(dp),intent(in) :: cutoff_disp(ndisp),cutoff_strain(6) 1318 type(effective_potential_type),intent(inout) :: eff_pot 1319 !Local variables------------------------------- 1320 !scalar 1321 logical :: need_confinement_tmp 1322 !arrays 1323 !character(len=500) :: msg 1324 1325 ! ************************************************************************* 1326 1327 !Checks 1328 if (ndisp <= 0) then 1329 ABI_ERROR('ndisp can not be inferior or equal to zero') 1330 end if 1331 1332 !First free the type 1333 call polynomial_conf_free(eff_pot%confinement) 1334 1335 need_confinement_tmp = .FALSE. 1336 if (present(need_confinement)) need_confinement_tmp = need_confinement 1337 1338 call polynomial_conf_init(cutoff_disp,cutoff_strain,factor_disp,factor_strain,ndisp,& 1339 & eff_pot%confinement,power_disp,power_strain,& 1340 & need_confinement=need_confinement_tmp) 1341 1342 1343 end subroutine effective_potential_setConfinement
m_effective_potential/effective_potential_setSupercell [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_setSupercell
FUNCTION
Set the supercell type in the effective_potential type
INPUTS
eff_pot<type(effective_potential_type)> = effective_potential datatype comm = MPI communicator ncell(3) = optional, size of the supercell supercell = optional, supercell type to set to eff_pot
OUTPUT
eff_pot<type(effective_potential_type)> = effective_potential datatype
SOURCE
1365 subroutine effective_potential_setSupercell(eff_pot,comm,ncell,supercell) 1366 1367 !Arguments ------------------------------------ 1368 !scalars 1369 integer,intent(in) :: comm 1370 !arrays 1371 type(effective_potential_type),intent(inout) :: eff_pot 1372 integer,optional,intent(in) :: ncell(3) 1373 type(supercell_type),optional,intent(in) :: supercell 1374 !Local variables------------------------------- 1375 !scalar 1376 !arrays 1377 !character(len=500) :: msg 1378 1379 ! ************************************************************************* 1380 1381 !Checks 1382 if (.not.present(supercell).and..not.present(ncell)) then 1383 ABI_ERROR(' You should at least set ncell of supercell type') 1384 end if 1385 1386 call destroy_supercell(eff_pot%supercell) 1387 1388 if(present(supercell))then 1389 call copy_supercell(supercell,eff_pot%supercell) 1390 else 1391 call init_supercell(eff_pot%crystal%natom, (/ncell(1),0,0, 0,ncell(2),0, 0,0,ncell(3)/), & 1392 & eff_pot%crystal%rprimd,eff_pot%crystal%typat,eff_pot%crystal%xcart,& 1393 & eff_pot%crystal%znucl, eff_pot%supercell) 1394 end if 1395 1396 !Initialisation of new mpi over supercell 1397 call effective_potential_initmpi(eff_pot,comm) 1398 1399 end subroutine effective_potential_setSupercell
m_effective_potential/effective_potential_type [ Types ]
[ Top ] [ m_effective_potential ] [ Types ]
NAME
effective_potential_type
FUNCTION
datatype for a effective potential constructed.
SOURCE
104 type, public :: effective_potential_type 105 106 character(len=fnlen) :: name 107 ! Name of the molecule (CaTiO3,...) 108 109 type(crystal_t) :: crystal 110 ! crystal type 111 ! contains all information of the crystal 112 113 real(dp):: energy 114 ! Energy of the system (Hatree) 115 116 real(dp), allocatable :: fcart(:,:) 117 ! forces(3,natom) 118 ! initial cartesian forces of the system 119 120 real(dp) :: strten(6) 121 ! strten(6) 122 ! initial stresses (Ha/bohr^3) of the system 123 124 type(harmonics_terms_type) :: harmonics_terms 125 ! type with all information for harmonics terms 126 127 type(anharmonics_terms_type) :: anharmonics_terms 128 ! type with all information for anharmonics terms 129 130 type(polynomial_conf_type) :: confinement 131 ! type with all the information for the confinement 132 133 type(supercell_type) :: supercell 134 ! super cell type 135 ! Store all the information of the suppercell 136 137 logical :: has_anharmonicsTerms 138 ! True : the aharmonic part is present 139 140 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 141 ! This is for the parallelisation over the supercell 142 type(effpot_mpi_type) :: mpi_ifc 143 ! effpot_mpi_type with all the information for the IFC paralellisation 144 145 type(effpot_mpi_type) :: mpi_coeff 146 ! effpot_mpi_type with all the information for the polynomial coefficients paralellisation 147 148 end type effective_potential_type
m_effective_potential/effective_potential_writeAbiInput [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_writeAbiInput
FUNCTION
This routine print the effective potential into input of abinit We can also apply a strain to the structure
INPUTS
eff_pot<type(effective_potential_type)> = effective_potential datatype filename = the name of input file strain<(strain_type)> = optional,strain datatype if need to apply strain into rprim
OUTPUT
SOURCE
1998 subroutine effective_potential_writeAbiInput(eff_pot,filename,strain) 1999 2000 !Arguments ------------------------------------ 2001 !scalars 2002 type(strain_type),optional,intent(in) :: strain 2003 character(len=fnlen),optional,intent(in) :: filename 2004 !arrays 2005 type(effective_potential_type), intent(in) :: eff_pot 2006 !Local variables------------------------------- 2007 !scalar 2008 integer :: unit = 20 2009 character(len=500) :: msg 2010 character(len=fnlen) :: namefile 2011 !arrays 2012 real(dp) :: xred(3,eff_pot%crystal%natom) 2013 type(strain_type) :: strain_tmp 2014 2015 ! ************************************************************************ 2016 2017 if(present(strain)) then 2018 strain_tmp = strain 2019 else 2020 call strain_init(strain_tmp) 2021 end if 2022 2023 ! try to open the file 2024 if(present(filename)) then 2025 namefile=filename 2026 else 2027 if(eff_pot%name /='') then 2028 write(namefile,'(a)') 'structure_'//trim(eff_pot%name) 2029 else 2030 write(namefile,'(a)') 'structure' 2031 end if 2032 if (strain_tmp%name/='') then 2033 write(namefile,'(a,a,a,a,a,a,a)') trim(namefile)//"_"//trim(strain_tmp%name)//"_"//& 2034 & trim(itoa(strain_tmp%direction)),"_"//trim(ftoa(strain_tmp%delta)) 2035 end if 2036 2037 namefile=trim(namefile)//".in" 2038 2039 end if 2040 2041 call isfile(namefile,'new') 2042 2043 if (open_file(namefile,msg,unit=unit,form="formatted",status="new",action="write") /= 0) then 2044 ABI_ERROR(msg) 2045 end if 2046 2047 write(msg,'(a,a,a,a)')ch10,& 2048 & ' Generation of the input file in ',namefile,ch10 2049 call wrtout(ab_out,msg,'COLL') 2050 call wrtout(std_out,msg,'COLL') 2051 2052 write(unit,'("#Abinit Input for DFPT, this file contrains the keyword")') 2053 write(unit,'("#To run DFPT calculation of")') 2054 write(unit,'(a)') trim(eff_pot%name) 2055 if (strain_tmp%direction /= 0) then 2056 write(unit,'("# With a perturbation ")',advance="no") 2057 write(unit,'(a)',advance="no") trim(strain_tmp%name) 2058 write(unit,'(" in the direction : ")',advance="no") 2059 write(unit,'(a)',advance='no') trim(itoa(strain_tmp%direction)) 2060 write(unit,'(" with the deformation : ")',advance="no") 2061 write(unit,'(a)') trim(ftoa(strain_tmp%delta)) 2062 end if 2063 2064 write(unit,'("")') 2065 write(unit,'("ndtset 1 jdtset 1 2 3")') 2066 write(unit,'("")') 2067 write(unit,'("#DATASET1 GROUND STATE")') 2068 write(unit,'("tolwfr1 = 1d-15")') 2069 write(unit,'(" prtwf1 = 1")') 2070 write(unit,'(" nline1 = 5")') 2071 2072 write(unit,'("")') 2073 write(unit,'("#DATASET2 DDK PERTURBATION")') 2074 write(unit,'("getwfk2 = 1")') 2075 write(unit,'(" iscf2 = -3")') 2076 write(unit,'(" nline2 = 15")') 2077 write(unit,'("nnsclo2 = 5")') 2078 write(unit,'("kptopt2 = 2")') 2079 write(unit,'(" nqpt2 = 1")') 2080 write(unit,'(" qpt2 = 0 0 0 ")') 2081 write(unit,'("rfelfd2 = 2")') 2082 write(unit,'(" rfdir2 = 1 1 1 ")') 2083 write(unit,'("tolwfr2 = 1.0d-20 ")') 2084 write(unit,'(" prtwf2 = 1 ")') 2085 write(unit,'(" ")') 2086 2087 write(unit,'("#DATASET3 RF")') 2088 write(unit,'(" getddk3 = 2")') 2089 write(unit,'(" getwfk3 = 1")') 2090 write(unit,'(" iscf3 = 7")') 2091 write(unit,'(" kptopt3 = 2")') 2092 write(unit,'(" nqpt3 = 1")') 2093 write(unit,'(" qpt3 = 0 0 0")') 2094 write(unit,'(" rfphon3 = 1")') 2095 write(unit,'("rfatpol3 = 1 ")',advance='no') 2096 write(unit,'(a)') itoa(eff_pot%crystal%natom) 2097 write(unit,'(" rfelfd3 = 3")') 2098 write(unit,'(" rfstrs3 = 3")') 2099 write(unit,'(" rfdir3 = 1 1 1")') 2100 write(unit,'(" tolvrs3 = 1.0d-8")') 2101 write(unit,'("")') 2102 2103 write(unit,'("#STRUCTURE")') 2104 write(unit,'(" natom = ")',advance='no') 2105 write(unit,'(a)') itoa(eff_pot%crystal%natom) 2106 write(unit,'(" znucl =")',advance='no') 2107 write(unit,'(10(F4.0))') (eff_pot%crystal%znucl) 2108 write(unit,'("ntypat = ")',advance='no') 2109 write(unit,'(a)') itoa(eff_pot%crystal%ntypat) 2110 write(unit,'(" typat = ")',advance='no') 2111 write(unit,'(10(I2))') (eff_pot%crystal%typat) 2112 write(unit,'(" acell = 1 1 1")') 2113 write(unit,'(" rprim ")') 2114 write(unit,'(3(F20.10))') (matmul(eff_pot%crystal%rprimd,strain%strain)) 2115 write(unit,'(" xred ")') 2116 call xcart2xred(eff_pot%crystal%natom,eff_pot%crystal%rprimd,eff_pot%crystal%xcart,xred) 2117 write(unit,'(3(F15.10))') (xred) 2118 write(unit,'(" ")') 2119 2120 write(unit,'("#SCF")') 2121 write(unit,'(" ecut = ")') 2122 write(unit,'("pawecutdg = ")') 2123 write(unit,'(" ecutsm = ")') 2124 write(unit,'(" tolvrs = ")') 2125 write(unit,'(" nband = ")') 2126 write(unit,'(" ixc = ")') 2127 write(unit,'(" occopt = ")') 2128 write(unit,'(" nstep = ")') 2129 write(unit,'(" kptopt = ")') 2130 write(unit,'(" ngkpt = ")') 2131 write(unit,'("")') 2132 write(unit,'(" prtwf 0 prtden 0 prtdos 0")') 2133 2134 close(unit) 2135 2136 end subroutine effective_potential_writeAbiInput
m_effective_potential/effective_potential_writeNETCDF [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_writeNETCDF
FUNCTION
This routine print the effective potential into netcdf format Several options are available
INPUTS
filename = the name of output file eff_pot = datatype contains the effective potential option = option for the format of the xml file 1 print the xml for a system
OUTPUT
SOURCE
3598 subroutine effective_potential_writeNETCDF(eff_pot,option,filename) 3599 3600 !Arguments ------------------------------------ 3601 !scalars 3602 integer, intent(in) :: option 3603 character(len=fnlen),optional,intent(in) :: filename 3604 !arrays 3605 type(effective_potential_type), intent(in) :: eff_pot 3606 3607 !Local variables------------------------------- 3608 !scalar 3609 integer :: amu_id,bec_id,ifccell_id,epsinf_id,elastic_id 3610 integer :: ifc_id,ifcs_id,natom_id,ntypat_id,nrpt_id,npsp_id,typat_id 3611 integer :: six_id,two_id,xyz_id,znucl_id 3612 integer :: ncerr,ncid,npsp 3613 integer :: dimCids(2),dimEids(2),dimIids(6),dimPids(1),dimRids(2),dimXids(2) 3614 integer :: etotal_id,rprimd_id,xcart_id 3615 character(len=500) :: msg 3616 character(len=fnlen) :: namefile 3617 !arrays 3618 real(dp) :: strain(9,6) 3619 3620 ! ************************************************************************* 3621 3622 #if defined HAVE_NETCDF 3623 3624 strain(:,1) = (/1,0,0,0,0,0,0,0,0/) 3625 strain(:,2) = (/0,0,0,0,1,0,0,0,0/) 3626 strain(:,3) = (/0,0,0,0,0,0,0,0,1/) 3627 strain(:,4) = half*(/0,0,0,0,0,1,0,1,0/) 3628 strain(:,5) = half*(/0,0,1,0,0,0,1,0,0/) 3629 strain(:,6) = half*(/0,1,0,1,0,0,0,0,0/) 3630 3631 !Print only the reference system in xml format 3632 if (option == 1) then 3633 3634 if(present(filename)) then 3635 namefile=filename 3636 else 3637 namefile='ref.nc' 3638 end if 3639 3640 call isfile(namefile,'new') 3641 3642 write(msg,'(a,a,a)')ch10,& 3643 & ' Generation of the xml file for the reference structure in ',namefile 3644 3645 call wrtout(ab_out,msg,'COLL') 3646 call wrtout(std_out,msg,'COLL') 3647 3648 ! 1. Create netCDF file 3649 ncerr = nf90_create(path=trim(namefile),cmode=NF90_CLOBBER, ncid=ncid) 3650 NCF_CHECK_MSG(ncerr,"create netcdf history file") 3651 3652 ! 2. Define dimensions 3653 ncerr = nf90_def_dim(ncid,"natom",eff_pot%crystal%natom,natom_id) 3654 NCF_CHECK_MSG(ncerr," define dimension natom") 3655 3656 ncerr = nf90_def_dim(ncid,"ntypat",eff_pot%crystal%ntypat,ntypat_id) 3657 NCF_CHECK_MSG(ncerr," define dimension ntypat") 3658 3659 ncerr = nf90_def_dim(ncid,"nrpt",eff_pot%harmonics_terms%ifcs%nrpt,nrpt_id) 3660 NCF_CHECK_MSG(ncerr," define dimension ntypat") 3661 3662 ncerr = nf90_def_var(ncid, "typat", NF90_INT, natom_id, typat_id) 3663 NCF_CHECK_MSG(ncerr," define variable typat") 3664 3665 npsp = size(eff_pot%crystal%znucl) 3666 if (npsp /= eff_pot%crystal%ntypat) then 3667 ABI_WARNING("HIST file does not support alchemical mixing!") 3668 end if 3669 ncerr = nf90_def_dim(ncid,"npsp",npsp,npsp_id) 3670 NCF_CHECK_MSG(ncerr," define dimension npsp") 3671 3672 ncerr = nf90_def_var(ncid, "znucl", NF90_DOUBLE, npsp_id, znucl_id) 3673 NCF_CHECK_MSG(ncerr," define variable znucl") 3674 3675 ncerr = nf90_def_dim(ncid,"xyz",3,xyz_id) 3676 NCF_CHECK_MSG(ncerr," define dimension xyz") 3677 3678 ncerr = nf90_def_dim(ncid,"six",6,six_id) 3679 NCF_CHECK_MSG(ncerr," define dimension six") 3680 3681 ncerr = nf90_def_dim(ncid,"two",2,two_id) 3682 NCF_CHECK_MSG(ncerr," define dimension two") 3683 3684 ! Dimensions for xcart,xred,fcart,gred and vel 3685 dimXids = (/ xyz_id, natom_id /) 3686 ! Dimensions for rprimd 3687 dimRids = (/ xyz_id, xyz_id /) 3688 ! Dimensions for ifc 3689 dimIids = (/ 2, xyz_id, natom_id, xyz_id, natom_id, nrpt_id /) 3690 ! Dimensions for position 3691 dimPids = (/ xyz_id /) 3692 ! Dimension for elastic constant 3693 dimEids = (/six_id,six_id/) 3694 ! Dimension for cell 3695 dimCids = (/nrpt_id,3/) 3696 3697 ! 3. Define variables and their attributes (units and mnemonics) 3698 call ab_define_var(ncid, (/1/), etotal_id, NF90_DOUBLE,& 3699 & "energy","Energy of the reference structure","Ha" ) 3700 3701 call ab_define_var(ncid, dimRids, rprimd_id, NF90_DOUBLE,& 3702 & "rprimd","Real space PRIMitive translations, Dimensional","bohr" ) 3703 3704 call ab_define_var(ncid, dimRids, epsinf_id, NF90_DOUBLE,& 3705 & "epsilon_inf","Dielectric tensor, Dimensional","epsilon_inf" ) 3706 3707 call ab_define_var(ncid, dimEids, elastic_id, NF90_DOUBLE,& 3708 & "elastic","Elastic Constants, Dimensional","Ha" ) 3709 3710 call ab_define_var(ncid, dimRids, bec_id, NF90_DOUBLE,& 3711 & "bec","Born Effective Charges, Dimensional","abs(e)" ) 3712 3713 call ab_define_var(ncid, dimXids, xcart_id, NF90_DOUBLE,& 3714 & "xcart","vectors (X) of atom positions in CARTesian coordinates","bohr" ) 3715 3716 call ab_define_var(ncid, dimIids, ifcs_id, NF90_DOUBLE,& 3717 & "IFCs","Interatomic Forces Constantes in real spaces (short range), Dimensional","Hatree/bohr**2" ) 3718 3719 call ab_define_var(ncid, dimIids, ifc_id, NF90_DOUBLE,& 3720 & "IFC","Interatomic Forces Constantes in real spaces (total range), Dimensional","Hatree/bohr**2" ) 3721 3722 call ab_define_var(ncid, dimCids, ifccell_id, NF90_DOUBLE,& 3723 & "cell","cell for the ifc, Dimensional","Dimensionless" ) 3724 3725 call ab_define_var(ncid, [ntypat_id], amu_id, NF90_DOUBLE,& 3726 & "amu","Masses of each type of atom in atomic mass units", "" ) 3727 3728 ! 4. End define mode 3729 ncerr = nf90_enddef(ncid) 3730 NCF_CHECK_MSG(ncerr," end define mode") 3731 3732 ! 5. Write variables 3733 ncerr = nf90_put_var(ncid,etotal_id, eff_pot%energy) 3734 NCF_CHECK_MSG(ncerr," write variable energy") 3735 3736 ncerr = nf90_put_var(ncid,rprimd_id, eff_pot%crystal%rprimd) 3737 NCF_CHECK_MSG(ncerr," write variable rprimd") 3738 3739 ncerr = nf90_put_var(ncid,epsinf_id, eff_pot%harmonics_terms%epsilon_inf) 3740 NCF_CHECK_MSG(ncerr," write variable epsilon_inf") 3741 3742 ncerr = nf90_put_var(ncid,elastic_id , eff_pot%harmonics_terms%elastic_constants) 3743 NCF_CHECK_MSG(ncerr," write variable elastic_constant") 3744 3745 ncerr = nf90_put_var(ncid, bec_id, eff_pot%harmonics_terms%zeff) 3746 NCF_CHECK_MSG(ncerr," write variable bec") 3747 3748 ncerr = nf90_put_var(ncid,xcart_id, eff_pot%crystal%xcart) 3749 NCF_CHECK_MSG(ncerr," write variable xcart") 3750 3751 ncerr = nf90_put_var(ncid,ifccell_id, eff_pot%harmonics_terms%ifcs%cell) 3752 NCF_CHECK_MSG(ncerr," write variable cell") 3753 3754 ncerr = nf90_put_var(ncid,ifcs_id, eff_pot%harmonics_terms%ifcs%short_atmfrc) 3755 NCF_CHECK_MSG(ncerr," write variable short ifc") 3756 3757 ncerr = nf90_put_var(ncid,ifc_id, eff_pot%harmonics_terms%ifcs%atmfrc) 3758 NCF_CHECK_MSG(ncerr," write variable total ifc") 3759 3760 3761 ! 6. Close NetCDF file 3762 ncerr = nf90_close(ncid) 3763 NCF_CHECK_MSG(ncerr," close netcdf history file") 3764 end if 3765 3766 #endif 3767 end subroutine effective_potential_writeNETCDF
m_effective_potential/effective_potential_writeXML [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
effective_potential_writeXML
FUNCTION
This routine print the effective potential into xml format Several options are available
INPUTS
filename = the name of output file eff_pot<type(effective_potential_type)> = effective_potential datatype option = 0 Do nothing = 1 Generate the XML file with: - The system definition and the model (Harmonic + Anharmonic) = 2 Generate two XML files with: - The system definition and the model (Harmonic) - The model (Anharmonic) = 3 Generate one XML files with: - The system definition and the model (Harmonic) = 4 Generate one XML files with: - The model (Anharmonic)
OUTPUT
SOURCE
1679 subroutine effective_potential_writeXML(eff_pot,option,filename,prt_dipdip) 1680 1681 !Arguments ------------------------------------ 1682 !scalars 1683 integer, intent(in) :: option 1684 character(len=fnlen),optional,intent(in) :: filename 1685 logical,optional,intent(in) :: prt_dipdip 1686 !arrays 1687 type(effective_potential_type), intent(in) :: eff_pot 1688 1689 !Local variables------------------------------- 1690 !scalar 1691 integer :: ii,ia,ib,jj 1692 integer :: iqpt,irpt,mu,nu 1693 integer :: unit_xml 1694 character(len=500) :: msg 1695 character(len=fnlen) :: namefile 1696 character(len=10) :: natom 1697 logical :: new_file,need_prtdipdip 1698 !arrays 1699 real(dp) :: strain(9,6) 1700 1701 ! ************************************************************************* 1702 1703 strain(:,1) = (/1,0,0,0,0,0,0,0,0/) 1704 strain(:,2) = (/0,0,0,0,1,0,0,0,0/) 1705 strain(:,3) = (/0,0,0,0,0,0,0,0,1/) 1706 strain(:,4) = half*(/0,0,0,0,0,1,0,1,0/) 1707 strain(:,5) = half*(/0,0,1,0,0,0,1,0,0/) 1708 strain(:,6) = half*(/0,1,0,1,0,0,0,0,0/) 1709 1710 unit_xml = get_unit() 1711 need_prtdipdip = .TRUE. 1712 if(present(prt_dipdip)) need_prtdipdip = prt_dipdip 1713 !Print only the reference system in xml format 1714 if (option == 1 .or. option == 2 .or. option ==3) then 1715 1716 ! convert natom in character 1717 write (natom,'(I9)') eff_pot%crystal%natom 1718 1719 ! Compute the name of the XML file 1720 if(present(filename)) then 1721 namefile=replace(trim(filename),".out","") 1722 select case(option) 1723 case(1) 1724 namefile=trim(namefile)//"_model.xml" 1725 case(2) 1726 namefile=trim(namefile)//"_sys.xml" 1727 case(3) 1728 namefile=trim(namefile)//"_sys.xml" 1729 end select 1730 else 1731 namefile='system.xml' 1732 end if 1733 1734 call isfile(namefile,'new') 1735 1736 if (open_file(namefile,msg,unit=unit_xml,form="formatted",& 1737 & status="new",action="write") /= 0) then 1738 ABI_ERROR(msg) 1739 end if 1740 1741 write(msg,'(a,a,a)')ch10,& 1742 & ' Generation of the xml file for the model in ',trim(namefile) 1743 1744 call wrtout(ab_out,msg,'COLL') 1745 call wrtout(std_out,msg,'COLL') 1746 1747 ! Write header 1748 WRITE(unit_xml,'("<?xml version=""1.0"" ?>")') 1749 WRITE(unit_xml,'("<System_definition>")') 1750 1751 WRITE(unit_xml,'(" <energy>")') 1752 WRITE(unit_xml,'(E23.14)') (eff_pot%energy) 1753 WRITE(unit_xml,'(" </energy>")') 1754 1755 WRITE(unit_xml,'(" <unit_cell units=""bohrradius"">")') 1756 do mu=1,3 1757 WRITE(unit_xml,'(3(E23.14))') (eff_pot%crystal%rprimd(mu,nu),nu=1,3) 1758 end do 1759 WRITE(unit_xml,'(" </unit_cell>")') 1760 1761 WRITE(unit_xml,'(" <epsilon_inf units=""epsilon0"">")') 1762 WRITE(unit_xml,'(3(E23.14))') (eff_pot%harmonics_terms%epsilon_inf) 1763 WRITE(unit_xml,'(" </epsilon_inf>")') 1764 1765 WRITE(unit_xml,'(" <elastic units=""hartree"">")') 1766 WRITE(unit_xml,'(6(E23.14))') (eff_pot%harmonics_terms%elastic_constants) 1767 WRITE(unit_xml,'(" </elastic>")') 1768 1769 do ia=1,eff_pot%crystal%natom 1770 WRITE(unit_xml,'(" <atom mass=""",1F10.5,""" massunits=""atomicmassunit"">")') & 1771 & eff_pot%crystal%amu(eff_pot%crystal%typat(ia)) 1772 WRITE(unit_xml,'(" <position units=""bohrradius"">")') 1773 WRITE(unit_xml,'(3(E23.14))') (eff_pot%crystal%xcart(:,ia)) 1774 WRITE(unit_xml,'(" </position>")') 1775 WRITE(unit_xml,'(" <borncharge units=""abs(e)"">")') 1776 WRITE(unit_xml,'(3(E23.14))') (eff_pot%harmonics_terms%zeff(:,:,ia)) 1777 WRITE(unit_xml,'(" </borncharge>")') 1778 WRITE(unit_xml,'(" </atom>")') 1779 end do 1780 ! Print the Ifc short range for each cell data is array 3*natom*3*natom 1781 ! [ [x1 x2 ....] 1782 ! [y1 y2 ....] for atom 1 1783 ! [z1 z2 ....] 1784 ! [x1 x2 ....] 1785 ! [y1 y2 ....] for atom 2 1786 ! [z1 z2 ....] 1787 ! .... ] 1788 ! Warning : The IFC are print in other order 1,mu,ia,nu,ib which is not fortran way 1789 ! We do like that to because the previous script was in python 1790 ! When you read ifc from XML file with fotran, you have to tranpose the matrix 1791 ! 1792 do irpt=1,eff_pot%harmonics_terms%ifcs%nrpt 1793 if(any(abs(eff_pot%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt))>tol20)) then 1794 WRITE(unit_xml,'(" <local_force_constant units=""hartree/bohrradius**2"">")') 1795 WRITE(unit_xml,'(" <data>")') 1796 do ia=1,eff_pot%crystal%natom 1797 do mu=1,3 1798 do ib=1,eff_pot%crystal%natom 1799 do nu=1,3 1800 WRITE(unit_xml,'(e22.14)', advance="no")& 1801 & (eff_pot%harmonics_terms%ifcs%short_atmfrc(mu,ia,nu,ib,irpt)) 1802 end do 1803 end do 1804 WRITE(unit_xml,'(a)')'' 1805 end do 1806 end do 1807 WRITE(unit_xml,'(" </data>")') 1808 WRITE(unit_xml,'(" <cell>")') 1809 WRITE(unit_xml,'(3(I4))') (eff_pot%harmonics_terms%ifcs%cell(:,irpt)) 1810 WRITE(unit_xml,'(" </cell>")') 1811 WRITE(unit_xml,'(" </local_force_constant>")') 1812 end if 1813 ! Print the IFC total for each cell, data is array 3*natom*3*natom 1814 ! [ [x1 x2 ....] 1815 ! [y1 y2 ....] for atom 1 1816 ! [z1 z2 ....] 1817 ! [x1 x2 ....] 1818 ! [y1 y2 ....] for atom 2 1819 ! [z1 z2 ....] 1820 ! .... ] 1821 if(need_prtdipdip)then 1822 if(all(abs(eff_pot%harmonics_terms%ifcs%atmfrc(:,:,:,:,irpt))<tol20)) then 1823 if(any(abs(eff_pot%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt))>tol20)) then 1824 write(msg, '(a,a,a,a)' )& 1825 & ' There is no total range but short range in your effective potential',ch10,& 1826 & 'Action: contact abinit group' 1827 ABI_BUG(msg) 1828 end if 1829 else 1830 WRITE(unit_xml,'(" <total_force_constant units=""hartree/bohrradius**2"">")') 1831 WRITE(unit_xml,'(" <data>")') 1832 do ia=1,eff_pot%crystal%natom 1833 do mu=1,3 1834 do ib=1,eff_pot%crystal%natom 1835 do nu=1,3 1836 WRITE(unit_xml,'(e22.14)', advance="no")& 1837 & (eff_pot%harmonics_terms%ifcs%atmfrc(mu,ia,nu,ib,irpt)) 1838 end do 1839 end do 1840 WRITE(unit_xml,'(a)')'' 1841 end do 1842 end do 1843 WRITE(unit_xml,'(" </data>")') 1844 WRITE(unit_xml,'(" <cell>")') 1845 WRITE(unit_xml,'(3(I4))') (eff_pot%harmonics_terms%ifcs%cell(:,irpt)) 1846 WRITE(unit_xml,'(" </cell>")') 1847 WRITE(unit_xml,'(" </total_force_constant>")') 1848 end if 1849 end if 1850 end do 1851 1852 do iqpt=1,eff_pot%harmonics_terms%nqpt 1853 WRITE(unit_xml,'(" <phonon>")') 1854 WRITE(unit_xml,'(" <qpoint units=""2pi*G0"">")') 1855 WRITE(unit_xml,'(3(E23.14))') (eff_pot%harmonics_terms%qpoints(:,iqpt)) 1856 WRITE(unit_xml,'(" </qpoint>")') 1857 WRITE(unit_xml,'(" <frequencies units=""reciprocal cm"">")') 1858 WRITE(unit_xml,'(3(e22.14))') (eff_pot%harmonics_terms%phfrq(:,iqpt)) 1859 WRITE(unit_xml,'(" </frequencies>")') 1860 WRITE(unit_xml,'(" <dynamical_matrix units=""hartree/bohrradius**2"">")') 1861 do ia=1,eff_pot%crystal%natom 1862 do mu=1,3 1863 do ib = 1,eff_pot%crystal%natom 1864 do nu=1,3 1865 WRITE(unit_xml,'(e22.14)',advance='no')(eff_pot%harmonics_terms%dynmat(1,nu,ib,mu,ia,iqpt)) 1866 end do 1867 end do 1868 WRITE(unit_xml,'(a)')'' 1869 end do 1870 end do 1871 WRITE(unit_xml,'(" </dynamical_matrix>")') 1872 WRITE(unit_xml,'(" </phonon>")') 1873 end do 1874 ! if phonon/forces strain is computed 1875 jj = 1 1876 do ii = 1,6 1877 WRITE(unit_xml,'(" <strain_coupling voigt=""",I2,""">")') ii-1 1878 WRITE(unit_xml,'(" <strain>")') 1879 WRITE(unit_xml,'(6(e12.4))') (strain(:,jj)) 1880 WRITE(unit_xml,'(" </strain>")') 1881 WRITE(unit_xml,'(" <correction_force units=""hartree/bohrradius"">")') 1882 do ia=1,eff_pot%crystal%natom 1883 do mu=1,3 1884 WRITE(unit_xml,'(e22.14)', advance="no")& 1885 & (eff_pot%harmonics_terms%strain_coupling(ii,mu,ia)) 1886 end do 1887 WRITE(unit_xml,'(a)')'' 1888 end do 1889 WRITE(unit_xml,'(" </correction_force>")') 1890 if (eff_pot%has_anharmonicsTerms)then 1891 if (eff_pot%anharmonics_terms%has_elastic3rd) then 1892 WRITE(unit_xml,'(" <elastic3rd units=""hartree"">")') 1893 WRITE(unit_xml,'(6(E23.14))') (eff_pot%anharmonics_terms%elastic3rd(ii,:,:)) 1894 WRITE(unit_xml,'(" </elastic3rd>")') 1895 end if 1896 if (eff_pot%anharmonics_terms%has_elastic_displ) then 1897 WRITE(unit_xml,'(" <correction_strain_force units=""hartree/bohrradius"">")') 1898 do ia=1,eff_pot%crystal%natom 1899 do mu=1,3 1900 do nu=1,6 1901 WRITE(unit_xml,'(e22.14)', advance="no")& 1902 & (eff_pot%anharmonics_terms%elastic_displacement(ii,nu,mu,ia)) 1903 end do 1904 end do 1905 WRITE(unit_xml,'(a)')'' 1906 end do 1907 WRITE(unit_xml,'(" </correction_strain_force>")') 1908 end if 1909 if (eff_pot%anharmonics_terms%has_strain_coupling) then 1910 do irpt=1,eff_pot%anharmonics_terms%phonon_strain(ii)%nrpt 1911 WRITE(unit_xml,'(" <correction_force_constant units=""hartree/bohrradius**2"">")') 1912 WRITE(unit_xml,'(" <data>")') 1913 do ia=1,eff_pot%crystal%natom 1914 do mu=1,3 1915 do ib=1,eff_pot%crystal%natom 1916 do nu=1,3 1917 WRITE(unit_xml,'(e22.14)', advance="no")& 1918 & (eff_pot%anharmonics_terms%phonon_strain(ii)%atmfrc(mu,ia,nu,ib,irpt)) 1919 end do 1920 end do 1921 WRITE(unit_xml,'(a)')'' 1922 end do 1923 end do 1924 WRITE(unit_xml,'(" </data>")') 1925 WRITE(unit_xml,'(" <cell>")') 1926 WRITE(unit_xml,'(3(I4))') (eff_pot%anharmonics_terms%phonon_strain(ii)%cell(:,irpt)) 1927 WRITE(unit_xml,'(" </cell>")') 1928 WRITE(unit_xml,'(" </correction_force_constant>")') 1929 end do 1930 end if!End if has_straincouplitn 1931 end if!end Hasstrain_coupling 1932 WRITE(unit_xml,'(" </strain_coupling>")') 1933 jj = jj + 1 1934 end do!end mu 1935 1936 if(option /=1) WRITE(unit_xml,'("</System_definition>")') 1937 ! Close file 1938 CLOSE(unit_xml) 1939 1940 end if!end option 1941 1942 !Print the coefficients into XML file 1943 new_file = .FALSE. 1944 if (option==1 .or. option == 2 .or. option==4) then 1945 ! Compute the name of the XML file 1946 if(present(filename)) then 1947 namefile=replace(trim(filename),".out","") 1948 select case(option) 1949 case(1) 1950 new_file = .FALSE. 1951 namefile=trim(namefile)//"_model.xml" 1952 case(2) 1953 new_file = .TRUE. 1954 namefile=trim(namefile)//"_coeffs.xml" 1955 case(4) 1956 new_file = .TRUE. 1957 namefile=trim(namefile)//"_coeffs.xml" 1958 end select 1959 else 1960 namefile='coeffs.xml' 1961 end if 1962 1963 if(eff_pot%anharmonics_terms%ncoeff > 0) then 1964 call polynomial_coeff_writeXML(eff_pot%anharmonics_terms%coefficients,& 1965 & eff_pot%anharmonics_terms%ncoeff,namefile,unit=unit_xml,& 1966 & newfile=new_file) 1967 end if 1968 end if!end option 1969 1970 if(option==1)then 1971 ! add the end of the file in the case option==1 1972 open(unit=unit_xml,file=namefile,position="append") 1973 WRITE(unit_xml,'("</System_definition>")') 1974 ! Close file 1975 CLOSE(unit_xml) 1976 end if 1977 1978 end subroutine effective_potential_writeXML
m_effective_potential/equal [ Functions ]
[ Top ] [ m_effective_potential ] [ Functions ]
NAME
equal
FUNCTION
compare two effective potential
INPUTS
e1<type(effective_potential_type)> = effective_potential datatype e2<type(effective_potential_type)> = effective_potential datatype
OUTPUT
SOURCE
3007 pure function effective_potential_compare(e1,e2) result (res) 3008 3009 !Arguments ------------------------------------ 3010 type(effective_potential_type), intent(in) :: e1,e2 3011 logical :: res 3012 ! ************************************************************************* 3013 res = .false. 3014 if(e1%crystal%natom==e2%crystal%natom.and.& 3015 & e1%harmonics_terms%ifcs%nrpt==e2%harmonics_terms%ifcs%nrpt.and.& 3016 & e1%crystal%ntypat==e2%crystal%ntypat.and.& 3017 & e1%harmonics_terms%nqpt==e2%harmonics_terms%nqpt.and.& 3018 & abs(e1%energy-e2%energy)<tol16.and.& 3019 & abs(e1%crystal%ucvol-e2%crystal%ucvol)<tol16) then 3020 res = .true. 3021 end if 3022 3023 end function effective_potential_compare