! This module contains a routine to compute the EWs of the lines from their ! polynomial GCOG, and a function for the voigt profile. ! ! It is part of the program SP_Ace, which derives stellar parameters, ! such as gravity, temperature, and element abundances from optical ! stellar spectra, assuming Local Thermodynamic Equilibrium (LTE) ! and 1D stellar atmosphere models. ! ! Copyright (C) 2016 Corrado Boeche ! ! This program is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation, either version 3 of the License, or ! (at your option) any later version. ! ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with this program. If not, see . MODULE func_poly USE num_type CONTAINS !####################################### REAL(DP) FUNCTION ew_poly4(pars,coeff) IMPLICIT NONE REAL(DP), DIMENSION(4), INTENT(IN) :: pars REAL(DP), DIMENSION(70), INTENT(IN) :: coeff INTEGER(I1B), PARAMETER :: grado=4 INTEGER(I1B) :: i1,i2,i3,i4 INTEGER(I1B) :: count REAL(DP) :: a,b,c !initialize variables ew_poly4=0.0_dp count=0 DO i1=0,grado a=(pars(1)**i1) DO i2=0,grado-i1 b=a*(pars(2)**i2) DO i3=0,grado-i2-i1 c=b*(pars(3)**i3) DO i4=0,grado-i3-i2-i1 count=count+1_I1B ew_poly4=ew_poly4+coeff(count)*c*(pars(4)**i4) END DO END DO END DO END DO IF(ew_poly4<1e-6) ew_poly4=1e-6_dp END FUNCTION ew_poly4 !####################################### ! REAL(DP) FUNCTION ew_lin_interp_a(pars,coeff) ! USE data_lib, ONLY: temp_gridL,logg_gridL,met_gridL,aFe_gridL ! USE read_GCOG, ONLY: load_GCOG_lin ! IMPLICIT NONE ! REAL(DP), DIMENSION(4), INTENT(IN) :: pars ! REAL(DP), DIMENSION(48), INTENT(IN) :: coeff !! INTEGER(I1B) :: i1,i2,i3,i4 ! INTEGER(I1B) :: i,j,k,l,count,place ! INTEGER(I1B) :: loc_a ! REAL(DP) :: t_prox0,l_prox0,m_prox0,a_prox0 ! REAL(DP), SAVE :: t_prox_old,l_prox_old,m_prox_old ! REAL(DP) :: t_step,l_step,m_step,a_step,xt,xl,xm,xa,a,b,c,d ! LOGICAL :: flag_tm,flag_lm,flag_mm,flag_am,flag_tp,flag_lp,flag_mp,flag_ap !! REAL(DP) :: nt_steps,nl_steps,nm_steps,na_steps ! ! t_prox0=par_prox(temp_gridL,pars(1),flag_tm,flag_tp) ! l_prox0=par_prox(logg_gridL,pars(2),flag_lm,flag_lp) ! m_prox0=par_prox(met_gridL,pars(3),flag_mm,flag_mp) ! a_prox0=par_prox(aFe_gridL,pars(4),flag_am,flag_ap) ! t_step=200_dp ! l_step=0.4_dp ! m_step=0.2_dp ! a_step=0.2_dp ! loc_a=INT(MINLOC(ABS(aFe_gridL-a_prox0),1),I1B) ! !! write(*,*) 'flags',pars,flag_tm,flag_tp,flag_lm,flag_lp,flag_mm,flag_mp,flag_am,flag_ap !! write(*,*) 'prox0',t_prox0,l_prox0,m_prox0,a_prox0,loc_a ! ! IF(t_prox0/=t_prox_old.OR.l_prox0/=l_prox_old.OR.& ! & m_prox0/=m_prox_old) THEN ! CALL load_GCOG_lin(t_prox0,l_prox0,m_prox0) ! t_prox_old=t_prox0 ! l_prox_old=l_prox0 ! m_prox_old=m_prox0 ! END IF ! ! ! xt=(pars(1)-t_prox0)/t_step ! xl=(pars(2)-l_prox0)/l_step ! xm=(pars(3)-m_prox0)/m_step ! xa=(pars(4)-a_prox0)/a_step ! !!#### if pars0.001) THEN !! write(*,*) 'pars',pars,t_prox0,l_prox0,m_prox0,a_prox0 !! write(*,*) 'coeff',coeff !! write(*,*) 'ew_interp',ew_lin_interp !! END IF ! ! ew_lin_interp_a=ew_lin_interp_a/1000._dp ! ! END FUNCTION ew_lin_interp_a !####################################### REAL(DP) FUNCTION ew_lin_interp(pars,coeff) USE data_lib, ONLY: temp_gridL,logg_gridL,met_gridL,aFe_gridL USE read_GCOG, ONLY: load_GCOG_lin USE utils, ONLY : find_prox_L IMPLICIT NONE REAL(DP), DIMENSION(4), INTENT(IN) :: pars REAL(DP), DIMENSION(48), INTENT(IN) :: coeff ! INTEGER(I1B) :: i1,i2,i3,i4 INTEGER(I1B) :: i,j,k,l,count,place INTEGER(I1B) :: loc_a REAL(DP),DIMENSION(4) :: tgm_prox REAL(DP), DIMENSION(3), SAVE :: tgm_prox_old REAL(DP) :: t_step,l_step,m_step,a_step,xt,xl,xm,xa,a,b,c,d LOGICAL :: flag_tm,flag_lm,flag_mm,flag_am,flag_tp,flag_lp,flag_mp,flag_ap REAL(DP) :: nt_steps,nl_steps,nm_steps,na_steps,ew_to_add REAL(DP) :: diff_t,diff_l,diff_m,diff_a CALL find_prox_L(pars,tgm_prox,flag_tm,flag_tp,flag_lm,flag_lp,flag_mm,flag_mp,flag_am,flag_ap) t_step=temp_gridL(2)-temp_gridL(1) l_step=logg_gridL(2)-logg_gridL(1) m_step=met_gridL(2)-met_gridL(1) a_step=aFe_gridL(2)-aFe_gridL(1) loc_a=INT(MINLOC(ABS(aFe_gridL-tgm_prox(4)),1),I1B) ! write(*,*) 'flags',pars,flag_tm,flag_tp,flag_lm,flag_lp,flag_mm,flag_mp,flag_am,flag_ap IF(ANY(tgm_prox(1:3)/=tgm_prox_old)) THEN CALL load_GCOG_lin(tgm_prox(1),tgm_prox(2),tgm_prox(3)) tgm_prox_old=tgm_prox(1:3) END IF IF(flag_tp.AND..NOT.flag_tm) THEN xt=1._dp ELSE IF (flag_tm.AND..NOT.flag_tp) THEN xt=0._dp ELSE IF(.NOT.flag_tm.AND..NOT.flag_tp) THEN xt=(pars(1)-tgm_prox(1))/t_step END IF IF(flag_lp.AND..NOT.flag_lm) THEN xl=1._dp ELSE IF(flag_lm.AND..NOT.flag_lp) THEN xl=0._dp ELSE IF(.NOT.flag_lm.AND..NOT.flag_lp) THEN xl=(pars(2)-tgm_prox(2))/l_step END IF IF(flag_mp.AND..NOT.flag_mm) THEN xm=1._dp ELSE IF(flag_mm.AND..NOT.flag_mp) THEN xm=0._dp ELSE IF(.NOT.flag_mm.AND..NOT.flag_mp) THEN xm=(pars(3)-tgm_prox(3))/m_step END IF IF(flag_ap.AND..NOT.flag_am) THEN xa=1._dp ! write(*,*) 'flag_ap',pars(4),t_prox0,l_prox0,m_prox0,a_prox0,xa ELSE IF(flag_am.AND..NOT.flag_ap) THEN xa=0._dp ! write(*,*) 'flag_am',pars(4),t_prox0,l_prox0,m_prox0,a_prox0,xa ELSE IF(.NOT.flag_am.AND..NOT.flag_ap) THEN xa=(pars(4)-tgm_prox(4))/a_step END IF ! write(*,*) 'x',xt,xl,xm,xa !#### if pars=0) THEN ! par_prox=array(loc) ! IF(par>array(SIZE(array))) flagp=.TRUE. ! ELSE ! IF(par>array(2)) THEN ! par_prox=array(loc-1_I1B) ! ELSE IF(par=array(1)) THEN ! par_prox=array(1) ! ELSE ! par_prox=array(1) ! flagm=.TRUE. ! END IF ! END IF ! ! END FUNCTION par_prox !##################### REAL(DP) FUNCTION ew_poly4_quick(pars,coeff) IMPLICIT NONE REAL(DP), DIMENSION(3), INTENT(IN) :: pars REAL(DP), DIMENSION(84), INTENT(IN) :: coeff INTEGER(I1B), PARAMETER :: grado=6 INTEGER(I1B) :: i1,i2,i3 INTEGER(I1B) :: count REAL(DP) :: a,b !initialize variables ew_poly4_quick=0.0_dp count=0 DO i1=0,grado a=(pars(1)**i1) DO i2=0,grado-i1 b=a*(pars(2)**i2) DO i3=0,grado-i2-i1 count=count+1_I1B ew_poly4_quick=ew_poly4_quick+coeff(count)*b*(pars(3)**i3) END DO END DO END DO IF(ew_poly4_quick<1e-6) ew_poly4_quick=1e-6_dp END FUNCTION ew_poly4_quick !##################### REAL(DP) FUNCTION voigt_logg(w,mu,gamG,ew,gamL) USE num_type IMPLICIT NONE REAL(DP),INTENT(IN) :: w,mu,gamG,ew,gamL REAL(DP),PARAMETER :: sqrtln2=0.832554611_dp,sqrtpi=1.772453851_dp REAL(DP), DIMENSION(4), PARAMETER :: A=(/-1.2150,-1.3509,-1.2150,-1.3509/) REAL(DP), DIMENSION(4), PARAMETER :: B=(/1.2359,0.3786,-1.2359,-0.3786/) REAL(DP), DIMENSION(4), PARAMETER :: C=(/-0.3085,0.5906,-0.3085,0.5906/) REAL(DP), DIMENSION(4), PARAMETER :: D=(/0.0210,-1.1858,-0.0210,1.1858/) REAL(DP), DIMENSION(4) :: V REAL(DP) :: sigmaL,aL,X,Y REAL(DP), PARAMETER :: pi=3.14159265358979_dp sigmaL=(gamL*0.5_dp)/sqrtpi aL=ew/(sigmaL*pi*sqrtpi) X=(w-mu)*2.0_dp*sqrtln2/gamG Y=gamL*sqrtln2/gamG V=(C*(Y-A)+D*(X-B))/((Y-A)**2+(X-B)**2) voigt_logg=SUM(V)*(gamL*aL*sqrtpi*sqrtln2/gamG) voigt_logg=MAX(voigt_logg,1e-6_dp) END FUNCTION voigt_logg !##################### END MODULE func_poly