LCOV - code coverage report
Current view: top level - mix - distance.F90 (source / functions) Hit Total Coverage
Test: combined.info Lines: 34 35 97.1 %
Date: 2019-09-08 04:53:50 Functions: 1 2 50.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : module m_distance
       7             : contains
       8         644 :   SUBROUTINE distance(irank,vol,jspins,fsm,inden,outden,results,fsm_mag)
       9             :     use m_types
      10             :     use m_types_mixvector
      11             :     use m_xmlOutput
      12             :  
      13             :     implicit none
      14             :     integer,intent(in)             :: irank,jspins
      15             :     real,intent(in)                :: vol
      16             :     type(t_mixvector),INTENT(IN)   :: fsm
      17             :     TYPE(t_potden),INTENT(INOUT)   :: inden,outden
      18             :     TYPE(t_results),INTENT(INOUT)  :: results
      19             :     type(t_mixvector),INTENT(OUT)  :: fsm_mag
      20             :     
      21             :     integer         ::js
      22             :     REAL            :: dist(6) !1:up,2:down,3:spinoff,4:total,5:magnet,6:noco
      23         322 :     TYPE(t_mixvector)::fmMet
      24             :     character(len=100)::attributes(2)
      25             :     
      26         322 :     CALL fmMet%alloc()
      27         322 :     IF (jspins==2) THEN
      28         266 :        CALL fsm_mag%alloc()
      29             :        ! calculate Magnetisation-difference
      30         266 :        CALL fsm_mag%from_density(outden,swapspin=.TRUE.)
      31         266 :        call fmMet%from_density(inden,swapspin=.true.)
      32         266 :        fsm_mag=fsm_mag-fmMet
      33             :     ENDIF
      34             :     ! Apply metric w to fsm and store in fmMet:  w |fsm>
      35         322 :     fmMet=fsm%apply_metric()
      36             :   
      37         322 :     dist(:) = 0.0
      38         910 :     DO js = 1,jspins
      39         910 :        dist(js) = fsm%multiply_dot_mask(fmMet,(/.true.,.true.,.true.,.false./),js)
      40             :     END DO
      41         322 :     IF (SIZE(outden%pw,2)>2) dist(6) = fsm%multiply_dot_mask(fmMet,(/.TRUE.,.TRUE.,.TRUE.,.FALSE./),3)
      42         322 :     IF (jspins.EQ.2) THEN
      43         266 :        dist(3) = fmMet%multiply_dot_mask(fsm_mag,(/.true.,.true.,.true.,.false./),1)
      44         266 :        dist(4) = dist(1) + dist(2) + 2.0e0*dist(3)
      45         266 :        dist(5) = dist(1) + dist(2) - 2.0e0*dist(3)
      46             :     ENDIF
      47             :     
      48         322 :     results%last_distance=maxval(1000*SQRT(ABS(dist/vol)))
      49        1127 :     if (irank>0) return
      50             :     !calculate the distance of charge densities for each spin
      51         161 :     CALL openXMLElement('densityConvergence',(/'units'/),(/'me/bohr^3'/))
      52             :     
      53         455 :     DO js = 1,jspins         
      54         882 :        attributes = ''
      55         294 :        WRITE(attributes(1),'(i0)') js
      56         294 :        WRITE(attributes(2),'(f20.10)') 1000*SQRT(ABS(dist(js)/vol))
      57         294 :        CALL writeXMLElementForm('chargeDensity',(/'spin    ','distance'/),attributes,reshape((/4,8,1,20/),(/2,2/)))
      58         455 :        WRITE ( 6,FMT=7900) js,inDen%iter,1000*SQRT(ABS(dist(js)/vol))
      59             :     END DO
      60             :     
      61         161 :     IF (SIZE(outden%pw,2)>2) WRITE (6,FMT=7900) 3,inDen%iter,1000*SQRT(ABS(dist(6)/vol))
      62             :     
      63             :     !calculate the distance of total charge and spin density
      64             :     !|rho/m(o) - rho/m(i)| = |rh1(o) -rh1(i)|+ |rh2(o) -rh2(i)| +/_
      65             :     !                        +/_2<rh2(o) -rh2(i)|rh1(o) -rh1(i)>
      66         161 :     IF (jspins.EQ.2) THEN
      67             :        CALL writeXMLElementFormPoly('overallChargeDensity',(/'distance'/),&
      68         133 :             (/1000*SQRT(ABS(dist(4)/vol))/),reshape((/10,20/),(/1,2/)))
      69             :        CALL writeXMLElementFormPoly('spinDensity',(/'distance'/),&
      70         133 :             (/1000*SQRT(ABS(dist(5)/vol))/),reshape((/19,20/),(/1,2/)))
      71         133 :        WRITE ( 6,FMT=8000) inDen%iter,1000*SQRT(ABS(dist(4)/vol))
      72         133 :        WRITE ( 6,FMT=8010) inDen%iter,1000*SQRT(ABS(dist(5)/vol))
      73             :        
      74             :        !dist/vol should always be >= 0 ,
      75             :        !but for dist=0 numerically you might obtain dist/vol < 0
      76             :        !(e.g. when calculating non-magnetic systems with jspins=2).
      77             :     END IF
      78         161 :     CALL closeXMLElement('densityConvergence')
      79             : 
      80             : 
      81             : 7900  FORMAT (/,'---->    distance of charge densities for spin ',i2,'                 it=',i5,':',f13.6,' me/bohr**3')
      82             : 8000 FORMAT (/,'---->    distance of charge densities for it=',i5,':', f13.6,' me/bohr**3')
      83             : 8010 FORMAT (/,'---->    distance of spin densities for it=',i5,':', f13.6,' me/bohr**3')
      84             : 8020 FORMAT (4d25.14)
      85             : 8030  FORMAT (10i10)
      86        1288 :   end SUBROUTINE distance
      87           0 : end module m_distance

Generated by: LCOV version 1.13