TABLE OF CONTENTS
- ABINIT/m_fit_polynomial_coeff
- m_fit_polynomial_coeff/fit_polynomial_coeff_computeGF
- m_fit_polynomial_coeff/fit_polynomial_coeff_computeMSD
- m_fit_polynomial_coeff/fit_polynomial_coeff_fit
- m_fit_polynomial_coeff/fit_polynomial_coeff_getCoeffBound
- m_fit_polynomial_coeff/fit_polynomial_coeff_getFS
- m_fit_polynomial_coeff/fit_polynomial_coeff_getPositive
- m_fit_polynomial_coeff/fit_polynomial_coeff_solve
- m_fit_polynomial_coeff/fit_polynomial_printSystemFiles
- m_fit_polynomiaL_coeff/testEffPot
ABINIT/m_fit_polynomial_coeff [ Modules ]
NAME
m_fit_polynomial_coeff
FUNCTION
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
18 #if defined HAVE_CONFIG_H 19 #include "config.h" 20 #endif 21 22 #include "abi_common.h" 23 24 module m_fit_polynomial_coeff 25 26 use defs_basis 27 use m_errors 28 use m_abicore 29 use m_polynomial_coeff 30 use m_atomdata 31 use m_xmpi 32 use m_supercell 33 34 use m_special_funcs,only : factorial 35 use m_geometry, only : xred2xcart 36 use m_crystal,only : symbols_crystal 37 use m_strain,only : strain_type,strain_get 38 use m_effective_potential,only : effective_potential_type, effective_potential_evaluate 39 use m_effective_potential,only : effective_potential_freeCoeffs,effective_potential_setCoeffs 40 use m_effective_potential,only : effective_potential_getDisp, effective_potential_writeAnhHead 41 use m_effective_potential,only : effective_potential_copy,effective_potential_free,effective_potential_init 42 use m_effective_potential_file, only : effective_potential_file_mapHistToRef 43 use m_io_tools, only : open_file,get_unit 44 use m_abihist, only : abihist,abihist_free,abihist_init,abihist_copy,write_md_hist,var2hist 45 use m_random_zbq 46 use m_fit_data 47 use m_geometry, only: metric 48 use m_scup_dataset 49 #if defined DEV_MS_SCALEUP 50 use scup_global, only : global_set_parent_iter,global_set_print_parameters 51 #endif 52 53 implicit none 54 55 public :: fit_polynomial_coeff_computeGF 56 public :: fit_polynomial_coeff_computeMSD 57 public :: fit_polynomial_coeff_fit 58 public :: fit_polynomial_coeff_getFS 59 public :: fit_polynomial_coeff_getPositive 60 public :: fit_polynomial_coeff_getCoeffBound 61 public :: fit_polynomial_coeff_solve 62 public :: fit_polynomial_coeff_testEffPot 63 public :: fit_polynomial_printSystemFiles 64 public :: genereList
m_fit_polynomial_coeff/fit_polynomial_coeff_computeGF [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_computeGF
FUNCTION
Compute the values of the goal function (Mean squared error) for gf_value(1) = stresses+forces (Ha/Bohr)**2 gf_value(2) = forces (Ha/Bohr)**2 gf_value(3) = stresses (Ha/Bohr)**2 gf_value(4) = energy (Ha)**2
INPUTS
coefficients(ncoeff) = type(polynomial_coeff_type) energy_coeffs(ncoeff,ntime) = value of the energy for each coefficient (Ha) energy_diff(ntime) = Difference of energ ybetween DFT calculation and fixed part of the model (more often harmonic part) fixed part of the model (more often harmonic part) fcart_coeffs(ncoeff,3,natom,ntime) = value of the forces for each coefficient (-1 factor is taking into acount) (Ha/Bohr) fcart_diff(3,natom,ntime) = Difference of cartesian forces between DFT calculation and fixed part of the model (more often harmonic part) list_coeffs(ncoeff_fit) = List with the indexes of the coefficients used for this model natom = Number of atoms ncoeff_fit = Number of coefficients fitted ncoeff_max = Maximum number of coeff in the list ntime = Number of time in the history strten_coeffs(ncoeff,3,natom,ntime)= value of the stresses for each coefficient (1/ucvol factor is taking into acount) (Ha/Bohr^3) strten_diff(6,natom) = Difference of stress tensor between DFT calculation and fixed part of the model (more often harmonic part) sqomega = Sheppard and al Factors \Omega^{2} see J.Chem Phys 136, 074103 (2012) [[cite:Sheppard2012]]
OUTPUT
gf_value(4) = Goal function
SOURCE
2115 subroutine fit_polynomial_coeff_computeGF(coefficients,energy_coeffs,energy_diff,& 2116 & fcart_coeffs,fcart_diff,gf_value,list_coeffs,& 2117 & natom,ncoeff_fit,ncoeff_max,ntime,strten_coeffs,& 2118 & strten_diff,sqomega) 2119 2120 implicit none 2121 2122 !Arguments ------------------------------------ 2123 !scalars 2124 integer,intent(in) :: natom,ncoeff_fit,ncoeff_max,ntime 2125 !arrays 2126 integer,intent(in) :: list_coeffs(ncoeff_fit) 2127 real(dp),intent(in) :: energy_coeffs(ncoeff_max,ntime) 2128 real(dp),intent(in) :: energy_diff(ntime) 2129 real(dp),intent(in) :: fcart_coeffs(3,natom,ncoeff_max,ntime) 2130 real(dp),intent(in) :: fcart_diff(3,natom,ntime) 2131 real(dp),intent(in) :: strten_coeffs(6,ntime,ncoeff_max) 2132 real(dp),intent(in) :: strten_diff(6,ntime),sqomega(ntime) 2133 real(dp),intent(in) :: coefficients(ncoeff_fit) 2134 real(dp),intent(out) :: gf_value(4) 2135 !Local variables------------------------------- 2136 !scalar 2137 integer :: ia,icoeff,icoeff_tmp,itime,mu 2138 real(dp):: etmp,emu,fmu,ftmp,smu,stmp 2139 real(dp) :: ffact,sfact,efact 2140 !arrays 2141 ! ************************************************************************* 2142 2143 !1-Compute the value of the goal function 2144 ! see equation 9 of PRB 95 094115(2017) [[cite:Escorihuela-Sayalero2017]] 2145 gf_value = zero 2146 etmp = zero 2147 ftmp = zero 2148 stmp = zero 2149 2150 !Compute factors 2151 ffact = one/(3*natom*ntime) 2152 sfact = one/(6*ntime) 2153 efact = one/(ntime) 2154 2155 ! loop over the configuration 2156 do itime=1,ntime 2157 ! Fill energy 2158 emu = zero 2159 do icoeff=1,ncoeff_fit 2160 icoeff_tmp = list_coeffs(icoeff) 2161 emu = emu + coefficients(icoeff)*energy_coeffs(icoeff_tmp,itime) 2162 end do 2163 ! uncomment the next line to be consistent with the definition of the goal function 2164 etmp = etmp + (energy_diff(itime)-emu)**2/(sqomega(itime)**(1.0/2.0)) 2165 ! uncomment the next get a measure in Ha instead of Ha^2 2166 ! etmp = etmp + abs(energy_diff(itime)-emu) 2167 ! Fill forces 2168 do ia=1,natom 2169 do mu=1,3 2170 fmu = zero 2171 do icoeff=1,ncoeff_fit 2172 icoeff_tmp = list_coeffs(icoeff) 2173 fmu = fmu + coefficients(icoeff)*fcart_coeffs(mu,ia,icoeff_tmp,itime) 2174 end do 2175 ftmp = ftmp + (fcart_diff(mu,ia,itime)-fmu)**2 2176 end do !End loop dir 2177 end do !End loop natom 2178 do mu=1,6 2179 smu = zero 2180 do icoeff=1,ncoeff_fit 2181 icoeff_tmp = list_coeffs(icoeff) 2182 smu = smu + coefficients(icoeff)*strten_coeffs(mu,itime,icoeff_tmp) 2183 end do 2184 stmp = stmp + sqomega(itime)*(strten_diff(mu,itime)-smu)**2 2185 end do !End loop stress dir 2186 end do ! End loop time 2187 2188 gf_value(1) = ffact*ftmp + sfact*stmp !+ efact*etmp !Stresses + Forces 2189 gf_value(2) = ffact*ftmp ! only Forces 2190 gf_value(3) = sfact*stmp ! only Stresses 2191 gf_value(4) = efact*etmp !abs(Energy) 2192 2193 end subroutine fit_polynomial_coeff_computeGF
m_fit_polynomial_coeff/fit_polynomial_coeff_computeMSD [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_computeMSD
FUNCTION
Compute the Mean square error of the energy, forces and stresses
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 sqomega = Sheppard and al Factors \Omega^{2} see J.Chem Phys 136, 074103 (2012) [[cite:Sheppard2012]] compute_anharmonic = TRUE if the anharmonic part of the effective potential has to be taking into acount print_file = if True, a ASCII file with the difference in energy will be print
OUTPUT
mse = Mean square error of the energy (Hatree) msef = Mean square error of the forces (Hatree/Bohr)**2 mses = Mean square error of the stresses (Hatree/Bohr)**2
SOURCE
2507 subroutine fit_polynomial_coeff_computeMSD(eff_pot,hist,mse,msef,mses,natom,ntime,sqomega,comm,& 2508 & compute_anharmonic,print_file,filename,scup_dtset,prt_ph) 2509 2510 implicit none 2511 2512 !Arguments ------------------------------------ 2513 !scalars 2514 integer, intent(in) :: natom,ntime,comm 2515 real(dp),intent(out):: mse,msef,mses 2516 logical,optional,intent(in) :: compute_anharmonic,print_file,prt_ph 2517 !arrays 2518 real(dp),intent(in) :: sqomega(ntime) 2519 type(effective_potential_type),intent(in) :: eff_pot 2520 type(abihist),intent(in) :: hist 2521 !Strings/Characters 2522 character(len=fnlen),optional,intent(in) :: filename 2523 type(scup_dtset_type),optional,intent(inout) :: scup_dtset 2524 !Local variables------------------------------- 2525 !scalar 2526 integer :: ii,ia,mu,unit_energy,unit_stress,itime,master,nproc,my_rank,i 2527 !Uncommend for dipdip test 2528 integer :: ifirst 2529 real(dp):: energy,energy_harm 2530 logical :: need_anharmonic,need_print,need_elec_eval,iam_master 2531 logical :: need_prt_ph 2532 !arrays 2533 real(dp):: fcart(3,natom),gred(3,natom),strten(6),rprimd(3,3),xred(3,natom) 2534 !Strings/Characters 2535 character(len=fnlen) :: file_energy, file_stress, file_anh, name_file 2536 character(len=500) :: msg 2537 !Uncommend for dipdip test 2538 type(abihist) :: hist_out 2539 character(len=200) :: filename_hist 2540 2541 ! ************************************************************************* 2542 !MS Hide SCALE-UP variables 2543 ABI_UNUSED(itime) 2544 2545 !MPI 2546 master = 0 2547 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 2548 iam_master = (my_rank == master) 2549 2550 !Do some checks 2551 if(ntime /= hist%mxhist)then 2552 write(msg,'(a)')'ntime is not correct' 2553 ABI_BUG(msg) 2554 end if 2555 2556 if(natom /= size(hist%xred,2)) then 2557 write(msg,'(a)')'natom is not correct' 2558 ABI_BUG(msg) 2559 end if 2560 2561 need_anharmonic = .TRUE. 2562 if(present(compute_anharmonic))then 2563 need_anharmonic = compute_anharmonic 2564 end if 2565 2566 name_file='' 2567 if(present(filename))name_file = filename 2568 2569 need_print=.FALSE. 2570 if(present(print_file))need_print=print_file 2571 2572 need_elec_eval = .FALSE. 2573 if(present(scup_dtset))need_elec_eval=scup_dtset%scup_elec_model 2574 2575 need_prt_ph=.FALSE. 2576 if(present(prt_ph))need_prt_ph=prt_ph 2577 2578 2579 if(need_print .and. present(filename))then 2580 !MS hist out uncommented for PHONOPY test 2581 call abihist_init(hist_out,natom,ntime,.false.,.false.) 2582 file_energy=trim(name_file)//'_energy.dat' 2583 unit_energy = get_unit() 2584 if (open_file(file_energy,msg,unit=unit_energy,form="formatted",& 2585 & status="unknown",action="write") /= 0) then 2586 ABI_ERROR(msg) 2587 end if 2588 unit_stress = get_unit() 2589 file_stress=trim(name_file)//'_stress.dat' 2590 if (open_file(file_stress,msg,unit=unit_stress,form="formatted",& 2591 & status="unknown",action="write") /= 0) then 2592 ABI_ERROR(msg) 2593 end if 2594 else if(need_print .and. .not. present(filename))then 2595 write(msg,'(3a)')' You asked for printing of the MSD-values',ch10,& 2596 & ' without specifying a filename' 2597 ABI_ERROR(msg) 2598 end if 2599 2600 file_anh=trim(name_file)//'_anharmonic_terms_energy.dat' 2601 2602 mse = zero 2603 msef = zero 2604 mses = zero 2605 do ii=1,ntime ! Loop over configurations 2606 xred(:,:) = hist%xred(:,:,ii) 2607 rprimd(:,:) = hist%rprimd(:,:,ii) 2608 itime = ii 2609 #if defined DEV_MS_SCALEUP 2610 !Pass print options to scale-up 2611 itime = ii 2612 if(need_elec_eval)then 2613 call global_set_parent_iter(itime) 2614 ! Set all print options to false. 2615 call global_set_print_parameters(geom=.FALSE.,eigvals=.FALSE.,eltic=.FALSE.,& 2616 & orbocc=.FALSE.,bands=.FALSE.) 2617 if(ii == 1 .or. modulo(ii,scup_dtset%scup_printniter) == 0)then 2618 call global_set_print_parameters(scup_dtset%scup_printgeom,scup_dtset%scup_printeigv,scup_dtset%scup_printeltic,& 2619 & scup_dtset%scup_printorbocc,scup_dtset%scup_printbands) 2620 end if 2621 end if 2622 #endif 2623 call effective_potential_evaluate(eff_pot,energy_harm,fcart,gred,strten,natom,rprimd,& 2624 & xred=xred,compute_anharmonic=.False.,verbose=.false.,& 2625 & elec_eval=need_elec_eval) 2626 2627 call effective_potential_evaluate(eff_pot,energy,fcart,gred,strten,natom,rprimd,& 2628 & xred=xred,compute_anharmonic=need_anharmonic,verbose=.false.,& 2629 & filename=file_anh,elec_eval=need_elec_eval) 2630 2631 if(need_print .and. iam_master)then 2632 WRITE(unit_energy ,'(I10,7(F23.14))') ii,hist%etot(ii),energy_harm,energy,& 2633 & abs(hist%etot(ii) - energy_harm),abs(hist%etot(ii) - energy) 2634 WRITE(unit_stress,'(I10,12(F23.14))') ii,hist%strten(:,ii),strten(:) 2635 end if 2636 2637 !MS Uncommented for abihist test 2638 if(need_prt_ph)then 2639 if(ii == 1)then 2640 write(msg,'(a,(80a))') ch10,('-',i=1,80) 2641 call wrtout(ab_out,msg,'COLL') 2642 call wrtout(std_out,msg,'COLL') 2643 write(msg,'(3a)') ch10,'test_prt_ph == 1, write evulation of Model on the TEST-set into ph_test.nc',ch10 2644 call wrtout(ab_out,msg,'COLL') 2645 call wrtout(std_out,msg,'COLL') 2646 endif 2647 ifirst=merge(0,1,(ii>1)) 2648 filename_hist = trim("ph_test.nc") 2649 hist_out%fcart(:,:,hist_out%ihist) = fcart(:,:) 2650 hist_out%strten(:,hist_out%ihist) = strten(:) 2651 hist_out%etot(hist_out%ihist) = energy 2652 hist_out%entropy(hist_out%ihist) = hist%entropy(ii) 2653 hist_out%time(hist_out%ihist) = real(ii,kind=dp) 2654 ! call vel2hist(ab_mover%amass,hist,vel,vel_cell) 2655 call var2hist(hist%acell(:,ii),hist_out,natom,hist%rprimd(:,:,ii),hist%xred(:,:,ii),.false.) 2656 if(iam_master)then 2657 call write_md_hist(hist_out,filename_hist,ifirst,ii,natom,1,eff_pot%crystal%ntypat,& 2658 & eff_pot%supercell%typat,eff_pot%crystal%amu,eff_pot%crystal%znucl,& 2659 & real(100,dp),(/real(100,dp),real(100,dp)/)) 2660 endif 2661 endif!(need_prt_ph) 2662 2663 mse = mse + ((hist%etot(ii) - energy))**2/(sqomega(ii)**(1.0/2.0)) !+abs(hist$etot(ii) - energy) 2664 do ia=1,natom ! Loop over atoms 2665 do mu=1,3 ! Loop over cartesian directions 2666 msef = msef + (hist%fcart(mu,ia,ii) - fcart(mu,ia))**2 2667 end do 2668 end do 2669 do mu=1,6 ! Loop over stresses 2670 mses = mses + sqomega(ii)*(hist%strten(mu,ii) - strten(mu))**2 2671 end do 2672 end do ! End loop itime 2673 if(need_prt_ph)then 2674 write(msg,'(a,(80a))') ch10,('-',i=1,80) 2675 call wrtout(ab_out,msg,'COLL') 2676 call wrtout(std_out,msg,'COLL') 2677 endif 2678 2679 mse = mse / ntime 2680 msef = msef / (3*natom*ntime) 2681 mses = mses / (6*ntime) 2682 2683 if(need_print)then 2684 close(unit_energy) 2685 close(unit_stress) 2686 end if 2687 2688 !MS uncommented for PHONOPY TEST 2689 call abihist_free(hist_out) 2690 2691 end subroutine fit_polynomial_coeff_computeMSD
m_fit_polynomial_coeff/fit_polynomial_coeff_fit [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_fit
FUNCTION
Fit the list of coefficients included in eff_pot, if the coefficients are not set in eff_pot, this routine will genenerate a list of coefficients by taking into acount the symmetries of the system and the cutoff
INPUTS
eff_pot<type(effective_potential)> = effective potential bancoeff(nbancoeff) = list of bannned coeffcients, these coefficients will NOT be used during the fit process fixcoeff(nfixcoeff) = list of fixed coefficient, these coefficients will be imposed during the fit process hist<type(abihist)> = The history of the MD (or snapshot of DFT) generateterm = term to activate the generation of the term set power_disps(2) = array with the minimal and maximal power_disp to be computed nbancoeff = number of banned coeffcients ncycle_in = number of maximum cycle (maximum coefficient to be fitted) nfixcoeff = Number of coefficients imposed during the fit process option = option of the fit process : 1 - selection of the coefficient one by one 2 - selection of the coefficients with Monte Carlo(testversion) comm = MPI communicator cutoff_in = optional,cut off to apply to the range of interation if the coefficient are genereted in this routine max_power_strain = maximum order of the strain of the strain phonon coupling fit_initializeData = optional, logical !If true, we store all the information for the fit, it will reduce the computation time but increase a lot the memory... fit_tolMSDF = optional, tolerance in eV^2/A^2 on the Forces for the fit process fit_tolMSDS = optional, tolerance in eV^2/A^2 on the Stresses for the fit process fit_tolMSDE = optional, tolerance in meV^2/A^2 on the Energy for the fit process fit_tolMSDFS= optional, tolerance in eV^2/A^2 on the Forces+stresses for the fit process positive = optional, TRUE will return only positive coefficients FALSE, default verbose = optional, flag for the verbose mode anhstr = logical, optional : TRUE, the anharmonic strain are computed FALSE, (default) the anharmonic strain are not computed only_odd_power = logical, optional : if TRUE generate only odd power only_even_power= logical, optional : if TRUE generate only even power
OUTPUT
eff_pot<type(effective_potential)> = effective potential datatype with new fitted coefficients
SOURCE
119 subroutine fit_polynomial_coeff_fit(eff_pot,bancoeff,fixcoeff,hist,generateterm,power_disps,& 120 & nbancoeff,ncycle_in,nfixcoeff,nimposecoeff,imposecoeff,& 121 & option,comm,cutoff_in,max_power_strain,initialize_data,& 122 & fit_tolMSDF,fit_tolMSDS,fit_tolMSDE,fit_tolMSDFS,fit_tolGF,& 123 & positive,verbose,anharmstr,spcoupling,& 124 & only_odd_power,only_even_power,prt_anh,& 125 & fit_iatom,prt_files,fit_on,sel_on,fit_factors,prt_GF_csv,& 126 & dispterms) 127 128 implicit none 129 130 !Arguments ------------------------------------ 131 !scalars 132 integer,intent(in) :: ncycle_in,nfixcoeff,nimposecoeff,comm 133 integer,intent(in) :: generateterm,nbancoeff,option 134 !arrays 135 integer,intent(in) :: fixcoeff(nfixcoeff), bancoeff(nbancoeff),imposecoeff(nimposecoeff) 136 integer,intent(in) :: power_disps(2) 137 type(effective_potential_type),target,intent(inout) :: eff_pot 138 type(abihist),intent(inout) :: hist 139 integer,optional,intent(in) :: max_power_strain,prt_anh,fit_iatom 140 real(dp),optional,intent(in) :: cutoff_in,fit_tolMSDF,fit_tolMSDS,fit_tolMSDE,fit_tolMSDFS 141 real(dp),optional,intent(in) :: fit_tolGF 142 logical,optional,intent(in) :: verbose,positive,anharmstr,spcoupling 143 logical,optional,intent(in) :: only_odd_power,only_even_power 144 logical,optional,intent(in) :: initialize_data,prt_files,prt_GF_csv 145 logical,optional,intent(in) :: fit_on(3), sel_on(3),dispterms 146 real(dp),optional,intent(in) :: fit_factors(3) 147 !Local variables------------------------------- 148 !scalar 149 integer :: ii,icoeff,my_icoeff,icycle,icycle_tmp,ierr,info,index_min,iproc,isweep,jcoeff,ia 150 integer :: master,max_power_strain_in,my_rank,my_ncoeff,ncoeff_model,ncoeff_tot,natom_sc,ncell,ncycle 151 integer :: ncycle_tot,ncycle_max,nproc,ntime,nsweep,size_mpi,ncoeff_fix,ncoeff_out 152 integer :: rank_to_send,unit_anh,fit_iatom_in,unit_GF_val,nfix_and_impose,nfixcoeff_corr 153 integer :: ncopy_terms 154 real(dp) :: cutoff,factor,time,tolMSDF,tolMSDS,tolMSDE,tolMSDFS,tolGF,check_value 155 real(dp),parameter :: HaBohr_eVAng = 27.21138386d0 / 0.529177249d0 156 type(effective_potential_type) :: eff_pot_fixed 157 logical :: iam_master,need_verbose,need_positive,converge,file_opened 158 logical :: need_anharmstr,need_spcoupling,ditributed_coefficients,need_prt_anh 159 logical :: need_only_odd_power,need_only_even_power,need_initialize_data 160 logical :: need_prt_files,need_prt_GF_csv,need_disp 161 !arrays 162 real(dp) :: mingf(4),int_fit_factors(3) 163 integer :: sc_size(3) 164 logical,allocatable :: fix_and_impose(:) 165 integer,allocatable :: buffsize(:),buffdisp(:),buffin(:),fixcoeff_corr(:) 166 integer,allocatable :: list_coeffs(:),list_coeffs_tmp(:),list_coeffs_tmp2(:) 167 integer,allocatable :: my_coeffindexes(:),singular_coeffs(:) 168 integer,allocatable :: my_coefflist(:) ,stat_coeff(:),list_coeffs_copy(:) 169 real(dp),allocatable :: gf_values_iter(:,:) 170 real(dp),allocatable :: buffGF(:,:),coeff_values(:),energy_coeffs(:,:) 171 real(dp),allocatable :: energy_coeffs_tmp(:,:) 172 real(dp),allocatable :: fcart_coeffs(:,:,:,:),gf_values(:,:),gf_mpi(:,:) 173 real(dp),allocatable :: fcart_coeffs_tmp(:,:,:,:),strten_coeffs_tmp(:,:,:) 174 real(dp),allocatable :: strten_coeffs(:,:,:) 175 type(polynomial_coeff_type),allocatable :: my_coeffs(:) 176 type(polynomial_coeff_type),allocatable :: coeffs_out(:) 177 type(polynomial_coeff_type),target,allocatable :: coeffs_tmp(:) 178 type(polynomial_coeff_type),pointer :: coeffs_in(:) 179 type(fit_data_type) :: fit_data 180 character(len=1000) :: message,message2 181 character(len=fnlen) :: filename 182 character(len=3) :: i_char 183 character(len=7) :: j_char 184 character(len=5),allocatable :: symbols(:) 185 ! ************************************************************************* 186 187 !MPI variables 188 master = 0 189 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 190 iam_master = (my_rank == master) 191 192 !Initialisation of optional arguments 193 need_verbose = .TRUE. 194 if(present(verbose)) need_verbose = verbose 195 need_initialize_data = .TRUE. 196 if(present(initialize_data)) need_initialize_data = initialize_data 197 need_positive = .FALSE. 198 if(present(positive)) need_positive = positive 199 need_anharmstr = .FALSE. 200 if(present(anharmstr)) need_anharmstr = anharmstr 201 need_disp = .TRUE. 202 if(present(dispterms)) need_disp = dispterms 203 need_spcoupling = .TRUE. 204 if(present(spcoupling)) need_spcoupling = spcoupling 205 need_only_odd_power = .FALSE. 206 if(present(only_odd_power)) need_only_odd_power = only_odd_power 207 need_prt_anh = .FALSE. 208 if(present(prt_anh))then 209 if(prt_anh == 1) need_prt_anh = .TRUE. 210 end if 211 need_prt_GF_csv = .FALSE. 212 if(present(prt_GF_csv)) need_prt_GF_csv = prt_GF_csv 213 need_prt_files = .TRUE. 214 if(present(prt_files))need_prt_files=prt_files 215 need_only_even_power = .FALSE. 216 if(present(only_even_power)) need_only_even_power = only_even_power 217 if(need_only_odd_power.and.need_only_even_power)then 218 write(message, '(3a)' )& 219 & 'need_only_odd_power and need_only_even_power are both true',ch10,& 220 & 'Action: contact abinit group' 221 ABI_ERROR(message) 222 end if 223 max_power_strain_in = 1 224 if(present(max_power_strain))then 225 max_power_strain_in = max_power_strain 226 end if 227 if(max_power_strain_in <= 0)then 228 write(message, '(3a)' )& 229 & 'max_power_strain can not be inferior or equal to zero',ch10,& 230 & 'Action: contact abinit group' 231 ABI_ERROR(message) 232 end if 233 !Check which atom to fit, if not present do all atoms 234 if(present(fit_iatom))then 235 fit_iatom_in = fit_iatom 236 else 237 fit_iatom_in = -1 238 endif 239 !Set int fit factors to default value if fit factors not present 240 int_fit_factors = (/1,1,1/) 241 if (present(fit_factors)) int_fit_factors = fit_factors 242 243 !Set the tolerance for the fit 244 tolMSDF=zero;tolMSDS=zero;tolMSDE=zero;tolMSDFS=zero;tolGF=zero 245 if(present(fit_tolMSDF)) tolMSDF = fit_tolMSDF 246 if(present(fit_tolMSDS)) tolMSDS = fit_tolMSDS 247 if(present(fit_tolMSDE)) tolMSDE = fit_tolMSDE 248 if(present(fit_tolMSDFS))tolMSDFS = fit_tolMSDFS 249 if(present(fit_tolGF)) tolGF = fit_tolGF 250 251 !Copy the input effective potential eff_pot to eff_pot fixed 252 !If nimposecoeff=0 the fixed potential is the harmonic potential 253 ncoeff_model = eff_pot%anharmonics_terms%ncoeff 254 if (nimposecoeff > ncoeff_model)then 255 write(message,'(2a)') "fit_nimposecoeff is greater then the number of anharmonic terms& 256 & provided by input effective potential."& 257 & ,"Action -> Change fit_nimposecoeff, and fit_imposecoeff in the input" 258 ABI_ERROR(message) 259 endif 260 !Impose some coefficients of the input potential 261 if (nimposecoeff > 0)then 262 if (any(imposecoeff > ncoeff_model))then 263 write(message,'(2a)') "At least one value in fit_imposeccoeff is greater then the number of anharmonic terms& 264 & provided by input effective potential."& 265 & ,"Action -> Change fit_imposecoeff in the input" 266 ABI_ERROR(message) 267 endif 268 ABI_MALLOC(coeffs_tmp,(nimposecoeff)) 269 do ia = 1,nimposecoeff 270 ii = imposecoeff(ia) 271 call polynomial_coeff_init(eff_pot%anharmonics_terms%coefficients(ii)%coefficient,& 272 & eff_pot%anharmonics_terms%coefficients(ii)%nterm,coeffs_tmp(ia),& 273 & eff_pot%anharmonics_terms%coefficients(ii)%terms,& 274 & eff_pot%anharmonics_terms%coefficients(ii)%name,& 275 & check = .TRUE.) 276 enddo 277 !Copy the input eff pot, free the coeffs and set the ones who shall be imposed to fixed 278 call effective_potential_copy(eff_pot_fixed,eff_pot,comm) 279 call effective_potential_freeCoeffs(eff_pot_fixed) 280 call effective_potential_setCoeffs(coeffs_tmp,eff_pot_fixed,nimposecoeff) 281 !Deallocate coeffs tmp 282 do ii = 1,nimposecoeff 283 call polynomial_coeff_free(coeffs_tmp(ii)) 284 enddo 285 ABI_FREE(coeffs_tmp) 286 !Fix the whole input potential, copy the input potential to eff_pot 287 elseif (nimposecoeff == -1)then 288 call effective_potential_copy(eff_pot_fixed,eff_pot,comm) 289 !Fix only the harmonic potential 290 else 291 call effective_potential_copy(eff_pot_fixed,eff_pot,comm) 292 call effective_potential_freeCoeffs(eff_pot_fixed) 293 endif 294 295 ncopy_terms = 0 296 !Set consistency between fixcoeff and imposecoeff. 297 if ( nfixcoeff > 0 .and. nimposecoeff >0)then 298 ABI_MALLOC(fix_and_impose,(nfixcoeff)) 299 fix_and_impose = .FALSE. 300 do ii = 1,nfixcoeff 301 if (any(imposecoeff == fixcoeff(ii)))then 302 fix_and_impose(ii) = .TRUE. 303 endif 304 enddo 305 nfix_and_impose = count(fix_and_impose) 306 nfixcoeff_corr = nfixcoeff - nfix_and_impose 307 ABI_MALLOC(fixcoeff_corr,(nfixcoeff_corr)) 308 ia = 1 309 do ii = 1,nfixcoeff 310 if (.not. fix_and_impose(ii))then 311 fixcoeff_corr(ia) = fixcoeff(ii) 312 ia = ia + 1 313 endif 314 enddo 315 ncopy_terms = ncoeff_model - nimposecoeff 316 ABI_MALLOC(list_coeffs_copy,(ncopy_terms)) 317 ia = 1 318 do ii = 1,ncoeff_model 319 if( .not. any(imposecoeff == ii))then 320 list_coeffs_copy(ia) = ii 321 ia = ia + 1 322 endif 323 enddo 324 do ii = 1,ncopy_terms 325 do ia = 1,nfixcoeff_corr 326 if (list_coeffs_copy(ii) == fixcoeff_corr(ia))then 327 fixcoeff_corr(ia) = ii 328 endif 329 enddo 330 enddo 331 elseif (nfixcoeff == -1 .and. nimposecoeff > 0)then 332 ABI_MALLOC(fix_and_impose,(ncoeff_model)) 333 fix_and_impose = .FALSE. 334 do ii = 1,ncoeff_model 335 if (any( imposecoeff == ii))then 336 fix_and_impose(ii) = .TRUE. 337 endif 338 enddo 339 nfix_and_impose = nimposecoeff 340 ncopy_terms = ncoeff_model - nimposecoeff 341 ABI_MALLOC(fixcoeff_corr,(ncopy_terms)) 342 ABI_MALLOC(list_coeffs_copy,(ncopy_terms)) 343 ia = 1 344 do ii = 1,ncoeff_model 345 if (.not. fix_and_impose(ii))then 346 fixcoeff_corr(ia) = ia 347 list_coeffs_copy(ia) = ii 348 ia = ia + 1 349 endif 350 enddo 351 nfixcoeff_corr = ncoeff_model- nfix_and_impose 352 elseif (nfixcoeff == -1 .and. nimposecoeff ==-1)then 353 nfixcoeff_corr = 0 354 write(message,'(3a)') "nfixcoeff and nimposecoeff are set to -1.",ch10,& 355 & "This does not make sense. nfixcoeff will be set to 0." 356 if(iam_master) ABI_WARNING(message) 357 ncopy_terms = 0 358 ABI_MALLOC(list_coeffs_copy,(ncopy_terms)) 359 elseif (nfixcoeff >0 .and. nimposecoeff ==-1)then 360 nfixcoeff_corr = 0 361 write(message,'(3a)') "nfixcoeff is > 0 and nimposecoeff is set to -1.",ch10,& 362 & "This does not make sense. nfixcoeff will be set to 0." 363 if(iam_master) ABI_WARNING(message) 364 ncopy_terms = 0 365 else 366 nfixcoeff_corr = nfixcoeff 367 ABI_MALLOC(fixcoeff_corr,(nfixcoeff_corr)) 368 !nimposecoeff or nfixcoeff always 0 here so fix_and_impose is empty 369 ABI_MALLOC(fix_and_impose,(0)) 370 fixcoeff_corr = fixcoeff 371 ncopy_terms = ncoeff_model 372 ABI_MALLOC(list_coeffs_copy,(ncopy_terms)) 373 do ii = 1,ncopy_terms 374 list_coeffs_copy(ii) = ii 375 enddo 376 endif 377 378 if(need_verbose) then 379 write(message,'(a,(80a))') ch10,('-',ii=1,80) 380 call wrtout(ab_out,message,'COLL') 381 call wrtout(std_out,message,'COLL') 382 write(message,'(2a)') ch10,' Starting Fit process' 383 call wrtout(ab_out,message,'COLL') 384 call wrtout(std_out,message,'COLL') 385 write(message,'(a,(80a))') ch10,('-',ii=1,80) 386 call wrtout(ab_out,message,'COLL') 387 call wrtout(std_out,message,'COLL') 388 end if 389 390 ditributed_coefficients = .true. 391 if(option==2) ditributed_coefficients = .false. 392 393 !if the number of atoms in reference supercell into effpot is not correct, 394 !wrt to the number of atom in the hist, we set map the hist and set the good supercell 395 if (size(hist%xred,2) /= eff_pot%supercell%natom) then 396 call effective_potential_file_mapHistToRef(eff_pot,hist,comm,verbose=need_verbose) 397 end if 398 399 !Set the cut off 400 cutoff = zero 401 if(present(cutoff_in))then 402 cutoff = cutoff_in 403 end if 404 !If the cutoff is set to zero, we define a default value 405 if(abs(cutoff)<tol16)then 406 do ii=1,3 407 cutoff = cutoff + sqrt(eff_pot%supercell%rprimd(ii,1)**2+& 408 & eff_pot%supercell%rprimd(ii,2)**2+& 409 & eff_pot%supercell%rprimd(ii,3)**2) 410 end do 411 cutoff = cutoff / 3.0_dp 412 end if 413 !we get the size of the supercell in the hist file 414 do ii=1,3 415 sc_size(ii) = int(anint(sqrt(eff_pot%supercell%rprimd(ii,1)**2+& 416 & eff_pot%supercell%rprimd(ii,2)**2+& 417 & eff_pot%supercell%rprimd(ii,3)**2) / & 418 & sqrt(eff_pot%crystal%rprimd(ii,1)**2+& 419 & eff_pot%crystal%rprimd(ii,2)**2+& 420 & eff_pot%crystal%rprimd(ii,3)**2))) 421 end do 422 423 424 !Get the list of coefficients to fit: 425 !get from the eff_pot type (from the input) 426 !or 427 !regenerate the list 428 my_ncoeff = 0 429 ncoeff_tot = 0 430 431 !Reset ncoeff_tot 432 if(ncoeff_model > 0)then 433 if(need_verbose)then 434 write(message, '(4a)' )ch10,' The coefficients present in the effective',& 435 & ' potential will be used for the fit' 436 call wrtout(std_out,message,'COLL') 437 call wrtout(ab_out,message,'COLL') 438 end if 439 end if 440 441 ABI_MALLOC(symbols,(eff_pot%crystal%natom)) 442 call symbols_crystal(eff_pot%crystal%natom,eff_pot%crystal%ntypat,eff_pot%crystal%npsp,& 443 & symbols,eff_pot%crystal%typat,eff_pot%crystal%znucl) 444 445 if(generateterm == 1)then 446 ! we need to regenerate them 447 if(need_verbose)then 448 if(fit_iatom_in > 0)then 449 write(message, '(2a,I3,4a)' )ch10,' The coefficients for the fit around atom', fit_iatom_in,': ',& 450 & trim(symbols(fit_iatom)),', will be generated',ch10 451 call wrtout(std_out,message,'COLL') 452 call wrtout(ab_out,message,'COLL') 453 else 454 write(message, '(3a)' )ch10,' The coefficients for the fit will be generated with all cross terms',ch10 455 call wrtout(std_out,message,'COLL') 456 call wrtout(ab_out,message,'COLL') 457 endif 458 write(message,'(a,F6.3,a)') " Cutoff of ",cutoff," Bohr is imposed" 459 call wrtout(std_out,message,'COLL') 460 end if 461 462 call polynomial_coeff_getNorder(coeffs_tmp,eff_pot%crystal,cutoff,my_ncoeff,ncoeff_tot,power_disps,& 463 & max_power_strain_in,0,sc_size,comm,anharmstr=need_anharmstr,& 464 & spcoupling=need_spcoupling,distributed=.true.,& 465 & only_odd_power=need_only_odd_power,& 466 & only_even_power=need_only_even_power,& 467 & fit_iatom=fit_iatom_in,dispterms=need_disp) 468 end if 469 470 ABI_FREE(symbols) 471 472 !Copy the initial coefficients from the model on the CPU 0 473 ncoeff_tot = ncoeff_tot + ncoeff_model 474 if((iam_master .and. ncopy_terms > 0)) my_ncoeff = my_ncoeff + ncopy_terms 475 476 !Get number of fixed coeff 477 ncoeff_fix = 0 478 if(nfixcoeff_corr /=0) then 479 if(nfixcoeff_corr == -1)then 480 ncoeff_fix = ncoeff_model 481 else 482 ncoeff_fix = nfixcoeff_corr 483 endif 484 endif 485 486 487 !Get the list with the number of coeff on each CPU 488 !In order to be abble to compute the my_coeffindexes array which is for example: 489 ! if CPU0 has 200 Coeff and CPU1 has 203 Coeff then 490 ! for CPU0:my_coeffindexes=>1-200 and for CPU1:my_coeffindexes=>201-403 491 !Also fill the my_coeffs array with the generated coefficients and/or the coefficient from the input xml 492 ABI_MALLOC(buffin,(nproc)) 493 buffin = 0 494 buffin(my_rank+1) = my_ncoeff 495 call xmpi_sum(buffin,comm,ierr) 496 ABI_MALLOC(my_coeffindexes,(my_ncoeff)) 497 ABI_MALLOC(my_coefflist,(my_ncoeff)) 498 ABI_MALLOC(my_coeffs,(my_ncoeff)) 499 do icoeff=1,my_ncoeff 500 501 jcoeff = icoeff 502 my_coefflist(icoeff) = icoeff 503 504 if(my_rank==0) then 505 my_coeffindexes(icoeff) = icoeff 506 else 507 my_coeffindexes(icoeff) = sum(buffin(1:my_rank)) + icoeff 508 end if 509 510 ! Only copy the input coefficients on the CPU0 511 if(my_rank==0) then 512 if(icoeff <= ncopy_terms)then 513 coeffs_in => eff_pot%anharmonics_terms%coefficients 514 jcoeff = list_coeffs_copy(icoeff) 515 else 516 coeffs_in => coeffs_tmp 517 jcoeff = jcoeff - ncopy_terms 518 end if 519 else 520 coeffs_in => coeffs_tmp 521 end if 522 call polynomial_coeff_init(one,coeffs_in(jcoeff)%nterm,& 523 & my_coeffs(icoeff),coeffs_in(jcoeff)%terms,& 524 & coeffs_in(jcoeff)%name,& 525 & check=.true.) 526 call polynomial_coeff_free(coeffs_in(jcoeff)) 527 end do 528 529 !Deallocation 530 ABI_SFREE(coeffs_tmp) 531 NULLIFY(coeffs_in) 532 ABI_FREE(buffin) 533 534 !wait everybody 535 call xmpi_barrier(comm) 536 537 !Reset the output (we free the memory) 538 call effective_potential_freeCoeffs(eff_pot) 539 540 541 !Check if ncycle_in is not zero or superior to ncoeff_tot 542 if(need_verbose.and.(ncycle_in > ncoeff_tot).or.(ncycle_in<0.and.nfixcoeff_corr /= -1)) then 543 write(message, '(6a,I0,3a)' )ch10,& 544 & ' --- !WARNING',ch10,& 545 & ' The number of cycle requested in the input is not correct.',ch10,& 546 & ' This number will be set to the maximum of coefficients: ',ncoeff_tot,ch10,& 547 & ' ---',ch10 548 call wrtout(std_out,message,"COLL") 549 end if 550 551 !Use fixcoeff 552 !ncycle_tot store the curent number of coefficient in the model 553 !Do not reset this variable... 554 ncycle_tot = 0 555 if (nfixcoeff_corr == -1)then 556 write(message, '(3a)')' nfixcoeff is set to -1, the coefficients present in the model',& 557 & ' are imposed.',ch10 558 ncycle_tot = ncycle_tot + ncoeff_model 559 else 560 if (nfixcoeff_corr > 0)then 561 if(maxval(fixcoeff_corr(:)) > ncoeff_tot) then 562 write(message, '(4a,I0,6a)' )ch10,& 563 & ' --- !WARNING',ch10,& 564 & ' The value ',maxval(fixcoeff_corr(:)),' is not in the list.',ch10,& 565 & ' Start from scratch...',ch10,& 566 & ' ---',ch10 567 else 568 ncycle_tot = ncycle_tot + nfixcoeff_corr 569 write(message, '(2a)')' Some coefficients are imposed from the input.',ch10 570 end if 571 else 572 write(message, '(4a)')' There is no coefficient imposed from the input.',ch10,& 573 & ' Start from scratch',ch10 574 end if 575 end if 576 577 if(need_verbose) call wrtout(std_out,message,'COLL') 578 579 !Compute the number of cycle: 580 ncycle = ncycle_in 581 !Compute the maximum number of cycle 582 ncycle_max = ncycle_in + ncycle_tot 583 584 !Check if the number of request cycle + the initial number of coeff is superior to 585 !the maximum number of coefficient allowed 586 if(ncycle_max > ncoeff_tot) then 587 ncycle = ncoeff_tot - ncycle_tot 588 ncycle_max = ncoeff_tot 589 write(message, '(4a,I0,2a,I0,2a,I0,3a)' )ch10,& 590 & ' --- !WARNING',ch10,& 591 & ' The number of cycle + the number of imposed coefficients: ',ncycle_max,ch10,& 592 & ' is superior to the maximum number of coefficients in the initial list: ',ncoeff_tot,ch10,& 593 & ' The number of cycle is set to ',ncycle,ch10,& 594 & ' ---',ch10 595 if(need_verbose) call wrtout(std_out,message,'COLL') 596 else if (option==2)then 597 ! Always set to the maximum 598 ncycle_max = ncoeff_tot 599 end if 600 601 !Initialisation of constants 602 ntime = hist%mxhist 603 natom_sc = eff_pot%supercell%natom 604 ncell = eff_pot%supercell%ncells 605 factor = 1._dp/natom_sc 606 607 !Initialisation of arrays: 608 ABI_MALLOC(energy_coeffs_tmp,(ncycle_max,ntime)) 609 ABI_MALLOC(list_coeffs,(ncycle_max)) 610 ABI_MALLOC(fcart_coeffs_tmp,(3,natom_sc,ncycle_max,ntime)) 611 ABI_MALLOC(strten_coeffs_tmp,(6,ntime,ncycle_max)) 612 list_coeffs = 0 613 614 !if ncycle_tot > 0 fill list_coeffs with the fixed coefficients 615 if(ncycle_tot > 0)then 616 do ii = 1,ncycle_tot 617 if(nfixcoeff_corr == -1)then 618 if(ii <= ncoeff_model)then 619 list_coeffs(ii) = ii 620 end if 621 else 622 list_coeffs(ii) = fixcoeff_corr(ii) 623 end if 624 end do 625 end if 626 627 !Get the decomposition for each coefficients of the forces and stresses for 628 !each atoms and each step equations 11 & 12 of PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]] 629 if(need_verbose)then 630 write(message, '(a)' ) ' Initialisation of the fit process...' 631 call wrtout(std_out,message,'COLL') 632 end if 633 !Before the fit, compute constants with fit_data_compute. 634 !Conpute the strain of each configuration. 635 !Compute the displacmeent of each configuration. 636 !Compute the variation of the displacement due to strain of each configuration. 637 !Compute fixed forces and stresse and get the standard deviation. 638 !Compute Sheppard and al Factors \Omega^{2} see J.Chem Phys 136, 074103 (2012) [[cite:Sheppard2012]]. 639 call fit_data_compute(fit_data,eff_pot,hist,comm,verbose=need_verbose) 640 641 !Get the decomposition for each coefficients of the forces,stresses and energy for 642 !each atoms and each step (see equations 11 & 12 of 643 !PRB95,094115(2017)) [[cite:Escorihuela-Sayalero2017]]+ allocation 644 !If the user does not turn off this initialization, we store all the information for the fit, 645 !it will reduce the computation time but increase a lot the memory... 646 if(need_initialize_data)then 647 ABI_MALLOC(energy_coeffs,(my_ncoeff,ntime)) 648 ABI_MALLOC(fcart_coeffs,(3,natom_sc,my_ncoeff,ntime)) 649 ABI_MALLOC(strten_coeffs,(6,ntime,my_ncoeff)) 650 call fit_polynomial_coeff_getFS(my_coeffs,fit_data%training_set%du_delta,& 651 & fit_data%training_set%displacement,& 652 & energy_coeffs,fcart_coeffs,natom_sc,eff_pot%crystal%natom,& 653 & my_ncoeff,ntime,sc_size,fit_data%training_set%strain,& 654 & strten_coeffs,fit_data%training_set%ucvol,my_coefflist,my_ncoeff) 655 else 656 ! Allocate just 1 dimension ! Save MEMORY ! 657 ABI_MALLOC(energy_coeffs,(1,ntime)) 658 ABI_MALLOC(fcart_coeffs,(3,natom_sc,1,ntime)) 659 ABI_MALLOC(strten_coeffs,(6,ntime,1)) 660 end if 661 662 !Allocation of arrays 663 ABI_MALLOC(coeffs_tmp,(ncycle_max)) 664 ABI_MALLOC(singular_coeffs,(max(1,my_ncoeff))) 665 ABI_MALLOC(coeff_values,(ncycle_max)) 666 ABI_MALLOC(gf_values,(4,max(1,my_ncoeff))) 667 ABI_MALLOC(list_coeffs_tmp,(ncycle_max)) 668 ABI_MALLOC(list_coeffs_tmp2,(ncycle_max)) 669 ABI_MALLOC(stat_coeff,(ncoeff_tot)) 670 coeff_values = zero 671 singular_coeffs = 0 672 stat_coeff = 0 673 !Set mpi buffer 674 !Set the bufsize for mpi allgather 675 ABI_MALLOC(buffsize,(nproc)) 676 ABI_MALLOC(buffdisp,(nproc)) 677 ABI_MALLOC(buffGF,(5,1)) 678 ABI_MALLOC(gf_mpi,(5,nproc)) 679 buffsize(:) = 0 680 buffdisp(1) = 0 681 do ii= 1,nproc 682 buffsize(ii) = 5 683 end do 684 do ii = 2,nproc 685 buffdisp(ii) = buffdisp(ii-1) + buffsize(ii-1) 686 end do 687 size_mpi = 5*nproc 688 !If some coeff are imposed by the input, we need to fill the arrays 689 !with this coeffs and broadcast to the others CPUs : 690 if(ncycle_tot>=1)then 691 do icycle = 1,ncycle_tot 692 list_coeffs_tmp(icycle) = icycle 693 rank_to_send = 0 694 do icoeff=1,my_ncoeff 695 if((my_coeffindexes(icoeff)==list_coeffs(icycle)))then 696 697 if(need_initialize_data)then 698 my_icoeff = icoeff 699 else 700 my_icoeff = 1 701 ! Need to initialized the data for the fit for this coefficient 702 call fit_polynomial_coeff_getFS(my_coeffs,fit_data%training_set%du_delta,& 703 & fit_data%training_set%displacement,& 704 & energy_coeffs,fcart_coeffs,natom_sc,eff_pot%crystal%natom,& 705 & my_ncoeff,ntime,sc_size,fit_data%training_set%strain,& 706 & strten_coeffs,fit_data%training_set%ucvol,& 707 & my_coefflist(icoeff),1) 708 end if 709 710 energy_coeffs_tmp(icycle,:) = energy_coeffs(my_icoeff,:) 711 fcart_coeffs_tmp(:,:,icycle,:) = fcart_coeffs(:,:,my_icoeff,:) 712 strten_coeffs_tmp(:,:,icycle) = strten_coeffs(:,:,my_icoeff) 713 rank_to_send = my_rank 714 call polynomial_coeff_free(coeffs_tmp(icycle)) 715 call polynomial_coeff_init(coeff_values(icycle),my_coeffs(icoeff)%nterm,& 716 & coeffs_tmp(icycle),my_coeffs(icoeff)%terms,& 717 & my_coeffs(icoeff)%name,& 718 & check=.false.) 719 exit 720 end if 721 end do 722 ! Need to send the rank with the chosen coefficient 723 call xmpi_sum(rank_to_send, comm, ierr) 724 ! Boadcast the coefficient 725 call xmpi_bcast(energy_coeffs_tmp(icycle,:), rank_to_send, comm, ierr) 726 call xmpi_bcast(fcart_coeffs_tmp(:,:,icycle,:) , rank_to_send, comm, ierr) 727 call xmpi_bcast(strten_coeffs_tmp(:,:,icycle), rank_to_send, comm, ierr) 728 call polynomial_coeff_broadcast(coeffs_tmp(icycle), rank_to_send, comm) 729 end do 730 end if 731 732 !Waiting for all 733 if(nproc > 1) then 734 if(need_verbose)then 735 write(message, '(a)') ' Initialisation done... waiting for all the CPU' 736 call wrtout(std_out,message,'COLL') 737 end if 738 call xmpi_barrier(comm) 739 end if 740 741 !Compute GF, coeff_values,strten_coeffs and fcart_coeffs are set to zero 742 !it means that only the harmonic part wiil be computed 743 coeff_values = zero 744 745 call fit_polynomial_coeff_computeGF(coeff_values,energy_coeffs,fit_data%energy_diff,fcart_coeffs,& 746 & fit_data%fcart_diff,gf_values(:,1),int((/1/)),natom_sc,& 747 & 0,my_ncoeff,ntime,strten_coeffs,fit_data%strten_diff,& 748 & fit_data%training_set%sqomega) 749 750 !Print the standard deviation before the fit 751 write(message,'(4a,ES24.16,2a,ES24.16,2a,ES24.16,2a,ES24.16,a)' ) ch10,& 752 !& ' Mean Standard Deviation values at the begining of the fit process (meV**2/atm):',& 753 !& ch10,' Energy : ',& 754 !& gf_values(4,1)*factor*(Ha_EV*1000)**2 ,ch10,& 755 & ' Goal function values at the begining of the fit process (eV^2/A^2):',ch10,& 756 & ' Energy : ',& 757 & gf_values(4,1)*(HaBohr_eVAng)**2,ch10,& 758 & ' Forces+Stresses : ',& 759 & gf_values(1,1)*(HaBohr_eVAng)**2,ch10,& 760 & ' Forces : ',& 761 & gf_values(2,1)*(HaBohr_eVAng)**2,ch10,& 762 & ' Stresses : ',& 763 & gf_values(3,1)*(HaBohr_eVAng)**2,ch10 764 if(need_verbose)then 765 call wrtout(ab_out,message,'COLL') 766 call wrtout(std_out,message,'COLL') 767 end if 768 769 ABI_MALLOC(gf_values_iter,(4,ncycle+1)) 770 gf_values_iter(:,:) = zero 771 !Store initial gf_values as first value in gf_values_iter 772 gf_values_iter(:,1) = gf_values(:,1) 773 774 select case(option) 775 776 case(1) 777 !Option 1, we select the coefficients one by one 778 if(need_verbose.and.ncycle > 0)then 779 write(message,'(a,3x,a,10x,a,14x,a,14x,a,14x,a)') " N","Selecting","MSDE","MSDFS","MSDF","MSDS" 780 call wrtout(ab_out,message,'COLL') 781 write(message,'(4x,a,6x,a,8x,a,8x,a,8x,a)') "Coefficient","(eV^2/A^2)","(eV^2/A^2)","(eV^2/A^2)",& 782 & "(eV^2/A^2)" 783 call wrtout(ab_out,message,'COLL') 784 end if 785 786 ! Start fit process 787 do icycle_tmp = 1,ncycle 788 icycle = ncycle_tot + 1 789 list_coeffs_tmp(icycle) = icycle 790 if(need_verbose)then 791 write(message, '(4a,I0,a)')ch10,'--',ch10,' Try to find the best model with ',& 792 & icycle,' coefficient' 793 if(icycle > 1) write(message, '(2a)') trim(message),'s' 794 if(nproc > 1) then 795 if(my_ncoeff>=1) then 796 write(message, '(2a,I0,a)')trim(message), ' (only the ',my_ncoeff,& 797 & ' first are printed for this CPU)' 798 else 799 write(message, '(2a)')trim(message), ' (no coefficient treated by this CPU)' 800 end if 801 end if 802 call wrtout(std_out,message,'COLL') 803 if(icycle>1 .or. any(list_coeffs(:) > zero))then 804 write(message, '(3a)') ' The coefficient numbers from the previous cycle are:',ch10,' [' 805 do ii=1,icycle-1 806 if(ii<icycle-1)then 807 write(message, '(a,I0,a)') trim(message),list_coeffs(ii),',' 808 else 809 write(message, '(a,I0)') trim(message),list_coeffs(ii) 810 end if 811 end do 812 write(message, '(3a)') trim(message),']',ch10 813 call wrtout(std_out,message,'COLL') 814 end if 815 816 write(message,'(2x,a,12x,a,14x,a,13x,a,14x,a)') " Testing","MSDE","MSDFS","MSDF","MSDS" 817 call wrtout(std_out,message,'COLL') 818 write(message,'(a,7x,a,8x,a,8x,a,8x,a)') " Coefficient","(eV^2/A^2)","(eV^2/A^2)","(eV^2/A^2)",& 819 & "(eV^2/A^2)" 820 call wrtout(std_out,message,'COLL') 821 end if!End if verbose 822 823 !Print all GF VALUES in CSV if wanted 824 !Open *csv file for storing GF values of all cores for this iteration 825 if(need_prt_GF_csv)then 826 write(filename,'(a,I1,a,I3.3,a,I3.3,a)') "GF_values_iatom",fit_iatom,"_proc",my_rank,"_iter",icycle,".csv" 827 unit_GF_val = get_unit() 828 if (open_file(filename,message,unit=unit_GF_val,form="formatted",& 829 & status="unknown",action="write") /= 0) then 830 ABI_ERROR(message) 831 end if 832 end if 833 ! Reset gf_values 834 gf_values(:,:) = zero 835 do icoeff=1,my_ncoeff 836 ! cycle if this coefficient is not allowed 837 if(any(list_coeffs==my_coeffindexes(icoeff)).or.singular_coeffs(icoeff) == 1)then 838 gf_values(:,icoeff) = zero 839 cycle 840 endif 841 if(nbancoeff >= 1)then 842 if(any(bancoeff==my_coeffindexes(icoeff)))then 843 gf_values(:,icoeff) = zero 844 cycle 845 endif 846 end if 847 list_coeffs(icycle) = my_coeffindexes(icoeff) 848 849 if(need_initialize_data)then 850 my_icoeff = icoeff 851 else 852 ! Need to initialized the data for the fit for this coefficient 853 my_icoeff = 1 854 call fit_polynomial_coeff_getFS(my_coeffs,fit_data%training_set%du_delta,& 855 & fit_data%training_set%displacement,& 856 & energy_coeffs,fcart_coeffs,natom_sc,eff_pot%crystal%natom,& 857 & my_ncoeff,ntime,sc_size,fit_data%training_set%strain,& 858 & strten_coeffs,fit_data%training_set%ucvol,& 859 & my_coefflist(icoeff),1) 860 end if 861 862 ! Fill the temporary arrays 863 energy_coeffs_tmp(icycle,:) = energy_coeffs(my_icoeff,:) 864 fcart_coeffs_tmp(:,:,icycle,:) = fcart_coeffs(:,:,my_icoeff,:) 865 strten_coeffs_tmp(:,:,icycle) = strten_coeffs(:,:,my_icoeff) 866 867 ! call the fit process routine 868 ! This routine solves the linear system proposed 869 ! by C.Escorihuela-Sayalero see PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]] 870 call fit_polynomial_coeff_solve(coeff_values(1:icycle),fcart_coeffs_tmp,fit_data%fcart_diff,& 871 & energy_coeffs_tmp,fit_data%energy_diff,info,& 872 & list_coeffs_tmp(1:icycle),natom_sc,icycle,ncycle_max,ntime,& 873 & strten_coeffs_tmp,fit_data%strten_diff,& 874 & fit_data%training_set%sqomega,fit_on,int_fit_factors) 875 876 if(info==0)then 877 if (need_positive.and.any(coeff_values(ncoeff_fix+1:icycle) < zero)) then 878 write(message, '(a)') ' Negative value detected...' 879 gf_values(:,icoeff) = zero 880 coeff_values = zero 881 else 882 call fit_polynomial_coeff_computeGF(coeff_values(1:icycle),energy_coeffs_tmp,& 883 & fit_data%energy_diff,fcart_coeffs_tmp,fit_data%fcart_diff,& 884 & gf_values(:,icoeff),list_coeffs_tmp(1:icycle),natom_sc,& 885 & icycle,ncycle_max,ntime,strten_coeffs_tmp,& 886 & fit_data%strten_diff,fit_data%training_set%sqomega) 887 888 889 write (j_char, '(i7)') my_coeffindexes(icoeff) 890 write(message, '(4x,a,3x,4ES18.10)') adjustl(j_char),& 891 !& gf_values(4,icoeff)*factor*(1000*Ha_ev)**2 ,& 892 & gf_values(4,icoeff)*HaBohr_eVAng**2,& 893 & gf_values(1,icoeff)*HaBohr_eVAng**2,& 894 & gf_values(2,icoeff)*HaBohr_eVAng**2,& 895 & gf_values(3,icoeff)*HaBohr_eVAng**2 896 if(need_prt_GF_csv)then 897 write(message2, '(I7.7,3a,ES18.10,a,ES18.10,a,ES18.10,a,ES18.10)') my_coeffindexes(icoeff),",",& 898 !& gf_values(4,icoeff)*factor*(1000*Ha_ev)**2,",",& 899 & trim(my_coeffs(icoeff)%name),",",& 900 & gf_values(4,icoeff)*HaBohr_eVAng**2,",",& 901 & gf_values(1,icoeff)*HaBohr_eVAng**2,",",& 902 & gf_values(2,icoeff)*HaBohr_eVAng**2,",",& 903 & gf_values(3,icoeff)*HaBohr_eVAng**2 904 end if 905 end if 906 else!In this case the matrix is singular 907 gf_values(:,icoeff) = zero 908 singular_coeffs(icoeff) = 1 909 write(message, '(a)') ' The matrix is singular...' 910 if(need_prt_GF_csv)then 911 write(message2, '(I7.7,10a)') my_coeffindexes(icoeff),",",& 912 !& gf_values(4,icoeff)*factor*(1000*Ha_ev)**2,",",& 913 & trim(my_coeffs(icoeff)%name),",",& 914 & "None",",",& 915 & "None",",",& 916 & "None",",",& 917 & "None" 918 endif 919 end if 920 if(need_verbose)then 921 call wrtout(std_out,message,'COLL') 922 if(need_prt_GF_csv)then 923 call wrtout(unit_GF_val,message2,'PERS',do_flush=.TRUE.) 924 end if 925 endif 926 end do !icoeff=1,my_ncoeff 927 928 !Close *csv file for GF values of this iteration 929 if(need_prt_GF_csv)close(unit_GF_val) 930 931 ! find the best coeff on each CPU 932 mingf(:) = 9D99 933 index_min = 0 934 do icoeff=1,my_ncoeff 935 if(gf_values(1,icoeff) < zero) cycle 936 if(abs(gf_values(1,icoeff)) <tol16) cycle 937 if(sum(gf_values(2:4,icoeff),MASK=sel_on) < sum(mingf(2:4),MASK=sel_on))then 938 mingf(:) = gf_values(:,icoeff) 939 index_min = my_coeffindexes(icoeff) 940 end if 941 end do 942 943 ! MPI GATHER THE BEST COEFF ON EACH CPU 944 if(nproc > 1)then 945 buffGF(1,1) = index_min 946 buffGF(2:5,1) = mingf(:) 947 948 call xmpi_allgatherv(buffGF,5,gf_mpi,buffsize,buffdisp, comm, ierr) 949 ! find the best coeff 950 mingf(:) = 9D99 951 index_min= 0 952 do icoeff=1,nproc 953 if(gf_mpi(2,icoeff) < zero) cycle 954 if(abs(gf_mpi(2,icoeff)) < tol16) cycle 955 if(sum(gf_mpi(3:5,icoeff),MASK=sel_on) < sum(mingf(2:4),MASK=sel_on))then 956 mingf(:) = gf_mpi(2:5,icoeff) 957 index_min = int(gf_mpi(1,icoeff)) 958 end if 959 end do 960 end if 961 962 ! Check if there is still coefficient 963 if(index_min==0) then 964 exit 965 else 966 list_coeffs(icycle) = index_min 967 end if 968 969 ! Check if this coeff is treat by this cpu and fill the 970 ! temporary array before broadcast 971 rank_to_send = 0 972 do icoeff=1,my_ncoeff 973 974 975 if((my_coeffindexes(icoeff)==list_coeffs(icycle)))then 976 977 if(need_initialize_data)then 978 my_icoeff = icoeff 979 else 980 ! Need to initialized the data for the fit for this coefficient 981 my_icoeff = 1 982 call fit_polynomial_coeff_getFS(my_coeffs,fit_data%training_set%du_delta,& 983 & fit_data%training_set%displacement,& 984 & energy_coeffs,fcart_coeffs,natom_sc,eff_pot%crystal%natom,& 985 & my_ncoeff,ntime,sc_size,fit_data%training_set%strain,& 986 & strten_coeffs,fit_data%training_set%ucvol,& 987 & my_coefflist(icoeff),1) 988 end if 989 990 energy_coeffs_tmp(icycle,:) = energy_coeffs(my_icoeff,:) 991 fcart_coeffs_tmp(:,:,icycle,:) = fcart_coeffs(:,:,my_icoeff,:) 992 strten_coeffs_tmp(:,:,icycle) = strten_coeffs(:,:,my_icoeff) 993 call polynomial_coeff_free(coeffs_tmp(icycle)) 994 call polynomial_coeff_init(coeff_values(icycle),my_coeffs(icoeff)%nterm,& 995 & coeffs_tmp(icycle),my_coeffs(icoeff)%terms,& 996 & my_coeffs(icoeff)%name,& 997 & check=.false.) 998 999 rank_to_send = my_rank 1000 exit 1001 end if 1002 end do 1003 ! Need to send the rank with the chosen coefficient 1004 call xmpi_sum(rank_to_send, comm, ierr) 1005 1006 ! Boadcast the coefficient 1007 call xmpi_bcast(energy_coeffs_tmp(icycle,:), rank_to_send, comm, ierr) 1008 call xmpi_bcast(fcart_coeffs_tmp(:,:,icycle,:) , rank_to_send, comm, ierr) 1009 call xmpi_bcast(strten_coeffs_tmp(:,:,icycle), rank_to_send, comm, ierr) 1010 call polynomial_coeff_broadcast(coeffs_tmp(icycle), rank_to_send, comm) 1011 1012 if(need_verbose) then 1013 write(message, '(a,I0,2a)' )' Selecting the coefficient number ',list_coeffs(icycle),& 1014 & ' ===> ',trim(coeffs_tmp(icycle)%name) 1015 call wrtout(std_out,message,'COLL') 1016 1017 ! write(message, '(2a,I0,a,ES24.16)' )' Standard deviation of the energy for',& 1018 !& ' the iteration ',icycle_tmp,' (meV^2/atm): ',& 1019 !& mingf(4)* factor * (Ha_eV *1000)**2 1020 ! call wrtout(std_out,message,'COLL') 1021 1022 write (i_char, '(i3)') icycle 1023 write (j_char, '(i7)') list_coeffs(icycle) 1024 write(message, '(a,a,3x,a,3x,4ES18.10)') " ",adjustl(i_char),adjustl(j_char),& 1025 !& mingf(4)* factor * (Ha_eV *1000)**2,& 1026 & mingf(4)*HaBohr_eVAng**2,& 1027 & mingf(1)*HaBohr_eVAng**2,& 1028 & mingf(2)*HaBohr_eVAng**2,& 1029 & mingf(3)*HaBohr_eVAng**2 1030 call wrtout(ab_out,message,'COLL') 1031 end if 1032 1033 ncycle_tot = ncycle_tot + 1 1034 1035 !Store GF Values of this iteration 1036 gf_values_iter(:,icycle_tmp+1) = mingf(:) 1037 1038 ! Check the stopping criterion 1039 converge = .false. 1040 if(tolGF > zero)then 1041 check_value = (sum(gf_values_iter(2:4,icycle_tmp+1),MASK=sel_on) - sum(gf_values_iter(2:4,icycle_tmp),MASK=sel_on)) & 1042 & /(sum(gf_values_iter(2:4,icycle_tmp+1),MASK=sel_on) - sum(gf_values_iter(2:4,1),MASK=sel_on)) 1043 if(check_value < tolGF)then 1044 write(message,'(2a,ES18.10,a,ES18.10,a)') ch10," Fit process complete =>",& 1045 & check_value ," < ",tolGF,& 1046 & ' Goal Function is converged' 1047 converge = .true. 1048 end if 1049 endif 1050 if(tolMSDE > zero)then 1051 if(abs(tolMSDE) > abs(mingf(4)* (Ha_eV *1000)**2 *factor))then 1052 write(message,'(2a,ES18.10,a,ES18.10,a)') ch10," Fit process complete =>",& 1053 & mingf(4)* (Ha_eV *1000)**2 * factor ," < ",tolMSDE,& 1054 & ' for MSDE' 1055 converge = .true. 1056 end if 1057 end if 1058 if(tolMSDF > zero) then 1059 if(abs(tolMSDF) > abs(mingf(2)*HaBohr_eVAng**2))then 1060 write(message,'(2a,ES18.10,a,ES18.10,a)') ch10," Fit process complete =>",& 1061 & mingf(2)*HaBohr_eVAng**2 ," < ",tolMSDF,& 1062 & ' for MSDF' 1063 converge = .true. 1064 end if 1065 end if 1066 if(tolMSDS > zero) then 1067 if(abs(tolMSDS) > abs(mingf(3)*HaBohr_eVAng**2))then 1068 write(message,'(2a,ES18.10,a,ES18.10,a)') ch10," Fit process complete =>",& 1069 & mingf(3)*HaBohr_eVAng**2 ," < ",tolMSDS,& 1070 & ' for MSDS' 1071 converge = .true. 1072 end if 1073 end if 1074 if(tolMSDFS > zero)then 1075 if(abs(tolMSDFS) > abs(mingf(1)*HaBohr_eVAng**2))then 1076 write(message,'(2a,ES18.10,a,ES18.10,a)') ch10," Fit process complete =>",& 1077 & mingf(1)*HaBohr_eVAng**2 ," < ",tolMSDFS,& 1078 & ' for MSDFS' 1079 converge = .true. 1080 end if 1081 end if 1082 if(converge)then 1083 call wrtout(ab_out,message,'COLL') 1084 call wrtout(std_out,message,'COLL') 1085 exit 1086 else 1087 if(any((/abs(tolMSDE),abs(tolMSDF),abs(tolMSDS),abs(tolMSDFS)/) > tol20) .and.& 1088 & icycle_tmp == ncycle)then 1089 write(message,'(2a,I0,a)') ch10," WARNING: ",ncycle,& 1090 & " cycles was not enougth to converge the fit process" 1091 call wrtout(ab_out,message,'COLL') 1092 call wrtout(std_out,message,'COLL') 1093 end if 1094 end if 1095 1096 end do !icycle_tmp=1,ncycle 1097 1098 case(2) 1099 1100 ! Monte Carlo selection 1101 nsweep = 10000 1102 ! If no coefficient imposed in the inputs we reset the goal function 1103 if (ncycle_tot == 0) then 1104 gf_values(:,:) = zero 1105 mingf(:) = 9D99 1106 else 1107 mingf = gf_values(:,1) 1108 end if 1109 call cpu_time(time) 1110 call ZBQLINI(int(time*1000000/(my_rank+1))) 1111 if(need_verbose)then 1112 write(message,'(a,I0,a)') " Start Monte Carlo simulations on ", nproc," CPU" 1113 if(nproc>1) write(message,'(2a)') trim(message)," (only print result of the master)" 1114 call wrtout(std_out,message,'COLL') 1115 call wrtout(ab_out,message,'COLL') 1116 write(message,'(a,2x,a,9x,a,14x,a,13x,a,14x,a)') ch10," Iteration ","MSDE","MSDFS","MSDF","MSdS" 1117 call wrtout(std_out,message,'COLL') 1118 write(message,'(a,5x,a,8x,a,8x,a,8x,a)') " ","(eV^2/A^2)","(eV^2/A^2)","(eV^2/A^2)",& 1119 & "(eV^2/A^2)" 1120 call wrtout(std_out,message,'COLL') 1121 1122 end if 1123 1124 do ii = 1,1!nyccle 1125 do isweep =1,nsweep 1126 write (j_char, '(i7)') isweep 1127 !TEST_AM 1128 icycle_tmp = int(ZBQLU01(zero)*(ncycle+1-1))+1 1129 icycle_tmp = ncycle 1130 do icycle=1,icycle_tmp 1131 icoeff = int(ZBQLU01(zero)*(my_ncoeff))+1 1132 ! icycle = int(ZBQLU01(zero)*(ncycle))+1 1133 list_coeffs_tmp2(icycle) = icoeff 1134 list_coeffs_tmp(icycle)= icycle 1135 ! Fill the temporary arrays 1136 energy_coeffs_tmp(icycle,:) = energy_coeffs(icoeff,:) 1137 fcart_coeffs_tmp(:,:,icycle,:) = fcart_coeffs(:,:,icoeff,:) 1138 strten_coeffs_tmp(:,:,icycle) = strten_coeffs(:,:,icoeff) 1139 end do 1140 !TEST_AM 1141 1142 ! call the fit process routine 1143 ! This routine solves the linear system proposed by 1144 ! C.Escorihuela-Sayalero see PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]] 1145 call fit_polynomial_coeff_solve(coeff_values(1:icycle_tmp),fcart_coeffs_tmp,fit_data%fcart_diff,& 1146 & energy_coeffs_tmp,fit_data%energy_diff,info,& 1147 & list_coeffs_tmp(1:icycle_tmp),natom_sc,icycle_tmp,ncycle_max,& 1148 & ntime,strten_coeffs_tmp,fit_data%strten_diff,& 1149 & fit_data%training_set%sqomega,fit_on,int_fit_factors) 1150 if(info==0)then 1151 call fit_polynomial_coeff_computeGF(coeff_values(1:icycle_tmp),energy_coeffs_tmp,& 1152 & fit_data%energy_diff,fcart_coeffs_tmp,fit_data%fcart_diff,& 1153 & gf_values(:,1),list_coeffs_tmp(1:icycle_tmp),natom_sc,& 1154 & icycle_tmp,ncycle_max,ntime,strten_coeffs_tmp,& 1155 & fit_data%strten_diff,fit_data%training_set%sqomega) 1156 1157 else!In this case the matrix is singular 1158 gf_values(:,icoeff) = zero 1159 singular_coeffs(icoeff) = 1 1160 end if 1161 1162 if(gf_values(1,1) > zero.and.abs(gf_values(1,1))>tol16.and.& 1163 & gf_values(1,1) < mingf(1) ) then 1164 mingf = gf_values(:,1) 1165 list_coeffs(1:icycle_tmp) = list_coeffs_tmp2(1:icycle_tmp) 1166 ncycle_tot = icycle_tmp 1167 1168 write(message, '(4x,a,3x,4ES18.10)') adjustl(j_char),& 1169 & gf_values(4,1)* (1000*Ha_ev)**2 *factor,& 1170 & gf_values(1,1)*HaBohr_eVAng**2,& 1171 & gf_values(2,1)*HaBohr_eVAng**2,& 1172 & gf_values(3,1)*HaBohr_eVAng**2 1173 if(need_verbose) call wrtout(std_out,message,'COLL') 1174 else 1175 list_coeffs_tmp2(1:icycle_tmp) = list_coeffs(1:icycle_tmp) 1176 end if 1177 end do 1178 1179 if(nproc > 1) then 1180 !TEST_AM 1181 do iproc=1,ncycle_tot 1182 stat_coeff(list_coeffs(iproc)) = stat_coeff(list_coeffs(iproc)) + 1 1183 end do 1184 !TEST_AM 1185 1186 ! Find the best model on all the CPUs 1187 buffGF(1,1) = zero 1188 buffGF(2:5,1) = mingf(:) 1189 call xmpi_allgatherv(buffGF,5,gf_mpi,buffsize,buffdisp, comm, ierr) 1190 ! find the best coeff 1191 mingf(:) = 9D99 1192 index_min= 0 1193 do iproc=1,nproc 1194 if(gf_mpi(2,iproc) < zero) cycle 1195 if(abs(gf_mpi(2,iproc)) <tol16) cycle 1196 if(gf_mpi(2,iproc) < mingf(1) ) then 1197 mingf(:) = gf_mpi(2:5,iproc) 1198 index_min = int(gf_mpi(1,iproc)) 1199 rank_to_send = iproc-1 1200 end if 1201 end do 1202 write(message, '(2a,I0)') ch10,' Best model found on the CPU: ', rank_to_send 1203 call wrtout(std_out,message,'COLL') 1204 end if 1205 end do 1206 1207 !TEST_AM 1208 ! call xmpi_sum(stat_coeff, comm, ierr) 1209 ! do ii=1,ncoeff_tot 1210 ! write(100,*) ii,stat_coeff(ii) 1211 ! end do 1212 ! close(100) 1213 !TEST_AM 1214 1215 ! Transfer final model 1216 if(nproc>1)then 1217 call xmpi_bcast(ncycle_tot,rank_to_send,comm,ierr) 1218 call xmpi_bcast(list_coeffs(1:ncycle_tot),rank_to_send,comm,ierr) 1219 end if 1220 do ii=1,ncycle_tot 1221 icoeff = list_coeffs(ii) 1222 list_coeffs_tmp(ii) = ii 1223 ! Fill the temporary arrays 1224 energy_coeffs_tmp(ii,:) = energy_coeffs(icoeff,:) 1225 fcart_coeffs_tmp(:,:,ii,:) = fcart_coeffs(:,:,icoeff,:) 1226 strten_coeffs_tmp(:,:,ii) = strten_coeffs(:,:,icoeff) 1227 call polynomial_coeff_free(coeffs_tmp(ii)) 1228 call polynomial_coeff_init(one,my_coeffs(icoeff)%nterm,& 1229 & coeffs_tmp(ii),my_coeffs(icoeff)%terms,& 1230 & my_coeffs(icoeff)%name,& 1231 & check=.false.) 1232 end do 1233 end select 1234 1235 !This routine solves the linear system proposed by 1236 ! C.Escorihuela-Sayalero see PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]] 1237 if(ncycle_tot > 0)then 1238 1239 call fit_polynomial_coeff_solve(coeff_values(1:ncycle_tot),fcart_coeffs_tmp,fit_data%fcart_diff,& 1240 & energy_coeffs_tmp,fit_data%energy_diff,info,& 1241 & list_coeffs_tmp(1:ncycle_tot),natom_sc,& 1242 & ncycle_tot,ncycle_max,ntime,strten_coeffs_tmp,& 1243 & fit_data%strten_diff,fit_data%training_set%sqomega,fit_on,int_fit_factors) 1244 1245 if(need_verbose) then 1246 write(message, '(3a)') ch10,' Fitted coefficients at the end of the fit process: ' 1247 call wrtout(ab_out,message,'COLL') 1248 call wrtout(std_out,message,'COLL') 1249 end if 1250 do ii = 1,ncycle_tot 1251 if(list_coeffs(ii) ==0) cycle 1252 ! Set the value of the coefficient 1253 coeffs_tmp(ii)%coefficient = coeff_values(ii) 1254 if(need_verbose) then 1255 write(message, '(a,I0,a,ES19.10,2a)') " ",list_coeffs(ii)," =>",coeff_values(ii),& 1256 & " ",trim(coeffs_tmp(ii)%name) 1257 call wrtout(ab_out,message,'COLL') 1258 call wrtout(std_out,message,'COLL') 1259 end if 1260 end do 1261 1262 call fit_polynomial_coeff_computeGF(coeff_values(1:ncycle_tot),energy_coeffs_tmp,& 1263 & fit_data%energy_diff,fcart_coeffs_tmp,fit_data%fcart_diff,& 1264 & gf_values(:,1),list_coeffs_tmp(1:ncycle_tot),natom_sc,& 1265 & ncycle_tot,ncycle_max,ntime,strten_coeffs_tmp,& 1266 & fit_data%strten_diff,fit_data%training_set%sqomega) 1267 1268 if(need_verbose) then 1269 ! Print the standard deviation after the fit 1270 write(message,'(4a,ES24.16,2a,ES24.16,2a,ES24.16,2a,ES24.16,a)' )ch10,& 1271 !& ' Mean Standard Deviation values at the end of the fit process (meV^2/atm): ',ch10,& 1272 !& ' Energy : ',& 1273 !& gf_values(4,1)*(Ha_EV*1000)**2 *factor ,ch10,& 1274 & ' Goal function values at the end of the fit process (eV^2/A^2):',ch10,& 1275 & ' Energy : ',& 1276 & gf_values(4,1)*(HaBohr_eVAng)**2,ch10,& 1277 & ' Forces+Stresses : ',& 1278 & gf_values(1,1)*(HaBohr_eVAng)**2,ch10,& 1279 & ' Forces : ',& 1280 & gf_values(2,1)*(HaBohr_eVAng)**2,ch10,& 1281 & ' Stresses : ',& 1282 & gf_values(3,1)*(HaBohr_eVAng)**2,ch10 1283 call wrtout(ab_out,message,'COLL') 1284 call wrtout(std_out,message,'COLL') 1285 end if 1286 1287 !Allocate output coeffs -> selected plus fixed ones 1288 ncoeff_out = ncycle_tot+eff_pot_fixed%anharmonics_terms%ncoeff 1289 ! DEBUG MS 1290 ! write(*,*) ncoeff_out,ncycle_tot 1291 ABI_MALLOC(coeffs_out,(ncoeff_out)) 1292 do ii = 1,ncoeff_out 1293 if(ii <= eff_pot_fixed%anharmonics_terms%ncoeff)then 1294 call polynomial_coeff_init(eff_pot_fixed%anharmonics_terms%coefficients(ii)%coefficient,& 1295 & eff_pot_fixed%anharmonics_terms%coefficients(ii)%nterm,coeffs_out(ii),& 1296 & eff_pot_fixed%anharmonics_terms%coefficients(ii)%terms,& 1297 & eff_pot_fixed%anharmonics_terms%coefficients(ii)%name,& 1298 & check = .TRUE.) 1299 else 1300 ia = ii - eff_pot_fixed%anharmonics_terms%ncoeff 1301 call polynomial_coeff_init(coeffs_tmp(ia)%coefficient,coeffs_tmp(ia)%nterm,& 1302 & coeffs_out(ii),coeffs_tmp(ia)%terms,& 1303 & coeffs_tmp(ia)%name,& 1304 & check=.true.) 1305 1306 endif 1307 ! DEBUG MS 1308 ! write(*,*) "coeffs_out(", ii,")%name:",coeffs_out(ii)%name 1309 enddo 1310 1311 1312 ! Set the final set of coefficients into the eff_pot type 1313 call effective_potential_setCoeffs(coeffs_out(:),eff_pot,ncoeff_out) 1314 1315 ! If Wanted open the anharmonic_terms_file and write header 1316 filename = "TRS_fit_diff" 1317 ncoeff_model = eff_pot%anharmonics_terms%ncoeff 1318 if(need_prt_anh .and. ncoeff_model > 0 )then 1319 call effective_potential_writeAnhHead(ncoeff_model,filename,& 1320 & eff_pot%anharmonics_terms) 1321 else if (need_prt_anh)then 1322 write(message, '(6a,I3,3a)' )ch10,& 1323 & ' --- !WARNING',ch10,& 1324 & ' Printing of anharmonic terms has been asked,but',ch10,& 1325 & ' there are',ncoeff_model,'anharmonic terms in the potential',ch10,& 1326 & ' ---',ch10 1327 call wrtout(ab_out,message,'COLL') 1328 call wrtout(std_out,message,'COLL') 1329 end if 1330 1331 ! Calculate MSD values for final model 1332 if(need_prt_files)call fit_polynomial_coeff_computeMSD(eff_pot,hist,gf_values(4,1),gf_values(2,1),gf_values(1,1),& 1333 & natom_sc,ntime,fit_data%training_set%sqomega,comm,& 1334 & compute_anharmonic=.TRUE.,print_file=.TRUE.,filename=filename) 1335 1336 1337 INQUIRE(FILE='TRS_fit_diff_anharmonic_terms_energy.dat',OPENED=file_opened,number=unit_anh) 1338 if(file_opened) close(unit_anh) 1339 1340 ! if(need_verbose) then 1341 ! ! Print the standard deviation after the fit 1342 ! write(message,'(4a,ES24.16,4a,ES24.16,2a,ES24.16,2a,ES24.16,a)' )ch10,& 1343 ! & ' Mean Standard Deviation values at the end of the fit process (meV/f.u.):',& 1344 ! & ch10,' Energy : ',& 1345 ! & gf_values(4,1)*Ha_EV*1000/ ncell ,ch10,& 1346 ! & ' Goal function values at the end of the fit process (eV^2/A^2):',ch10,& 1347 ! & ' Forces+Stresses : ',& 1348 ! & (gf_values(1,1)+gf_values(2,1))*(HaBohr_eVAng)**2,ch10,& 1349 ! & ' Forces : ',& 1350 ! & gf_values(2,1)*(HaBohr_eVAng)**2,ch10,& 1351 ! & ' Stresses : ',& 1352 ! & gf_values(3,1)*(HaBohr_eVAng)**2,ch10 1353 ! call wrtout(ab_out,message,'COLL') 1354 ! call wrtout(std_out,message,'COLL') 1355 ! end if 1356 1357 else 1358 ncoeff_out = 0 1359 if(need_verbose) then 1360 write(message, '(9a)' )ch10,& 1361 & ' --- !WARNING',ch10,& 1362 & ' The fit process does not provide possible terms.',ch10,& 1363 & ' Please make sure that the terms set is correct',ch10,& 1364 & ' ---',ch10 1365 call wrtout(ab_out,message,'COLL') 1366 call wrtout(std_out,message,'COLL') 1367 end if 1368 end if 1369 !Deallocation of arrays 1370 call fit_data_free(fit_data) 1371 1372 !Deallocate the temporary coefficient 1373 do ii=1,ncycle_max 1374 call polynomial_coeff_free(coeffs_tmp(ii)) 1375 end do 1376 ABI_FREE(coeffs_tmp) 1377 do ii=1,my_ncoeff 1378 call polynomial_coeff_free(my_coeffs(ii)) 1379 end do 1380 ABI_FREE(my_coeffs) 1381 do ii=1,ncoeff_out 1382 call polynomial_coeff_free(coeffs_out(ii)) 1383 end do 1384 ABI_FREE(coeffs_out) 1385 1386 1387 !Deallocate fixed eff_pot 1388 call effective_potential_free(eff_pot_fixed) 1389 1390 1391 !Other deallocations 1392 ABI_FREE(gf_values_iter) 1393 ABI_FREE(buffsize) 1394 ABI_FREE(buffdisp) 1395 ABI_FREE(buffGF) 1396 ABI_FREE(coeff_values) 1397 ABI_FREE(energy_coeffs) 1398 ABI_FREE(energy_coeffs_tmp) 1399 ABI_FREE(fcart_coeffs) 1400 ABI_FREE(fcart_coeffs_tmp) 1401 ABI_FREE(gf_mpi) 1402 ABI_FREE(gf_values) 1403 ABI_FREE(list_coeffs) 1404 ABI_FREE(list_coeffs_tmp) 1405 ABI_FREE(list_coeffs_tmp2) 1406 ABI_FREE(my_coeffindexes) 1407 ABI_FREE(my_coefflist) 1408 ABI_FREE(singular_coeffs) 1409 ABI_FREE(strten_coeffs) 1410 ABI_FREE(strten_coeffs_tmp) 1411 ABI_FREE(stat_coeff) 1412 1413 ABI_SFREE(fixcoeff_corr) 1414 ABI_SFREE(fix_and_impose) 1415 ABI_SFREE(list_coeffs_copy) 1416 1417 end subroutine fit_polynomial_coeff_fit
m_fit_polynomial_coeff/fit_polynomial_coeff_getCoeffBound [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_getCoeffBound
FUNCTION
This routine fit a list of possible model. Return in the isPositive array:
INPUTS
NEED TO UPDATE eff_pot<type(effective_potential)> = effective potential hist<type(abihist)> = The history of the MD (or snapshot of DFT comm = MPI communicator verbose = optional, flag for the verbose mode
OUTPUT
SOURCE
1650 subroutine fit_polynomial_coeff_getCoeffBound(eff_pot,coeffs_out,hist,ncoeff_bound,comm,verbose) 1651 1652 implicit none 1653 1654 !Arguments ------------------------------------ 1655 !scalars 1656 integer,intent(in) :: comm 1657 integer,intent(out) :: ncoeff_bound 1658 logical,optional,intent(in) :: verbose 1659 !arrays 1660 type(abihist),intent(inout) :: hist 1661 type(effective_potential_type),target,intent(inout) :: eff_pot 1662 type(polynomial_coeff_type),allocatable,intent(out) :: coeffs_out(:) 1663 !Local variables------------------------------- 1664 !scalar 1665 integer :: counter,icoeff,icoeff_bound,idisp,istrain,ii 1666 integer :: istart,iterm,ndisp,nstrain,nterm,ncoeff_model,ncoeff_in,ncoeff_max 1667 real(dp):: weight 1668 logical :: need_verbose 1669 !arrays 1670 integer,allocatable :: atindx(:,:),cells(:,:,:),direction(:) 1671 integer,allocatable :: power_disps(:),power_strain(:),strain(:) 1672 type(polynomial_term_type),dimension(:),allocatable :: terms 1673 integer,allocatable :: odd_coeff(:),need_bound(:) 1674 type(polynomial_coeff_type),pointer :: coeffs_in(:) 1675 type(polynomial_coeff_type),allocatable :: coeffs_test(:) 1676 character(len=5),allocatable :: symbols(:) 1677 character(len=200):: name 1678 character(len=500) :: msg 1679 ! ************************************************************************* 1680 1681 1682 !set the inputs varaibles 1683 ncoeff_model = eff_pot%anharmonics_terms%ncoeff 1684 coeffs_in => eff_pot%anharmonics_terms%coefficients 1685 1686 !Do check 1687 if(ncoeff_model == 0)then 1688 write(msg,'(a)')'ncoeff_model must be different to 0' 1689 ABI_BUG(msg) 1690 end if 1691 1692 !Map the hist in order to be consistent with the supercell into reference_effective_potential 1693 call effective_potential_file_mapHistToRef(eff_pot,hist,comm) 1694 1695 !Initialisation of optional arguments 1696 need_verbose = .TRUE. 1697 if(present(verbose)) need_verbose = verbose 1698 1699 write(msg, '(a)' ) ' Detection of the unbound coefficients' 1700 if(need_verbose)call wrtout(std_out,msg,'COLL') 1701 1702 !Allocation 1703 ncoeff_max = 2 * ncoeff_model 1704 ABI_MALLOC(odd_coeff,(ncoeff_max)) 1705 ABI_MALLOC(need_bound,(ncoeff_max)) 1706 1707 ABI_MALLOC(symbols,(eff_pot%crystal%natom)) 1708 call symbols_crystal(eff_pot%crystal%natom,eff_pot%crystal%ntypat,eff_pot%crystal%npsp,& 1709 & symbols,eff_pot%crystal%typat,eff_pot%crystal%znucl) 1710 1711 1712 ABI_MALLOC(coeffs_test,(ncoeff_max)) 1713 1714 do icoeff=1,ncoeff_model 1715 call polynomial_coeff_init(coeffs_in(icoeff)%coefficient,coeffs_in(icoeff)%nterm,& 1716 & coeffs_test(icoeff),coeffs_in(icoeff)%terms,& 1717 & coeffs_in(icoeff)%name,check=.false.) 1718 end do 1719 1720 !array to know which coeff has to be bound 1721 need_bound(:) = 1 1722 counter = 0 1723 ncoeff_in = ncoeff_model 1724 1725 do while(.not.all(need_bound == 0).and.counter<1) 1726 ! Get the coefficients with odd coefficient 1727 odd_coeff = 0 1728 if(counter>0) then 1729 need_bound(1:ncoeff_in) = 0 1730 icoeff_bound = ncoeff_in 1731 else 1732 icoeff_bound = 1 1733 end if 1734 1735 do icoeff=icoeff_bound,ncoeff_model 1736 if(any(mod(coeffs_in(icoeff)%terms(1)%power_disp(:),2)/=0))then 1737 odd_coeff(icoeff) = 1 1738 end if 1739 if(any(mod(coeffs_in(icoeff)%terms(1)%power_strain(:),2)/=0))then 1740 odd_coeff(icoeff) = 1 1741 end if 1742 if(odd_coeff(icoeff) == 0 .and. coeffs_in(icoeff)%coefficient > zero) then 1743 need_bound(icoeff) = 0 1744 else 1745 need_bound(icoeff) = 1 1746 end if 1747 end do 1748 if(need_verbose)then 1749 write(msg, '(a)' ) ' The following coefficients need to be bound:' 1750 call wrtout(std_out,msg,'COLL') 1751 do icoeff=1,ncoeff_model 1752 if(need_bound(icoeff) == 1)then 1753 write(msg, '(2a)' ) ' =>',trim(coeffs_in(icoeff)%name) 1754 call wrtout(std_out,msg,'COLL') 1755 end if 1756 end do 1757 end if 1758 1759 1760 icoeff_bound = ncoeff_in + 1 1761 if(counter==0)then 1762 istart = 1 1763 else 1764 istart = ncoeff_in 1765 end if 1766 1767 ncoeff_bound = count(need_bound(istart:ncoeff_model)==1) 1768 1769 do icoeff=istart,ncoeff_model 1770 if(need_bound(icoeff)==1)then 1771 1772 nterm = coeffs_in(icoeff)%nterm 1773 ndisp = coeffs_in(icoeff)%terms(1)%ndisp 1774 nstrain = coeffs_in(icoeff)%terms(1)%nstrain 1775 1776 ABI_MALLOC(terms,(nterm)) 1777 ABI_MALLOC(atindx,(2,ndisp)) 1778 ABI_MALLOC(cells,(3,2,ndisp)) 1779 ABI_MALLOC(direction,(ndisp)) 1780 ABI_MALLOC(power_disps,(ndisp)) 1781 ABI_MALLOC(power_strain,(nstrain)) 1782 ABI_MALLOC(strain,(nstrain)) 1783 1784 do iterm=1,coeffs_in(icoeff)%nterm 1785 atindx(:,:) = coeffs_in(icoeff)%terms(iterm)%atindx(:,:) 1786 cells(:,:,:) = coeffs_in(icoeff)%terms(iterm)%cell(:,:,:) 1787 direction(:) = coeffs_in(icoeff)%terms(iterm)%direction(:) 1788 power_strain(:) = coeffs_in(icoeff)%terms(iterm)%power_strain(:) 1789 power_disps(:) = coeffs_in(icoeff)%terms(iterm)%power_disp(:) 1790 strain(:) = coeffs_in(icoeff)%terms(iterm)%strain(:) 1791 weight = 1 1792 do idisp=1,ndisp 1793 if(mod(power_disps(idisp),2) /= 0) then 1794 power_disps(idisp) = power_disps(idisp) + 1 1795 else 1796 power_disps(idisp) = power_disps(idisp) + 2 1797 end if 1798 end do 1799 do istrain=1,nstrain 1800 if(mod(power_strain(istrain),2) /= 0)then 1801 power_strain(istrain) = power_strain(istrain) + 1 1802 else 1803 if(power_strain(istrain) < 4 ) power_strain(istrain) = power_strain(istrain) + 2 1804 end if 1805 end do 1806 1807 call polynomial_term_init(atindx,cells,direction,ndisp,nstrain,terms(iterm),& 1808 & power_disps,power_strain,strain,weight,check=.true.) 1809 end do 1810 1811 name = "" 1812 call polynomial_coeff_init(one,nterm,coeffs_test(icoeff_bound),terms,name,check=.true.) 1813 call polynomial_coeff_getName(name,coeffs_test(icoeff_bound),symbols,recompute=.TRUE.) 1814 call polynomial_coeff_SetName(name,coeffs_test(icoeff_bound)) 1815 1816 ! Deallocate the terms 1817 do iterm=1,nterm 1818 call polynomial_term_free(terms(iterm)) 1819 end do 1820 ABI_FREE(terms) 1821 ABI_FREE(atindx) 1822 ABI_FREE(cells) 1823 ABI_FREE(direction) 1824 ABI_FREE(power_disps) 1825 ABI_FREE(power_strain) 1826 ABI_FREE(strain) 1827 1828 icoeff_bound = icoeff_bound + 1 1829 1830 end if 1831 end do 1832 1833 1834 if(counter==0)ncoeff_model = ncoeff_model + ncoeff_bound 1835 ! call effective_potential_setCoeffs(coeffs_test,eff_pot,ncoeff_model) 1836 call fit_polynomial_coeff_fit(eff_pot,(/0/),(/0/),hist,0,(/0,0/),1,0,& 1837 & -1,0,(/0/),1,comm,verbose=.true.,positive=.false.) 1838 1839 coeffs_in => eff_pot%anharmonics_terms%coefficients 1840 1841 counter = counter + 1 1842 end do 1843 1844 ABI_MALLOC(coeffs_out,(ncoeff_bound)) 1845 do ii=1,ncoeff_bound 1846 icoeff_bound = ncoeff_in + ii 1847 call polynomial_coeff_init(one,coeffs_test(icoeff_bound)%nterm,coeffs_out(ii),& 1848 & coeffs_test(icoeff_bound)%terms,coeffs_test(icoeff_bound)%name,check=.true.) 1849 end do 1850 !Deallocation 1851 do ii=ncoeff_model,ncoeff_max 1852 call polynomial_coeff_free(coeffs_test(ii)) 1853 end do 1854 1855 !Deallocation 1856 do icoeff=1,ncoeff_max 1857 call polynomial_coeff_free(coeffs_test(icoeff)) 1858 end do 1859 ABI_FREE(coeffs_test) 1860 ABI_FREE(odd_coeff) 1861 ABI_FREE(need_bound) 1862 ABI_FREE(symbols) 1863 1864 1865 end subroutine fit_polynomial_coeff_getCoeffBound
m_fit_polynomial_coeff/fit_polynomial_coeff_getFS [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_getFS
FUNCTION
Compute all the matrix elements of eq.11 and 12 in PRB95,094115 (2017) [[cite:Escorihuela-Sayalero2017]]
INPUTS
coefficients(ncoeff) = type(polynomial_coeff_type) du_delta(6,3,natom_sc,ntime) = Variation to displacements wrt to the strain (Bohr) displacement(3,natom_sc,ntime)= Atomic displacement wrt to the reference (Bohr) natom_sc = Number of atoms in the supercell natom_uc = Number of atoms in the unit cell ncoeff = Number of coefficients ntime = Number of time in the history sc_size(3) = Size of the supercell strain(6,ntime) = Strain ucvol(ntime) = Volume of the supercell for each time (Bohr^3) cells(ncell) = Indexes of the cell treat by this CPU ncell = Number of cell treat by this CPU index_cells(ncell,3) = Indexes of the cells (1 1 1, 0 0 0 for instance) treat by this CPU comm = MPI communicator
OUTPUT
fcart_out(ncoeff,3,natom,ntime) = value of the forces for each coefficient (-1 factor is taking into acount) (Ha/Bohr) strten_out(ncoeff,3,natom,ntime)= value of the stresses for each coefficient (-1/ucvol factor is taking into acount) (Ha/Bohr^3) energy_out(ncoeff,ntime) = value of the energy for each coefficient (Ha)
SOURCE
2230 subroutine fit_polynomial_coeff_getFS(coefficients,du_delta,displacement,energy_out,fcart_out,& 2231 & natom_sc,natom_uc,ncoeff_max,ntime,sc_size,strain,strten_out,& 2232 & ucvol,coeffs,ncoeff) 2233 2234 implicit none 2235 2236 !Arguments ------------------------------------ 2237 !scalars 2238 integer,intent(in) :: natom_sc,natom_uc,ncoeff_max,ntime 2239 integer,intent(in) :: ncoeff 2240 !arrays 2241 integer,intent(in) :: sc_size(3) 2242 integer,intent(in) :: coeffs(ncoeff_max) 2243 real(dp),intent(in) :: du_delta(6,3,natom_sc,ntime) 2244 real(dp),intent(in) :: displacement(3,natom_sc,ntime) 2245 real(dp),intent(in) :: strain(6,ntime),ucvol(ntime) 2246 real(dp),intent(out):: energy_out(ncoeff,ntime) 2247 real(dp),intent(out) :: fcart_out(3,natom_sc,ncoeff,ntime) 2248 real(dp),intent(out) :: strten_out(6,ntime,ncoeff) 2249 type(polynomial_coeff_type), intent(in) :: coefficients(ncoeff_max) 2250 !Local variables------------------------------- 2251 !scalar 2252 integer :: i1,i2,i3,ia1,ia2,ib1,ib2,ii,icell,icoeff,icoeff_tmp 2253 integer :: idir1,idir2,idisp1,idisp2,idisp1_strain,idisp2_strain 2254 integer :: iterm,itime,ndisp,ndisp_tot,nstrain,power_disp,power_strain 2255 real(dp):: disp1,disp2,tmp1,tmp2,tmp3,weight 2256 !arrays 2257 integer :: cell_atoma1(3),cell_atoma2(3) 2258 integer :: cell_atomb1(3),cell_atomb2(3) 2259 2260 ! ************************************************************************* 2261 2262 2263 !1-Get forces and stresses from the model 2264 ! Initialisation of variables 2265 fcart_out(:,:,:,:) = zero 2266 strten_out(:,:,:) = zero 2267 energy_out(:,:) = zero 2268 2269 icell = 0; ib1=0; ia1=0 2270 do i1=1,sc_size(1) 2271 do i2=1,sc_size(2) 2272 do i3=1,sc_size(3) 2273 ii = icell*natom_uc 2274 icell = icell + 1 2275 ! Loop over configurations 2276 do itime=1,ntime 2277 ! Loop over coefficients 2278 do icoeff_tmp=1,ncoeff 2279 icoeff = coeffs(icoeff_tmp) 2280 ! Loop over terms of this coefficient 2281 do iterm=1,coefficients(icoeff)%nterm 2282 ndisp = coefficients(icoeff)%terms(iterm)%ndisp 2283 nstrain = coefficients(icoeff)%terms(iterm)%nstrain 2284 ndisp_tot = ndisp + nstrain 2285 ! Set the weight of this term 2286 weight =coefficients(icoeff)%terms(iterm)%weight 2287 tmp1 = one 2288 ! Loop over displacement and strain 2289 do idisp1=1,ndisp_tot 2290 2291 ! Set to one the acculation of forces and strain 2292 tmp2 = one 2293 tmp3 = one 2294 ! Strain case idir => -6, -5, -4, -3, -2 or -1 2295 if (idisp1 > ndisp)then 2296 idisp1_strain = idisp1 - ndisp 2297 power_strain = coefficients(icoeff)%terms(iterm)%power_strain(idisp1_strain) 2298 ! Get the direction of the displacement or strain 2299 idir1 = coefficients(icoeff)%terms(iterm)%strain(idisp1_strain) 2300 if(abs(strain(idir1,itime)) > tol10)then 2301 ! Accumulate energy fo each displacement (\sum ((A_x-O_x)^Y(A_y-O_c)^Z)) 2302 tmp1 = tmp1 * (strain(idir1,itime))**power_strain 2303 if(power_strain > 1) then 2304 ! Accumulate stress for each strain (\sum (Y(eta_2)^Y-1(eta_2)^Z+...)) 2305 tmp3 = tmp3 * power_strain*(strain(idir1,itime))**(power_strain-1) 2306 end if 2307 else 2308 tmp1 = zero 2309 if(power_strain > 1) then 2310 tmp3 = zero 2311 end if 2312 end if 2313 else 2314 ! Set the power_disp of the displacement: 2315 power_disp = coefficients(icoeff)%terms(iterm)%power_disp(idisp1) 2316 ! Get the direction of the displacement or strain 2317 idir1 = coefficients(icoeff)%terms(iterm)%direction(idisp1) 2318 ! Displacement case idir = 1, 2 or 3 2319 ! indexes of the cell of the atom a 2320 cell_atoma1 = coefficients(icoeff)%terms(iterm)%cell(:,1,idisp1) 2321 if(cell_atoma1(1)/=0.or.cell_atoma1(2)/=0.or.cell_atoma1(3)/=0) then 2322 ! if the cell is not 0 0 0 we apply PBC: 2323 cell_atoma1(1) = i1 + cell_atoma1(1) 2324 cell_atoma1(2) = i2 + cell_atoma1(2) 2325 cell_atoma1(3) = i3 + cell_atoma1(3) 2326 call getPBCIndexes_supercell(cell_atoma1(1:3),sc_size(1:3)) 2327 ! index of the first atom (position in the supercell if the cell is not 0 0 0) 2328 ia1 = (cell_atoma1(1)-1)*sc_size(2)*sc_size(3)*natom_uc+& 2329 & (cell_atoma1(2)-1)*sc_size(3)*natom_uc+& 2330 & (cell_atoma1(3)-1)*natom_uc+& 2331 & coefficients(icoeff)%terms(iterm)%atindx(1,idisp1) 2332 else 2333 ! index of the first atom (position in the supercell if the cell is 0 0 0) 2334 ia1 = ii + coefficients(icoeff)%terms(iterm)%atindx(1,idisp1) 2335 end if 2336 2337 ! indexes of the cell of the atom b (with PBC) same as ia1 2338 cell_atomb1 = coefficients(icoeff)%terms(iterm)%cell(:,2,idisp1) 2339 if(cell_atomb1(1)/=0.or.cell_atomb1(2)/=0.or.cell_atomb1(3)/=0) then 2340 cell_atomb1(1) = i1 + cell_atomb1(1) 2341 cell_atomb1(2) = i2 + cell_atomb1(2) 2342 cell_atomb1(3) = i3 + cell_atomb1(3) 2343 call getPBCIndexes_supercell(cell_atomb1(1:3),sc_size(1:3)) 2344 2345 ! index of the second atom in the (position in the supercell if the cell is not 0 0 0) 2346 ib1 = (cell_atomb1(1)-1)*sc_size(2)*sc_size(3)*natom_uc+& 2347 & (cell_atomb1(2)-1)*sc_size(3)*natom_uc+& 2348 & (cell_atomb1(3)-1)*natom_uc+& 2349 & coefficients(icoeff)%terms(iterm)%atindx(2,idisp1) 2350 else 2351 ! index of the first atom (position in the supercell if the cell is 0 0 0) 2352 ib1 = ii + coefficients(icoeff)%terms(iterm)%atindx(2,idisp1) 2353 end if 2354 2355 ! Get the displacement for the both atoms 2356 disp1 = displacement(idir1,ia1,itime) 2357 disp2 = displacement(idir1,ib1,itime) 2358 2359 if(abs(disp1) > tol10 .or. abs(disp2)> tol10)then 2360 ! Accumulate energy fo each displacement (\sum ((A_x-O_x)^Y(A_y-O_c)^Z)) 2361 tmp1 = tmp1 * (disp1-disp2)**power_disp 2362 if(power_disp > 1) then 2363 ! Accumulate forces for each displacement (\sum (Y(A_x-O_x)^Y-1(A_y-O_c)^Z+...)) 2364 tmp2 = tmp2 * power_disp*(disp1-disp2)**(power_disp-1) 2365 end if 2366 else 2367 tmp1 = zero 2368 if(power_disp > 1) then 2369 tmp2 = zero 2370 end if 2371 end if 2372 end if 2373 2374 do idisp2=1,ndisp_tot 2375 if(idisp2 /= idisp1) then 2376 2377 ! Strain case 2378 if (idisp2 > ndisp)then 2379 idisp2_strain = idisp2 - ndisp 2380 idir2 = coefficients(icoeff)%terms(iterm)%strain(idisp2_strain) 2381 ! Set the power_strain of the strain: 2382 power_strain = coefficients(icoeff)%terms(iterm)%power_strain(idisp2_strain) 2383 ! Accumulate energy forces 2384 tmp2 = tmp2 * (strain(idir2,itime))**power_strain 2385 ! Accumulate stress for each strain (\sum (Y(eta_2)^Y-1(eta_2)^Z+...)) 2386 tmp3 = tmp3 * (strain(idir2,itime))**power_strain 2387 ! Atomic displacement case 2388 else 2389 ! Set the power_disp of the displacement: 2390 power_disp = coefficients(icoeff)%terms(iterm)%power_disp(idisp2) 2391 ! Set the direction of the displacement: 2392 idir2 = coefficients(icoeff)%terms(iterm)%direction(idisp2) 2393 2394 cell_atoma2=coefficients(icoeff)%terms(iterm)%cell(:,1,idisp2) 2395 if(cell_atoma2(1)/=0.or.cell_atoma2(2)/=0.or.cell_atoma2(3)/=0) then 2396 cell_atoma2(1) = i1 + cell_atoma2(1) 2397 cell_atoma2(2) = i2 + cell_atoma2(2) 2398 cell_atoma2(3) = i3 + cell_atoma2(3) 2399 call getPBCIndexes_supercell(cell_atoma2(1:3),sc_size(1:3)) 2400 ! index of the first atom (position in the supercell and direction) 2401 ! if the cell of the atom a is not 0 0 0 (may happen) 2402 ia2 = (cell_atoma2(1)-1)*sc_size(2)*sc_size(3)*natom_uc+& 2403 & (cell_atoma2(2)-1)*sc_size(3)*natom_uc+& 2404 & (cell_atoma2(3)-1)*natom_uc+& 2405 & coefficients(icoeff)%terms(iterm)%atindx(1,idisp2) 2406 else 2407 ! index of the first atom (position in the supercell and direction) 2408 ia2 = ii + coefficients(icoeff)%terms(iterm)%atindx(1,idisp2) 2409 end if 2410 2411 cell_atomb2 = coefficients(icoeff)%terms(iterm)%cell(:,2,idisp2) 2412 2413 if(cell_atomb2(1)/=0.or.cell_atomb2(2)/=0.or.cell_atomb2(3)/=0) then 2414 ! indexes of the cell2 (with PBC) 2415 cell_atomb2(1) = i1 + cell_atomb2(1) 2416 cell_atomb2(2) = i2 + cell_atomb2(2) 2417 cell_atomb2(3) = i3 + cell_atomb2(3) 2418 call getPBCIndexes_supercell(cell_atomb2(1:3),sc_size(1:3)) 2419 2420 ! index of the second atom in the (position in the supercell) 2421 ib2 = (cell_atomb2(1)-1)*sc_size(2)*sc_size(3)*natom_uc+& 2422 & (cell_atomb2(2)-1)*sc_size(3)*natom_uc+& 2423 & (cell_atomb2(3)-1)*natom_uc+& 2424 & coefficients(icoeff)%terms(iterm)%atindx(2,idisp2) 2425 else 2426 ib2 = ii + coefficients(icoeff)%terms(iterm)%atindx(2,idisp2) 2427 end if 2428 2429 disp1 = displacement(idir2,ia2,itime) 2430 disp2 = displacement(idir2,ib2,itime) 2431 2432 tmp2 = tmp2 * (disp1-disp2)**power_disp 2433 tmp3 = tmp3 * (disp1-disp2)**power_disp 2434 2435 end if 2436 end if 2437 end do 2438 2439 if(idisp1 > ndisp)then 2440 ! Accumule stress tensor 2441 strten_out(idir1,itime,icoeff_tmp) = strten_out(idir1,itime,icoeff_tmp) + & 2442 & weight * tmp3 / ucvol(itime) 2443 else 2444 ! Accumule forces 2445 fcart_out(idir1,ia1,icoeff_tmp,itime)=fcart_out(idir1,ia1,icoeff_tmp,itime)+weight*tmp2 2446 fcart_out(idir1,ib1,icoeff_tmp,itime)=fcart_out(idir1,ib1,icoeff_tmp,itime)-weight*tmp2 2447 end if 2448 end do 2449 2450 ! accumule energy 2451 energy_out(icoeff_tmp,itime) = energy_out(icoeff_tmp,itime) + weight * tmp1 2452 2453 end do!End do iterm 2454 end do!End do coeff 2455 end do!End time 2456 end do!End do i3 2457 end do!End do i2 2458 end do!End do i1 2459 2460 ! multiply by -1 2461 fcart_out(:,:,:,:) = -1 * fcart_out(:,:,:,:) 2462 2463 !ADD stress due to forces on atoms and variation of disp with strain 2464 do icoeff=1,ncoeff 2465 do itime=1,ntime 2466 do ia1=1,natom_sc 2467 do idir1=1,3 2468 do idir2=1,6 2469 strten_out(idir2,itime,icoeff) = strten_out(idir2,itime,icoeff) + & 2470 & du_delta(idir2,idir1,ia1,itime)*fcart_out(idir1,ia1,icoeff,itime)/ucvol(itime) 2471 end do 2472 end do 2473 end do 2474 end do 2475 end do 2476 2477 2478 end subroutine fit_polynomial_coeff_getFS
m_fit_polynomial_coeff/fit_polynomial_coeff_getPositive [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_getPositive
FUNCTION
This routine fit a list of possible model. Return in the isPositive array: 0 if the model ii does not contain possive coefficients 1 if the model ii contain possive coefficients
INPUTS
eff_pot<type(effective_potential)> = effective potential hist<type(abihist)> = The history of the MD (or snapshot of DFT coeff_values(nmodel,ncoeff) = values of the coefficients for each model isPositive(nmodel) = see description below list_coeff(nmodel,ncoeff) = list of the models ncoeff = number of coeff per model nfixcoeff = will not test the nfixcoeff first coeffcients nmodel = number of model comm = MPI communicator verbose = optional, flag for the verbose mode
OUTPUT
eff_pot = effective potential datatype with new fitted coefficients
SOURCE
1448 subroutine fit_polynomial_coeff_getPositive(eff_pot,hist,coeff_values,isPositive,list_coeff,ncoeff,& 1449 & nfixcoeff,nmodel,comm,verbose) 1450 1451 implicit none 1452 1453 !Arguments ------------------------------------ 1454 !scalars 1455 integer,intent(in) :: ncoeff,nfixcoeff,nmodel,comm 1456 !arrays 1457 integer,intent(in) :: list_coeff(nmodel,ncoeff) 1458 integer,intent(out) :: isPositive(nmodel) 1459 real(dp),intent(out) :: coeff_values(nmodel,ncoeff) 1460 type(effective_potential_type),intent(inout) :: eff_pot 1461 type(abihist),intent(inout) :: hist 1462 logical,optional,intent(in) :: verbose 1463 !Local variables------------------------------- 1464 !scalar 1465 integer :: ierr,ii,info,imodel,my_nmodel,nmodel_alone 1466 integer :: master,my_rank,ncoeff_tot,natom_sc,ncell 1467 integer :: nproc,ntime 1468 logical :: iam_master,need_verbose 1469 !arrays 1470 integer :: sc_size(3) 1471 integer,allocatable :: list_coeffs(:),my_modelindexes(:),my_modellist(:) 1472 real(dp),allocatable :: energy_coeffs(:,:),fcart_coeffs(:,:,:,:), strten_coeffs(:,:,:) 1473 type(polynomial_coeff_type),allocatable :: coeffs_in(:) 1474 type(fit_data_type) :: fit_data 1475 character(len=500) :: message 1476 logical :: fit_on(3) 1477 real(dp) :: fit_factors(3) 1478 ! ************************************************************************* 1479 1480 !MPI variables 1481 master = 0 1482 nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 1483 iam_master = (my_rank == master) 1484 1485 !Initialisation of optional arguments 1486 need_verbose = .TRUE. 1487 if(present(verbose)) need_verbose = verbose 1488 1489 fit_on(1) = .FALSE. 1490 fit_on(2) = .TRUE. 1491 fit_on(3) = .TRUE. 1492 1493 fit_factors = (/1,1,1/) 1494 1495 !Get the list of coefficients from the eff_pot 1496 if(eff_pot%anharmonics_terms%ncoeff > 0)then 1497 ! Copy the initial coefficients array 1498 ncoeff_tot = eff_pot%anharmonics_terms%ncoeff 1499 ABI_MALLOC(coeffs_in,(ncoeff_tot)) 1500 do ii=1,ncoeff_tot 1501 call polynomial_coeff_init(eff_pot%anharmonics_terms%coefficients(ii)%coefficient,& 1502 & eff_pot%anharmonics_terms%coefficients(ii)%nterm,& 1503 & coeffs_in(ii),& 1504 & eff_pot%anharmonics_terms%coefficients(ii)%terms,& 1505 & eff_pot%anharmonics_terms%coefficients(ii)%name,& 1506 & check=.false.) 1507 end do 1508 end if 1509 1510 !Reset the output (we free the memory) 1511 call effective_potential_freeCoeffs(eff_pot) 1512 1513 !if the number of atoms in reference supercell into effpot is not corret, 1514 !wrt to the number of atom in the hist, we set map the hist and set the good 1515 !supercell 1516 if (size(hist%xred,2) /= eff_pot%supercell%natom) then 1517 call effective_potential_file_mapHistToRef(eff_pot,hist,comm,verbose=need_verbose) 1518 end if 1519 1520 !Initialisation of constants 1521 natom_sc = eff_pot%supercell%natom 1522 ncell = eff_pot%supercell%ncells 1523 ntime = hist%mxhist 1524 do ii = 1, 3 1525 sc_size(ii) = eff_pot%supercell%rlatt(ii,ii) 1526 end do 1527 1528 !Initialisation of arrays: 1529 ABI_MALLOC(list_coeffs,(ncoeff_tot)) 1530 list_coeffs = 0 1531 do ii = 1,ncoeff_tot 1532 list_coeffs(ii) = ii 1533 end do 1534 1535 !Get the decomposition for each coefficients of the forces and stresses for 1536 !each atoms and each step equations 11 & 12 of PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]] 1537 if(need_verbose)then 1538 write(message, '(a)' ) ' Initialisation of the fit process...' 1539 call wrtout(std_out,message,'COLL') 1540 end if 1541 !Before the fit, compute constants with fit_data_compute. 1542 !Conpute the strain of each configuration. 1543 !Compute the displacmeent of each configuration. 1544 !Compute the variation of the displacement due to strain of each configuration. 1545 !Compute fixed forces and stresse and get the standard deviation. 1546 !Compute Sheppard and al Factors \Omega^{2} see J.Chem Phys 136, 074103 (2012) [[cite:Sheppard2012]]. 1547 call fit_data_compute(fit_data,eff_pot,hist,comm,verbose=need_verbose) 1548 1549 !Get the decomposition for each coefficients of the forces,stresses and energy for 1550 !each atoms and each step (see equations 11 & 12 of 1551 ! PRB95,094115(2017)) [[cite:Escorihuela-Sayalero2017]] + allocation 1552 ABI_MALLOC(energy_coeffs,(ncoeff_tot,ntime)) 1553 ABI_MALLOC(fcart_coeffs,(3,natom_sc,ncoeff_tot,ntime)) 1554 ABI_MALLOC(strten_coeffs,(6,ntime,ncoeff_tot)) 1555 1556 call fit_polynomial_coeff_getFS(coeffs_in,fit_data%training_set%du_delta,& 1557 & fit_data%training_set%displacement,& 1558 & energy_coeffs,fcart_coeffs,natom_sc,eff_pot%crystal%natom,& 1559 & ncoeff_tot,ntime,sc_size,& 1560 & fit_data%training_set%strain,strten_coeffs,& 1561 & fit_data%training_set%ucvol,list_coeffs,ncoeff_tot) 1562 1563 1564 !set MPI, really basic stuff... 1565 nmodel_alone = mod(nmodel,nproc) 1566 my_nmodel = int(aint(real(nmodel,sp)/(nproc))) 1567 1568 if(my_rank >= (nproc-nmodel_alone)) then 1569 my_nmodel = my_nmodel + 1 1570 end if 1571 1572 ABI_MALLOC(my_modelindexes,(my_nmodel)) 1573 ABI_MALLOC(my_modellist,(my_nmodel)) 1574 1575 !2:compute the number of model and the list of the corresponding for each CPU. 1576 do imodel=1,my_nmodel 1577 if(my_rank >= (nproc-nmodel_alone))then 1578 my_modelindexes(imodel)=(int(aint(real(nmodel,sp)/nproc)))*(my_rank)+& 1579 & (my_rank - (nproc-nmodel_alone)) + imodel 1580 my_modellist(imodel) = imodel 1581 else 1582 my_modelindexes(imodel)=(my_nmodel)*(my_rank) + imodel 1583 my_modellist(imodel) = imodel 1584 end if 1585 end do 1586 1587 1588 !Start fit process 1589 isPositive = 0 1590 coeff_values = zero 1591 do ii=1,my_nmodel 1592 imodel = my_modelindexes(ii) 1593 call fit_polynomial_coeff_solve(coeff_values(imodel,1:ncoeff),fcart_coeffs,fit_data%fcart_diff,& 1594 & energy_coeffs,fit_data%energy_diff,info,& 1595 & list_coeff(imodel,1:ncoeff),natom_sc,ncoeff,& 1596 & ncoeff_tot,ntime,strten_coeffs,fit_data%strten_diff,& 1597 & fit_data%training_set%sqomega,fit_on,fit_factors) 1598 1599 if(info==0)then 1600 1601 if (any(coeff_values(imodel,nfixcoeff+1:ncoeff) < zero))then 1602 ! coeff_values(imodel,:) = zero 1603 isPositive(imodel) = 0 1604 else 1605 isPositive(imodel) = 1 1606 end if 1607 end if 1608 end do 1609 1610 call xmpi_sum(isPositive, comm, ierr) 1611 call xmpi_sum(coeff_values, comm, ierr) 1612 1613 !Deallocation of arrays 1614 do ii=1,ncoeff_tot 1615 call polynomial_coeff_free(coeffs_in(ii)) 1616 end do 1617 call fit_data_free(fit_data) 1618 ABI_FREE(coeffs_in) 1619 ABI_FREE(energy_coeffs) 1620 ABI_FREE(fcart_coeffs) 1621 ABI_FREE(list_coeffs) 1622 ABI_FREE(my_modelindexes) 1623 ABI_FREE(my_modellist) 1624 ABI_FREE(strten_coeffs) 1625 1626 end subroutine fit_polynomial_coeff_getPositive
m_fit_polynomial_coeff/fit_polynomial_coeff_solve [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_coeff_solve
FUNCTION
Build and the solve the system to get the values of the coefficients This routine solves the linear system proposed by C.Escorihuela-Sayalero see PRB95,094115(2017) [[cite:Escorihuela-Sayalero2017]]
INPUTS
fcart_coeffs(3,natom_sc,ncoeff_max,ntime) = List of the values of the contribution to the cartesian forces for all coefficients for each direction and each time fcart_diff(3,natom,ntime) = Difference of cartesian forces between DFT calculation and fixed part of the model (more often harmonic part) energy_coeffs(ncoeff,ntime) = value of the energy for each coefficient (Ha) energy_diff(ntime) = Difference of energ ybetween DFT calculation and fixed part of the model (more often harmonic part) list_coeffs(ncoeff_fit) = List with the index of the coefficients used for this model natom = Number of atoms ncoeff_fit = Number of coeff for the fit (dimension of the system) ncoeff_max = Maximum number of coeff in the list ntime = Number of time (number of snapshot, number of md step...) strten_coeffs(6,ntime,ncoeff_max) = List of the values of the contribution to the stress tensor of the coefficients for each direction,time strten_diff(6,natom) = Difference of stress tensor between DFT calculation and fixed part of the model (more often harmonic part) sqomega(ntime) = Sheppard and al Factors \Omega^{2} see J.Chem Phys 136, 074103 (2012) [[cite:Sheppard2012]]
OUTPUT
coefficients(ncoeff_fit) = Values of the coefficients info_out = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, U(i,i) computed in DOUBLE PRECISION is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed. = 0: successful exit information from the subroutine dsgesv in LAPACK
SOURCE
1911 subroutine fit_polynomial_coeff_solve(coefficients,fcart_coeffs,fcart_diff,energy_coeffs,energy_diff,& 1912 & info_out,list_coeffs,natom,ncoeff_fit,ncoeff_max,ntime,& 1913 & strten_coeffs,strten_diff,sqomega,fit_on,fit_factors) 1914 1915 implicit none 1916 1917 !Arguments ------------------------------------ 1918 !scalars 1919 integer,intent(in) :: natom,ncoeff_fit,ncoeff_max,ntime 1920 integer,intent(out) :: info_out 1921 !arrays 1922 real(dp),intent(in) :: energy_coeffs(ncoeff_max,ntime) 1923 real(dp),intent(in) :: energy_diff(ntime) 1924 integer,intent(in) :: list_coeffs(ncoeff_fit) 1925 real(dp),intent(in) :: fcart_coeffs(3,natom,ncoeff_max,ntime) 1926 real(dp),intent(in) :: fcart_diff(3,natom,ntime) 1927 real(dp),intent(in) :: strten_coeffs(6,ntime,ncoeff_max) 1928 real(dp),intent(in) :: strten_diff(6,ntime),sqomega(ntime) 1929 real(dp),intent(out):: coefficients(ncoeff_fit) 1930 real(dp),intent(in) :: fit_factors(3) 1931 logical,intent(in) :: fit_on(3) 1932 !Local variables------------------------------- 1933 !scalar 1934 integer :: ia,itime,icoeff,jcoeff,icoeff_tmp,jcoeff_tmp,mu,LDA,LDB,LDX,LDAF,N,NRHS 1935 real(dp):: efact,ffact,sfact,ftmpA,stmpA,ftmpB,stmpB,etmpA,etmpB,fmu,fnu,smu,snu,emu,enu 1936 integer :: INFO,ITER 1937 real(dp):: RCOND 1938 real(dp):: fcart_coeffs_tmp(3,natom,ntime) 1939 real(dp),allocatable:: AF(:,:),BERR(:),FERR(:),WORK(:),C(:),R(:) 1940 integer,allocatable :: IPIV(:),IWORK(:),SWORK(:) 1941 !arrays 1942 real(dp),allocatable :: A(:,:),B(:,:) 1943 character(len=1) :: FACT,EQUED,TRANS 1944 ! character(len=500) :: message 1945 ! ************************************************************************* 1946 1947 !0-Set variables for the 1948 N = ncoeff_fit; NRHS = 1; LDA = ncoeff_fit; LDB = ncoeff_fit; LDX = ncoeff_fit 1949 LDAF = ncoeff_fit; RCOND = zero; INFO = 0; TRANS='N'; EQUED='N'; FACT='N' 1950 1951 !Set the factors 1952 efact = fit_factors(1)*one/(ntime) 1953 ffact = fit_factors(2)*one/(3*natom*ntime) 1954 sfact = fit_factors(3)*one/(6*ntime) 1955 1956 !0-Allocation 1957 ABI_MALLOC(A,(LDA,N)) 1958 ABI_MALLOC(B,(LDB,NRHS)) 1959 ABI_MALLOC(AF,(LDAF,N)) 1960 ABI_MALLOC(IPIV,(N)) 1961 ABI_MALLOC(R,(N)) 1962 ABI_MALLOC(C,(N)) 1963 ABI_MALLOC(FERR,(NRHS)) 1964 ABI_MALLOC(BERR,(NRHS)) 1965 ABI_MALLOC(WORK,(4*N)) 1966 ABI_MALLOC(IWORK,(N)) 1967 ABI_MALLOC(SWORK,(N*(N+NRHS))) 1968 A=zero; B=zero; 1969 AF = zero; IPIV = 1; 1970 R = one; C = one; 1971 FERR = zero; BERR = zero 1972 IWORK = 0; WORK = 0 1973 1974 !1-Get forces and stresses from the model and fill A 1975 ! Fill alsor B with the forces and stresses from 1976 ! the DFT snapshot and the model 1977 ! See equation 17 of PRB95 094115 (2017) [[cite:Escorihuela-Sayalero2017]] 1978 do icoeff=1,ncoeff_fit 1979 icoeff_tmp = list_coeffs(icoeff) 1980 fcart_coeffs_tmp(:,:,:) = fcart_coeffs(:,:,icoeff_tmp,:) 1981 ftmpA= zero; ftmpB = zero 1982 stmpA= zero; stmpB = zero 1983 etmpA= zero; etmpB = zero 1984 ! loop over the configuration 1985 do itime=1,ntime 1986 ! Fill energy 1987 emu = energy_coeffs(icoeff_tmp,itime) 1988 do jcoeff=1,ncoeff_fit 1989 jcoeff_tmp = list_coeffs(jcoeff) 1990 enu = energy_coeffs(jcoeff_tmp,itime) 1991 if(fit_on(3))then 1992 etmpA = emu*enu/(sqomega(itime)**(1.0/2.0)) 1993 A(icoeff,jcoeff) = A(icoeff,jcoeff) + efact*etmpA 1994 endif 1995 end do 1996 if(fit_on(3))then 1997 etmpB = etmpB + energy_diff(itime)*emu/(sqomega(itime)**(1.0/2.0)) !/ (sqomega(itime)**3) 1998 else 1999 etmpB = zero ! REMOVE THIS LINE TO TAKE INTO ACOUNT THE ENERGY 2000 endif 2001 ! Fill forces 2002 do ia=1,natom 2003 do mu=1,3 2004 fmu = fcart_coeffs_tmp(mu,ia,itime) 2005 do jcoeff=1,ncoeff_fit 2006 jcoeff_tmp = list_coeffs(jcoeff) 2007 fnu = fcart_coeffs(mu,ia,jcoeff_tmp,itime) 2008 ftmpA = fmu*fnu 2009 if(fit_on(1))A(icoeff,jcoeff) = A(icoeff,jcoeff) + ffact*ftmpA 2010 end do 2011 if(fit_on(1))then 2012 ftmpB = ftmpB + fcart_diff(mu,ia,itime)*fmu 2013 else 2014 ftmpB = zero 2015 endif 2016 end do !End loop dir 2017 end do !End loop natom 2018 ! Fill stresses 2019 do mu=1,6 2020 smu = strten_coeffs(mu,itime,icoeff_tmp) 2021 do jcoeff=1,ncoeff_fit 2022 jcoeff_tmp = list_coeffs(jcoeff) 2023 snu = strten_coeffs(mu,itime,jcoeff_tmp) 2024 stmpA = sqomega(itime)*smu*snu 2025 if(fit_on(2))A(icoeff,jcoeff) = A(icoeff,jcoeff) + sfact*stmpA 2026 end do 2027 if(fit_on(2))then 2028 stmpB = stmpB + sqomega(itime)*strten_diff(mu,itime)*smu 2029 else 2030 stmpB = zero 2031 endif 2032 end do !End loop stress dir 2033 end do ! End loop time 2034 B(icoeff,1) = B(icoeff,1) + ffact*ftmpB + sfact*stmpB + efact*etmpB 2035 end do ! End loop icoeff 2036 2037 !2-Solve Ax=B 2038 !OLD VERSION.. 2039 ! call dgesvx(FACT,TRANS,N,NRHS,A,LDA,AF,LDAF,IPIV,EQUED,R,C,B,LDB,coefficients,LDX,& 2040 ! RCOND,FERR,BERR,WORK,IWORK,INFO) 2041 !U is nonsingular 2042 ! if (INFO==N+1) then 2043 ! coefficients = zero 2044 ! end if 2045 call DSGESV(N,NRHS,A,LDA,IPIV,B,LDB,coefficients,LDX,WORK,SWORK,ITER,INFO) 2046 2047 !other routine 2048 ! call dgesv(N,NRHS,A,LDA,IPIV,B,LDB,INFO) 2049 ! coefficients = B(:,NRHS) 2050 !U is nonsingular 2051 if (INFO==N+2) then 2052 coefficients = zero 2053 end if 2054 2055 if(any(abs(coefficients)>1.0E10))then 2056 INFO = 1 2057 coefficients = zero 2058 end if 2059 2060 info_out = INFO 2061 2062 ABI_FREE(AF) 2063 ABI_FREE(IPIV) 2064 ABI_FREE(R) 2065 ABI_FREE(C) 2066 ABI_FREE(FERR) 2067 ABI_FREE(BERR) 2068 ABI_FREE(WORK) 2069 ABI_FREE(IWORK) 2070 ABI_FREE(SWORK) 2071 ABI_FREE(A) 2072 ABI_FREE(B) 2073 2074 end subroutine fit_polynomial_coeff_solve
m_fit_polynomial_coeff/fit_polynomial_printSystemFiles [ Functions ]
[ Top ] [ m_fit_polynomial_coeff ] [ Functions ]
NAME
fit_polynomial_printSystemFiles
FUNCTION
Print the files for the fitting script
INPUTS
eff_pot<type(effective_potential)> = effective potential hist<type(abihist)> = datatype with the history of the MD
OUTPUT
SOURCE
2838 subroutine fit_polynomial_printSystemFiles(eff_pot,hist) 2839 2840 implicit none 2841 2842 !Arguments ------------------------------------ 2843 !scalars 2844 !arrays 2845 type(effective_potential_type), intent(in) :: eff_pot 2846 type(abihist),intent(in) :: hist 2847 !Local variables------------------------------- 2848 !scalar 2849 integer :: ia,ib,ib1,ii,jj,irpt,kk,ll,mu,nu,nstep,nshift 2850 integer :: natom_uc 2851 integer :: unit_born=22,unit_epsiloninf=23,unit_md=24 2852 integer :: unit_harmonic=25,unit_ref=26,unit_strain=27,unit_sym=28 2853 !arrays 2854 integer,allocatable :: typat_order(:),typat_order_uc(:) 2855 integer, dimension(3) :: A,ncell 2856 real(dp), allocatable :: xcart(:,:),fcart(:,:) 2857 character(len=500) :: msg 2858 type(supercell_type) :: supercell 2859 ! ************************************************************************* 2860 2861 !Create new supercell corresponding to the MD 2862 ncell = (/2,2,2/) 2863 call init_supercell(eff_pot%crystal%natom, (/ncell(1),0,0, 0,ncell(2),0, 0,0,ncell(3)/),& 2864 & eff_pot%crystal%rprimd,eff_pot%crystal%typat,& 2865 & eff_pot%crystal%xcart,eff_pot%crystal%znucl, supercell) 2866 2867 !allocation of array 2868 ABI_MALLOC(xcart,(3,supercell%natom)) 2869 ABI_MALLOC(fcart,(3,supercell%natom)) 2870 ABI_MALLOC(typat_order,(supercell%natom)) 2871 ABI_MALLOC(typat_order_uc,(eff_pot%crystal%natom)) 2872 2873 A = (/ 2, 3, 1/) 2874 2875 nshift = product(ncell) 2876 natom_uc = eff_pot%crystal%natom 2877 !Fill the typat_order array: 2878 !In the fit script the atom must be in the order 11111 222222 33333 .. 2879 !and the order of the atom can not be change in the fit script, 2880 !we transform into the format of the script 2881 ib = 1 2882 ib1= 1 2883 do ii=1,eff_pot%crystal%ntypat 2884 jj = A(ii) 2885 do kk=1,natom_uc 2886 if(supercell%typat(kk)==jj)then 2887 typat_order_uc(ib1) = kk 2888 ib1 = ib1 + 1 2889 do ll=1,nshift 2890 ia = (ll-1)*natom_uc + kk 2891 typat_order(ib) = ia 2892 ib = ib + 1 2893 end do 2894 end if 2895 end do 2896 end do 2897 2898 ! BORN CHARGES FILE 2899 if (open_file('system/Born_Charges',msg,unit=unit_born,form="formatted",& 2900 & status="replace",action="write") /= 0) then 2901 ABI_ERROR(msg) 2902 end if 2903 do ii=1,eff_pot%crystal%ntypat 2904 jj = A(ii) 2905 do ia=1,eff_pot%crystal%natom 2906 if(eff_pot%crystal%typat(ia)==jj)then 2907 write(unit_born,'(i2,a,1F10.5)') ia," ",eff_pot%crystal%amu(eff_pot%crystal%typat(ia)) 2908 do mu=1,3 2909 WRITE(unit_born,'(a,3(F23.14))') " ",eff_pot%harmonics_terms%zeff(:,mu,ia) 2910 end do 2911 end if 2912 end do 2913 end do 2914 2915 !DIELECTRIC TENSOR FILE 2916 if (open_file('system/Dielectric_Tensor',msg,unit=unit_epsiloninf,form="formatted",& 2917 & status="replace",action="write") /= 0) then 2918 ABI_ERROR(msg) 2919 end if 2920 do mu=1,3 2921 WRITE(unit_epsiloninf,'(3(F23.14))') eff_pot%harmonics_terms%epsilon_inf(:,mu) 2922 end do 2923 2924 2925 !REFERENCE STRUCTURE FILE 2926 if (open_file('system/Reference_structure',msg,unit=unit_ref,form="formatted",& 2927 & status="replace",action="write") /= 0) then 2928 ABI_ERROR(msg) 2929 end if 2930 2931 write(unit_ref,'("Energy (Hartree)")') 2932 write(unit_ref,'("================")') 2933 write(unit_ref,'(F23.14)') (hist%etot(1)/nshift) 2934 write(unit_ref,'("")') 2935 write(unit_ref,'("Cell vectors")') 2936 write(unit_ref,'("============")') 2937 do jj=1,3 2938 write(unit_ref,'(3(F22.14))') (supercell%rprimd(:,jj)) 2939 end do 2940 2941 write(unit_ref,'("")') 2942 write(unit_ref,'("Atomic positions (Bohr radius)")') 2943 write(unit_ref,'("==============================")') 2944 2945 do ia=1,supercell%natom 2946 write(unit_ref,'(3(F23.14))') supercell%xcart(:,typat_order(ia)) 2947 end do 2948 2949 !Harmonic XML file 2950 if (open_file('system/harmonic.xml',msg,unit=unit_harmonic,form="formatted",& 2951 & status="replace",action="write") /= 0) then 2952 ABI_ERROR(msg) 2953 end if 2954 2955 !Write header 2956 write(unit_harmonic,'("<?xml version=""1.0"" ?>")') 2957 write(unit_harmonic,'("<name>")') 2958 2959 do irpt=1,eff_pot%harmonics_terms%ifcs%nrpt 2960 if(any(abs(eff_pot%harmonics_terms%ifcs%short_atmfrc(:,:,:,:,irpt))>tol9)) then 2961 write(unit_harmonic,'(" <local_force_constant units=""hartree/bohrradius**2"">")') 2962 write(unit_harmonic,'(" <data>")') 2963 do ia=1,eff_pot%crystal%natom 2964 do mu=1,3 2965 do ib=1,eff_pot%crystal%natom 2966 do nu=1,3 2967 write(unit_harmonic,'(F22.14)', advance="no")& 2968 & (eff_pot%harmonics_terms%ifcs%short_atmfrc(mu,typat_order_uc(ia),& 2969 & nu,typat_order_uc(ib),irpt)) 2970 end do 2971 end do 2972 write(unit_harmonic,'(a)')'' 2973 end do 2974 end do 2975 write(unit_harmonic,'(" </data>")') 2976 write(unit_harmonic,'(" <cell>")') 2977 write(unit_harmonic,'(3(I4))') (eff_pot%harmonics_terms%ifcs%cell(:,irpt)) 2978 write(unit_harmonic,'(" </cell>")') 2979 write(unit_harmonic,'(" </local_force_constant>")') 2980 end if 2981 end do 2982 write(unit_harmonic,'("</name>")') 2983 2984 !STRAIN FILE 2985 if (open_file('system/Strain_Tensor',msg,unit=unit_strain,form="formatted",& 2986 & status="replace",action="write") /= 0) then 2987 ABI_ERROR(msg) 2988 end if 2989 write(unit_strain,'(6(F23.14))') (eff_pot%harmonics_terms%elastic_constants) 2990 2991 ! SYM FILE 2992 if (open_file('system/symmetry_operations',msg,unit=unit_sym,form="formatted",& 2993 & status="replace",action="write") /= 0) then 2994 ABI_ERROR(msg) 2995 end if 2996 write(unit_sym,'("(x,y,z) (y,-x,z) (z,x,y) (y,z,x) (x,z,y) (y,x,z) (z,y,x) (x,-y,-z) (z,-x,-y)",& 2997 & " (y,-z,-x) (x,-z,-y) (y,-x,-z) (z,-y,-x) (-x,y,-z) (-z,x,-y) (-y,z,-x) (-x,z,-y)",& 2998 & " (-y,x,-z) (-z,y,-x) (-x,-y,z) (-z,-x,y) (-y,-z,x) (-x,-z,y) (-y,-x,z) (-z,-y,x)",& 2999 & " (-x,-y,-z) (-z,-x,-y) (-y,-z,-x) (-x,-z,-y) (-y,-x,-z) (-z,-y,-x) (-x,y,z)",& 3000 & " (-z,x,y) (-y,z,x) (-x,z,y) (-y,x,z) (-z,y,x) (x,-y,z) (z,-x,y) (y,-z,x) (x,-z,y)",& 3001 & " (z,-y,x) (x,y,-z) (z,x,-y) (y,z,-x) (x,z,-y) (y,x,-z) (z,y,-x)")') 3002 3003 3004 !MD file 3005 nstep = hist%mxhist 3006 if (open_file('system/Molecular_dynamic',msg,unit=unit_md,form="formatted",& 3007 & status="replace",action="write") /= 0) then 3008 ABI_ERROR(msg) 3009 end if 3010 do ii=1,nstep 3011 write(unit_md,'(I5)') ii-1 3012 write(unit_md,'(F22.14)') hist%etot(ii)/nshift 3013 do jj=1,3 3014 write(unit_md,'(3(F22.14))') (hist%rprimd(:,jj,ii)) 3015 end do 3016 ! Set xcart and fcart for this step 3017 call xred2xcart(supercell%natom,hist%rprimd(:,:,ii),& 3018 & xcart,hist%xred(:,:,ii)) 3019 3020 fcart(:,:) = hist%fcart(:,:,ii) 3021 3022 do ia=1,supercell%natom 3023 write(unit_md,'(3(E22.14),3(E22.14))') xcart(:,typat_order(ia)),fcart(:,typat_order(ia)) 3024 end do 3025 write(unit_md,'(6(E22.14))') hist%strten(:,ii) 3026 end do 3027 3028 !Close files 3029 close(unit_ref) 3030 close(unit_born) 3031 close(unit_harmonic) 3032 close(unit_epsiloninf) 3033 close(unit_md) 3034 close(unit_strain) 3035 close(unit_sym) 3036 3037 !Deallocation array 3038 ABI_FREE(typat_order) 3039 ABI_FREE(typat_order_uc) 3040 ABI_FREE(xcart) 3041 ABI_FREE(fcart) 3042 call destroy_supercell(supercell) 3043 3044 end subroutine fit_polynomial_printSystemFiles
m_fit_polynomiaL_coeff/testEffPot [ Functions ]
NAME
testEffPot
FUNCTION
Calculate the energy, forces for displacements provided in an test-set (input:hist) within a given effective potential (input: eff_pot) If the test set is from DFT and contains DFT energies and forces calculate the Goal Function values and the MSD of the Energy with respect to the DFT energies
INPUTS
eff_pot = effective_potential datatype hist = abihist datatype
OUTPUT
SOURCE
2715 subroutine fit_polynomial_coeff_testEffPot(eff_pot,hist,master,comm,print_anharmonic,scup_dtset,prt_ph) 2716 2717 2718 implicit none 2719 2720 !Arguments ------------------------------------ 2721 !scalars 2722 integer,intent(in) :: master,comm 2723 integer,optional,intent(in) :: prt_ph 2724 !logicals 2725 logical,optional,intent(in) :: print_anharmonic 2726 !array 2727 type(effective_potential_type),intent(inout) :: eff_pot 2728 type(abihist),intent(in) :: hist 2729 type(scup_dtset_type),optional,intent(inout) :: scup_dtset 2730 !Local variables------------------------------- 2731 !reals 2732 real(dp) :: factor,mse,msef,mses 2733 real(dp),allocatable :: sqomega(:),ucvol(:) 2734 real(dp),parameter :: HaBohr_eVAng = 27.21138386d0 / 0.529177249d0 2735 !scalar 2736 integer :: itime,unit_anh 2737 integer :: natom,ntime,ncoeff,my_rank 2738 !logicals 2739 logical :: iam_master, need_print_anharmonic,file_opened,need_prt_ph 2740 !strings/characters 2741 character(len=fnlen) :: filename 2742 character(len=1000) :: message 2743 !arrays 2744 real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3) 2745 ! ************************************************************************* 2746 2747 !MPI variables 2748 my_rank=xmpi_comm_rank(comm) 2749 iam_master = (my_rank == master) 2750 2751 !Initialisation of optional arguments 2752 need_print_anharmonic = .FALSE. 2753 if(present(print_anharmonic)) need_print_anharmonic = print_anharmonic 2754 2755 need_prt_ph = .FALSE. 2756 if(present(prt_ph))then 2757 if(prt_ph==1) need_prt_ph=.TRUE. 2758 endif 2759 2760 !Setting/Allocating other Variables 2761 natom = size(hist%xred,2) 2762 factor = 1._dp/natom 2763 ntime = hist%mxhist 2764 ABI_MALLOC(sqomega,(ntime)) 2765 ABI_MALLOC(ucvol,(ntime)) 2766 sqomega = zero 2767 filename = 'TES_fit_diff' 2768 ncoeff = eff_pot%anharmonics_terms%ncoeff 2769 2770 do itime=1,ntime 2771 ! Compute \Omega^{2} and ucvol for each time 2772 call metric(gmet,gprimd,-1,rmet,hist%rprimd(:,:,itime),ucvol(itime)) 2773 ! Formula: sqomega(itime) = (((ucvol(itime)**(-2.))* ((natom)**(0.5)))**(-1.0/3.0))**2 2774 ! Compact form: 2775 sqomega(itime) = ((ucvol(itime)**(4.0/3.0)) / ((natom)**(1/3.0))) 2776 end do 2777 2778 2779 if(need_print_anharmonic) call effective_potential_writeAnhHead(ncoeff,& 2780 & filename,eff_pot%anharmonics_terms) 2781 2782 call fit_polynomial_coeff_computeMSD(eff_pot,hist,mse,msef,mses,natom,ntime,& 2783 & sqomega,comm,& 2784 & compute_anharmonic=.TRUE.,print_file=.TRUE.,filename=filename,scup_dtset=scup_dtset,prt_ph=need_prt_ph) 2785 2786 2787 ! Print the standard deviation after the fit 2788 write(message,'(6a,ES24.16,2a,ES24.16,2a,ES24.16,2a,ES24.16,a)' )ch10,& 2789 !& ' Mean Standard Deviation values of the effective-potential',ch10,& 2790 !& ' with respect to the test-set (meV^2/atm):',& 2791 !& ch10,' Energy : ',& 2792 !& mse* (Ha_EV*1000)**2 *factor ,ch10,& 2793 & ' Goal function values of the effective.potential',ch10,& 2794 & ' with respect to the test-set (eV^2/A^2):',ch10,& 2795 & ' Energy : ',& 2796 & (mse)*(HaBohr_eVAng)**2,ch10,& 2797 & ' Forces+Stresses : ',& 2798 & (msef+mses)*(HaBohr_eVAng)**2,ch10,& 2799 & ' Forces : ',& 2800 & msef*(HaBohr_eVAng)**2,ch10,& 2801 & ' Stresses : ',& 2802 & mses*(HaBohr_eVAng)**2,ch10 2803 call wrtout(ab_out,message,'COLL') 2804 call wrtout(std_out,message,'COLL') 2805 2806 2807 !Deallocating 2808 ABI_FREE(sqomega) 2809 ABI_FREE(ucvol) 2810 2811 INQUIRE(FILE='TES_fit_diff_anharmonic_terms_energy.dat',OPENED=file_opened,number=unit_anh) 2812 if(file_opened) close(unit_anh) 2813 2814 2815 end subroutine fit_polynomial_coeff_testEffPot