module write_mod implicit none ! unit conversion double precision ,parameter :: h2icm = 219474.69d0 double precision, parameter :: au2Debye = 2.541746d0 character(len=250), parameter :: sep_line = '(250("-"))' character(len=250), parameter :: block_line = '(250("="))' contains ! (q,x1,x2,y,wt,par,p_act,p_spread,nset,npar, > flag,lauf) use adia_mod, only: adia use dim_parameter,only: qn,ntot,numdatpt,ndiab use ctrans_mod,only: ctrans implicit none ! IN: variables integer lauf integer flag !< 0= initial output 1=fit not converged 2= Fit Converged, 3= max iteration reached integer npar,nset double precision par(npar,nset),p_spread(npar) integer p_act(npar) double precision q(qn,numdatpt),x1(qn,numdatpt),x2(qn,numdatpt) double precision y(ntot,numdatpt),wt(ntot,numdatpt) ! INTERNAL: Variables integer,parameter :: id_out = 20 , std_out = 6 integer pt integer i, id_print double precision, allocatable :: ymod(:,:) double precision, allocatable :: ew(:,:) double precision, allocatable :: ev(:,:,:) logical skip allocate(ymod(ntot,numdatpt)) allocate(ew(ndiab,numdatpt)) allocate(ev(ndiab,ndiab,numdatpt)) skip=.false. ! get Model Outputs for all geometries for current best parameter set par(:,1) do pt=1,numdatpt call adia(pt,par(1:npar,1),npar,ymod(1:ntot,pt), > ew(1:ndiab,pt),ev(1:ndiab,1:ndiab,pt),skip) call ctrans(q(:,pt),x1(:,pt),x2(:,pt)) enddo ! Initial write print everything you want to see before the fit and return if(flag.eq.0) then call print_parameterstate(std_out,par(:,1),p_act,npar) call print_ErrorSummary(std_out,y,ymod,wt) ! print Data into the plotfiles return endif ! open output files for individual makro iterations call open_outfile(id_out,lauf) ! print Data into the plotfiles call print_plotfiles(x1,y,wt,ymod) ! print Genetic output into files do i=1, 2 if (i.eq.1) then id_print= std_out else id_print= id_out endif write(id_print,'("Writing Iteration: ",i4)') lauf write(id_print,block_line) ! write data information only in outfile if(i.eq.2) then call print_data(id_print,x1,y,ymod,wt) call print_Set_Errors(id_print,y,ymod,wt) endif call print_parameterblock > (id_print,par(:,1),p_act,p_spread,npar) call print_ErrorSummary(id_print,y,ymod,wt) enddo call print_fortranfile(par(:,1),npar) ! write the type of calc at the end of the output close (id_out) deallocate(ymod,ev,ew) end subroutine !---------------------------------------------------------------------------------------------------- ! subroutine print_Set_Errors(id_out,y, ymod, wt) use io_parameters,only: llen use dim_parameter,only: ndata,nstat,ntot,numdatpt,sets integer , intent(in) :: id_out double precision, intent(in) :: y(ntot,numdatpt), > ymod(ntot,numdatpt), wt(ntot,numdatpt) integer :: set, setpoint, pt double precision :: Set_rms(sets,ntot), Set_num(sets,ntot) double precision :: Total_rms, Total_Energy_rms,Energy_rms(nstat) character(len=llen) fmt write(id_out,'(A)') 'Errors in icm for individual Sets' // > '(specified by sets: and npoints:)' write(id_out,'(A5,3A16)')'Set','Total', > 'Total_Energy', 'Energy[nstat]' write(id_out,sep_line) write(fmt,'("(I5,2f16.1,",I2,"f16.1)")') nstat Set_rms = 0.d0 pt = 0 do set=1, sets do setpoint=1, ndata(set) pt = pt + 1 where(wt(:,pt) > 0.d0) Set_rms(set,:) = Set_rms(set,:)+(ymod(:,pt)-y(:,pt))**2 Set_num(set,:) = Set_num(set,:) + 1 end where enddo Total_rms > = dsqrt(sum(Set_rms(set,:)) > / (sum(Set_num(set,:)))) Total_Energy_rms > = dsqrt(sum(Set_rms(set,1:nstat)) > / (sum(Set_num(set,1:nstat)))) Energy_rms(1:nstat) > = dsqrt(Set_rms(set,1:nstat) > / (Set_num(set,1:nstat))) write(id_out,fmt) set, Total_rms*h2icm, Total_Energy_rms*h2icm, > Energy_rms(1:nstat)*h2icm enddo write(id_out,block_line) write(id_out,*) '' end subroutine print_Set_Errors !---------------------------------------------------------------------------------------------------- ! ' Debye)') 42 format('#',10x,'No. of Points: ',i10) 43 format('#',10x,'Total weighted RMS: ',g16.8, '(',f8.1,' icm)') 44 format('#',10x,'Sum of point weights: ',f16.8) 45 format('#',10x,'Total Energie RMS: ',g16.8, '(',f8.1,' icm)') 48 format('#',10x,'Red. Energie RMS: ',g16.8,'(',f8.1,' icm)') 51 format('#') end subroutine !---------------------------------------------------------------------------------------------------- subroutine print_plotfiles(x,y,wt,ymod) use dim_parameter,only: ndata,sets,qn,ntot,numdatpt,plot_coord implicit none ! IN: variables double precision x(qn,numdatpt),y(ntot,numdatpt) double precision wt(ntot,numdatpt), ymod(ntot,numdatpt) ! INTERNAL: variables integer sstart,ssend,set,id_plot ! Initialize position pointer ssend=0 ! loop over datasets and print the plotfiles do set=1 ,sets if(ndata(set).eq.0) cycle id_plot=50+set call open_plotfile(id_plot,set) write(id_plot,'(A)') '# -*- truncate-lines: t -*-' ! get start and end point of each set sstart=ssend+1 ssend=ssend+ndata(set) if (plot_coord(set).eq.0) then call print_plotwalk(x(:,sstart:ssend),y(:,sstart:ssend), > wt(:,sstart:ssend),ymod(:,sstart:ssend), > ndata(set),id_plot,set) else call print_plotcoord(plot_coord(set), > x(:,sstart:ssend),y(:,sstart:ssend), > wt(:,sstart:ssend),ymod(:,sstart:ssend), > ndata(set),id_plot,set) endif close(id_plot) enddo end subroutine !---------------------------------------------------------------------------------------------------- subroutine print_plotwalk(x,y,wt,ymod,npt,id_plot,set) use dim_parameter,only: qn,ntot use io_parameters,only: llen implicit none ! IN: variables integer id_plot,npt,set double precision x(qn,npt),y(ntot,npt),ymod(ntot,npt),wt(ntot,npt) ! INTERNAL: variables double precision xdiff(qn),walktime double precision walknorm ! loop control integer i,j character(len=llen) fmt j=ntot-1 call print_plotheader(id_plot,0,npt,set) call getwalknorm(x,walknorm,npt) walktime = 0.d0 do i=1,npt if(i.gt.1) then xdiff(1:qn) = x(1:qn,i) - x(1:qn,i-1) walktime = walktime + dsqrt(sum(xdiff(1:qn)**2))/walknorm endif write(id_plot,"(ES16.8,*(3(ES16.8),:))") > walktime ,ymod(:,i),y(:,i),(wt(:,i)) enddo end subroutine !---------------------------------------------------------------------------------------------------- subroutine print_plotcoord(coord,x,y,wt,ymod,npt,id_plot,set) use dim_parameter,only: qn,ntot use io_parameters,only: llen implicit none ! IN: variables integer, intent(in) :: id_plot,npt,set,coord double precision, intent(in) :: x(qn,npt),y(ntot,npt) double precision, intent(in) :: ymod(ntot,npt),wt(ntot,npt) ! loop control integer i call print_plotheader(id_plot,coord,npt,set) do i=1,npt ! write(id_plot,"(ES16.8,*(3(ES16.8),:))") ! > x(coord,i), ymod(:,i),y(:,i),(wt(:,i)) write(id_plot,"(2ES16.8,*(3(ES16.8),:))") > x(coord,i), x(coord+1,i),y(:,i) enddo end subroutine !---------------------------------------------------------------------------------------------------- subroutine print_plotheader(id_plot,coord,npt,set) use dim_parameter,only: qn,ntot use io_parameters,only: llen implicit none integer, intent(in) :: id_plot,npt,set,coord character(len=llen) fmt write(id_plot,'("#SET: ",i5)') set write(id_plot,'("#OUTPUT VALUES",i4)') ntot write(id_plot,'("#DATA POINTS: ",i4)') npt if (coord.le.0) then write(id_plot,'("#t(x) = WALK")') else write(id_plot,'("#t(x) = x(",I0,")")') coord endif write(id_plot,'("#UNIT: hartree")') write(id_plot,'()') write(id_plot,'("#",A15)',advance='no') "t(x)" write(fmt,'("(3(7X,A9,",I3,"(16x)))")') ntot-1 write(id_plot,fmt) 'ymod(p,x)','y(x) ','wt(x) ' end subroutine !---------------------------------------------------------------------------------------------------- ! 'ERROR: No rule for Outputfile naming for MAXIT >= 1000' stop endif open (id_out,file=outname) end subroutine !---------------------------------------------------------------------------------------------------- ! =2 ! <@param id_out specifies the file in which the Parameters are Printed ! <@param p vector containing one set of parameter values ! <@param p_act vector containing the active state 0 (inactive) or 1 (active) for each parameter ! <@param p_spread vector containing the spreads for each parameter ! <@param npar lenght of the parmeter vectors (p,p_act,p_spread) ! <@TODO extract subroutine for printing the multiline values, would make this more readable subroutine print_parameterblock(id_out,p,p_act,p_spread,npar) use dim_parameter,only: pst, facspread use io_parameters,only: key, parkeynum,parkeylen,llen implicit none ! IN: Variables integer id_out,npar,p_act(npar) double precision p(npar),p_spread(npar) ! INTERNAL: variables ! loop index integer i,k,l,t,n !< internal variables for loops and positions in parameter vectors ! number of values per line, values must be atleast 2 set this to personal preference integer, parameter :: np=5,nsp=5 character(len=llen) fmt ! Write header for Parameter block 1 format('!',200('=')) write(id_out,1) write(id_out,'(A2,5x,A11,i3)') '! ','PARAMETER: ',npar write(id_out,1) ! loop over all Parameter Keys do i = 1, parkeynum ! save start and end of parameter block for specific key k = pst(1,i) l = pst(1,i)+pst(2,i)-1 ! print only used keys with atleast one parameter if(pst(2,i).gt.0) then write(fmt,'("(a",I3,"'' ''i3)")') parkeylen write(id_out,fmt) adjustl(key(1,i)), pst(2,i) ! write the actual parameters -> subroutine print_parameterlines()? if(l-k.le.(np-1)) then write(fmt,'("(a",I3,"'' ''",I3,"g24.15)")') parkeylen,np write(id_out,fmt) key(2,i),(p(n), n=k,l) else ! start of multi line parameter print, number of values per line specified by np write(fmt,'("(a",I3,"'' ''",I3,"g24.15'' &'')")') $ parkeylen,np write(id_out,fmt) key(2,i),(p(n), n=k,k+(np-1)) t=k+np ! write continuation lines till left parameters fit on last line do while(t.le.l) if(l-t.le.(np-1)) then write(fmt,'("(",I3,"x'' ''",I3,"g24.15)")') $ parkeylen,np write(id_out,fmt) (p(n), n=t, l) else write(fmt,'("(",I3,"x'' ''",I3,"g24.15'' &'')")') $ parkeylen,np write(id_out,fmt) (p(n), n=t, t+(np-1)) endif t=t+np enddo endif !-> end subroutine print_parameterlines ! write parameter active state in one line write(fmt,'("(a",I3,"'' ''","50i3)")') parkeylen write(id_out,fmt) key(3,i),(p_act(n),n=k,l) ! write the spreads for each parameter if(l-k.le.(np-1)) then write(fmt,'("(a",I3,"'' ''",I3,"g24.8)")') parkeylen,nsp write(id_out,fmt) key(4,i),(p_spread(n)/facspread, n=k,l) else ! start of multiline spread values write(fmt,'("(a",I3,"'' ''",I3,"g24.8'' &'')")') $ parkeylen,nsp write(id_out,fmt) key(4,i),(p_spread(n)/facspread, n=k,k > +(np-1)) t=k+nsp ! write continuation lines till left spreads fit on last line do while(t.le.l) if(l-t.le.(np-1)) then write(fmt,'("(",I3,"x'' ''",I3,"g24.8)")') $ parkeylen,nsp write(id_out,fmt) (p_spread(n)/facspread, n=t, l) else write(fmt,'("(",I3,"x'' ''",I3,"g24.8'' &'')")') $ parkeylen,nsp write(id_out,fmt) (p_spread(n)/facspread, n=t, t > +(np-1)) endif t=t+np enddo endif ! print empty line between diffrent parameter blocks for better readability write(id_out,'(" ")') endif enddo end subroutine !---------------------------------------------------------------------------------------------------- ! adjustl('y(x)-ymod(x)'),adjustl('weight'), > adjustl('x(1:qn_read) ') write(id_out,sep_line) ! loop over all datapoints for each set and count the actual datapointnumber with point point=0 do i=1,sets write(id_out,18) 'Set: ', i do j=1,ndata(i) write(id_out,18) 'Point: ', j point=point+1 ! print all data for one datapoint call print_datapoint(id_out,x(:,point),y(:,point), > ymod(:,point),wt(:,point)) write(id_out,sep_line) enddo enddo ! write end of data statement and two seperating lines write(id_out,block_line) write(id_out,*) '' end subroutine !---------------------------------------------------------------------------------------------------- ! wt(k), x(1:qn_read) enddo enddo end subroutine end module write_mod