LCOV - code coverage report
Current view: top level - global - chkmt.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 180 268 67.2 %
Date: 2024-04-26 04:44:34 Functions: 1 1 100.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             : 
       7             : MODULE m_chkmt
       8             :    USE m_juDFT
       9             : !---------------------------------------------------------------------
      10             : !  Check muffin tin radii and determine a reasonable choice for MTRs.
      11             : !  Derive also other parameters for the input file, to provide some
      12             : !  help in the out-file.
      13             : !                         GM'16
      14             : !
      15             : ! Note: This procedure is prepared to also return the next nearest
      16             : !       neighbors. That data is stored in nearestNeighborAtomsSorted,
      17             : !       nearestNeighborShiftsSorted, numNextNearestNeighbors.
      18             : !---------------------------------------------------------------------
      19             :    CONTAINS
      20             : 
      21          82 :    SUBROUTINE chkmt(atoms,input,vacuum,cell ,l_test,&
      22           0 :              l_gga,noel, kmax,dtild,dvac1,lmax1,jri1,rmt1,dx1,&!optional, if l_gga and ... are present suggestions are calculated
      23           2 :              overlap)!this is optional, if present and l_test the routine returns the overlaps and does not stop
      24             : 
      25             :       USE m_types_fleurinput
      26             :       USE m_constants
      27             :       USE m_sort
      28             :       USE m_inv3
      29             :       USE m_juDFT
      30             : 
      31             :       IMPLICIT NONE
      32             : 
      33             : !     .. Scalar Arguments ..
      34             :       TYPE(t_atoms),INTENT(IN) :: atoms
      35             :       TYPE(t_input),INTENT(IN) :: input
      36             :       TYPE(t_vacuum),INTENT(IN):: vacuum
      37             :       TYPE(t_cell),INTENT(IN)  :: cell
      38             :        
      39             :       CHARACTER*3, INTENT (IN),OPTIONAL :: noel(atoms%ntype)
      40             :       LOGICAL, INTENT (IN),OPTIONAL     :: l_gga
      41             :       LOGICAL, INTENT (IN)     ::l_test
      42             :       REAL,    INTENT (OUT),OPTIONAL    :: kmax,dtild,dvac1
      43             : 
      44             : !     .. Array Arguments ..
      45             :       INTEGER, INTENT (OUT),OPTIONAL    :: lmax1(atoms%ntype),jri1(atoms%ntype)
      46             :       REAL,    INTENT (OUT),OPTIONAL    :: rmt1(atoms%ntype),dx1(atoms%ntype)
      47             :       REAL,OPTIONAL,INTENT(OUT):: overlap(0:atoms%ntype,atoms%ntype)
      48             : 
      49             : !     .. Local Scalars ..
      50             :       INTEGER na,n
      51             :       INTEGER i,j,k,l,jri11,lmax11
      52             :       INTEGER maxCubeAtoms, iAtom, numAtoms, iNeighborAtom, identicalAtoms
      53             :       INTEGER typeA, typeB
      54             :       REAL    dx11,rkm,sum_r,facA,facB
      55             :       REAL    rmtMax, rmtMin, rmtMaxDefault, rmtDelta
      56             :       REAL    rmtFac, cubeLength, amatAuxDet
      57             :       REAL    maxSqrDist, dist, currentDist
      58             :       LOGICAL error, outOfBounds
      59             : 
      60             : !     .. Local Arrays ..
      61             :       REAL    t_rmt(0:103), minRmts(0:103)
      62             :       REAL    amatAux(3,3), invAmatAux(3,3)
      63          82 :       REAL    taualAux(3,atoms%nat), posAux(3,atoms%nat)
      64             :       REAL    minPos(3), maxPos(3), pos(3), point(3), realCellPos(3)
      65             :       REAL    offsetPos(3)
      66          82 :       REAL    nearestAtomDists(atoms%ntype)
      67          82 :       INTEGER nearestAtoms(atoms%ntype)
      68          82 :       INTEGER sortedDistList(atoms%ntype)
      69             :       INTEGER minCubeIndex(3), maxCubeIndex(3), cubeIndex(3)
      70             :       INTEGER minCellIndices(3), maxCellIndices(3)
      71             : 
      72          82 :       INTEGER, ALLOCATABLE :: numAtomsInCubes(:,:,:)
      73          82 :       INTEGER, ALLOCATABLE :: atomRefsInCubes(:,:,:,:)
      74          82 :       INTEGER, ALLOCATABLE :: atomsInCubes(:,:,:,:)
      75          82 :       INTEGER, ALLOCATABLE :: atomShiftsInCubes(:,:,:,:,:)
      76          82 :       INTEGER, ALLOCATABLE :: refCubes(:,:)
      77          82 :       INTEGER, ALLOCATABLE :: nearestNeighborRefsSorted(:,:)
      78          82 :       INTEGER, ALLOCATABLE :: nearestNeighborAtomsSorted(:,:)
      79          82 :       INTEGER, ALLOCATABLE :: nearestNeighborShiftsSorted(:,:,:)
      80          82 :       INTEGER, ALLOCATABLE :: numNearestNeighbors(:)
      81          82 :       INTEGER, ALLOCATABLE :: numNextNearestNeighbors(:)
      82          82 :       INTEGER, ALLOCATABLE :: neighborAtomRefs(:)
      83          82 :       INTEGER, ALLOCATABLE :: neighborAtoms(:)
      84          82 :       INTEGER, ALLOCATABLE :: neighborShifts(:,:)
      85          82 :       INTEGER, ALLOCATABLE :: distIndexList(:)
      86          82 :       REAL,    ALLOCATABLE :: posInCubes(:,:,:,:,:)
      87          82 :       REAL,    ALLOCATABLE :: refPos(:,:)
      88          82 :       REAL,    ALLOCATABLE :: nearestNeighborDists(:,:)
      89          82 :       REAL,    ALLOCATABLE :: sqrDistances(:)
      90             : 
      91             : !     Plan for this routine:
      92             : !     0. Do initializations and set some constants
      93             : !     1. Locally replace unit cell by an auxiliary unit cell with:
      94             : !        a) all atoms within the unit cell
      95             : !        b) basis vectors obtained by lattice reduction of the original cell.
      96             : !           [not in 1st (this) version of routine. Can be implemented with the LLL algorithm when needed.]
      97             : !     2. Get minimal and maximal coordinates within auxiliary unit cell
      98             : !     3. Construct mesh of cubes covering the auxiliary unit cell and a boundary of width 2*rmtMax + rmtDelta
      99             : !     4. Fill mesh of cubes with atoms
     100             : !        a) Store atoms in cubes and representative cube for each atom type
     101             : !     5. For each atom in auxiliary unit cell select cube and collect shortest distances to other atoms in neighborhood
     102             : !        a) Sort distances and set MT radii for the atoms
     103             : !     6. Correct bad choices and set missing MT radii, vacuum distances, and other parameters
     104             : !     7. Test old MT radii
     105             : 
     106             : 
     107             : !     0. Do initializations and set some constants
     108          98 :       if (present(overlap)) overlap=0.0
     109             : 
     110          82 :       rmtMaxDefault = 2.8
     111          82 :       rmtMax = rmtMaxDefault
     112          82 :       rmtMin = 1.0
     113          82 :       IF (l_test) THEN
     114         223 :          rmtMax = MAX(rmtMax,MAXVAL(atoms%rmt(:)))
     115         223 :          rmtMin = MIN(rmtMin,MINVAL(atoms%rmt(:)))
     116             :       END IF
     117          82 :       rmtDelta = 0.3
     118          82 :       IF (input%film) THEN
     119             :         rmtFac = 0.95
     120             :       ELSE
     121          70 :         rmtFac = 0.975
     122             :       ENDIF
     123        8610 :       t_rmt(0:103) = 2.3 ! default value
     124         656 :       t_rmt(1) = 1.0 ; t_rmt(5:9) = 1.3 ; t_rmt(16:17) = 1.8
     125          82 :       cubeLength = 2*rmtMax+rmtDelta
     126          82 :       maxCubeAtoms = (FLOOR(cubeLength / (0.7*2.0*rmtMin)) + 1)**3
     127          82 :       error  = .FALSE.
     128             : 
     129             : !     1. For the 1st version the auxiliary unit cell is just a copy of the original unit cell with
     130             : !        all atoms within the cell.
     131             : 
     132         328 :       DO i = 1, 3
     133        1066 :          DO j = 1, 3
     134         984 :             amatAux(i,j) = cell%amat(i,j)
     135             :          END DO
     136             :       END DO
     137             : 
     138         268 :       DO i = 1, atoms%nat
     139         186 :          taualAux(1,i) = atoms%taual(1,i) - FLOOR(atoms%taual(1,i))
     140         186 :          taualAux(2,i) = atoms%taual(2,i) - FLOOR(atoms%taual(2,i))
     141         186 :          taualAux(3,i) = atoms%taual(3,i) - FLOOR(atoms%taual(3,i))
     142        3058 :          posAux(:,i) = MATMUL(amatAux,taualAux(:,i))
     143             :       END DO
     144             : 
     145             : !     2. Get minimal and maximal coordinates for auxiliary unit cell
     146             : 
     147          82 :       minPos = 0.0
     148          82 :       maxPos = 0.0
     149             : 
     150         246 :       DO i = 0, 1
     151         574 :          DO j = 0, 1
     152        1148 :             DO k = 0, 1
     153        2952 :                DO l = 1, 3
     154        1968 :                   pos(l) = i*amatAux(l,1) + j*amatAux(l,2) + k*amatAux(l,3)
     155        1968 :                   IF (pos(l).GT.maxPos(l)) maxPos(l) = pos(l)
     156        2624 :                   IF (pos(l).LT.minPos(l)) minPos(l) = pos(l)
     157             :                END DO
     158             :             END DO
     159             :          END DO
     160             :       END DO
     161             : 
     162             : !     3. Construct cube mesh:
     163             : !        In each dimension cube i covers the interval from i*cubeLength to (i+1)*cubeLength
     164             : !        Each cube may cover up to maxCubeAtoms atoms. This should be set to a save size.
     165             : 
     166         328 :       DO i = 1, 3
     167         246 :          minPos(i) = minPos(i) - cubeLength
     168         246 :          maxPos(i) = maxPos(i) + cubeLength
     169         246 :          minCubeIndex(i) = FLOOR(minPos(i)/cubeLength)
     170         328 :          maxCubeIndex(i) = CEILING(maxPos(i)/cubeLength)
     171             :       END DO
     172             : 
     173             :       ALLOCATE (numAtomsInCubes(minCubeIndex(1):maxCubeIndex(1),&
     174             :                                 minCubeIndex(2):maxCubeIndex(2),&
     175         410 :                                 minCubeIndex(3):maxCubeIndex(3)))
     176             :       ALLOCATE (atomRefsInCubes(maxCubeAtoms,minCubeIndex(1):maxCubeIndex(1),&
     177             :                                              minCubeIndex(2):maxCubeIndex(2),&
     178         492 :                                              minCubeIndex(3):maxCubeIndex(3)))
     179             :       ALLOCATE (atomsInCubes(maxCubeAtoms,minCubeIndex(1):maxCubeIndex(1),&
     180             :                                           minCubeIndex(2):maxCubeIndex(2),&
     181         410 :                                           minCubeIndex(3):maxCubeIndex(3)))
     182             :       ALLOCATE (atomShiftsInCubes(3,maxCubeAtoms,minCubeIndex(1):maxCubeIndex(1),&
     183             :                                                  minCubeIndex(2):maxCubeIndex(2),&
     184         492 :                                                  minCubeIndex(3):maxCubeIndex(3)))
     185             :       ALLOCATE (posInCubes(3,maxCubeAtoms,minCubeIndex(1):maxCubeIndex(1),&
     186             :                                           minCubeIndex(2):maxCubeIndex(2),&
     187         492 :                                           minCubeIndex(3):maxCubeIndex(3)))
     188         410 :       ALLOCATE (refCubes(3,atoms%ntype),refPos(3,atoms%ntype))
     189         574 :       ALLOCATE (nearestNeighborRefsSorted(maxCubeAtoms,atoms%ntype),numNearestNeighbors(atoms%ntype),numNextNearestNeighbors(atoms%ntype))
     190         246 :       ALLOCATE (nearestNeighborAtomsSorted(maxCubeAtoms,atoms%ntype))
     191         328 :       ALLOCATE (nearestNeighborShiftsSorted(3,maxCubeAtoms,atoms%ntype))
     192         328 :       ALLOCATE (nearestNeighborDists(maxCubeAtoms,atoms%ntype))
     193             : 
     194       12833 :       numAtomsInCubes = 0
     195             : 
     196             : !     4. Fill mesh of cubes with atoms
     197             : !        First obtain minimal and maximal indices for relevant unit cells
     198             : 
     199          82 :       minCellIndices = 0
     200          82 :       maxCellIndices = 0
     201             : 
     202          82 :       CALL inv3(amatAux,invAmatAux,amatAuxDet)
     203             : 
     204         246 :       DO i = 0, 1
     205         574 :          DO j = 0, 1
     206        1148 :             DO k = 0, 1
     207         656 :                point(:) = minPos(:)
     208         656 :                IF(i.EQ.1) point(1) = maxPos(1)
     209         656 :                IF(j.EQ.1) point(2) = maxPos(2)
     210         656 :                IF(k.EQ.1) point(3) = maxPos(3)
     211        8528 :                realCellPos(:) = matmul(invAmatAux,point(:))
     212        2952 :                DO l = 1, 3
     213        1968 :                   IF(minCellIndices(l).GT.realCellPos(l)) THEN
     214         297 :                      minCellIndices(l) = FLOOR(realCellPos(l))
     215             :                   END IF
     216        2624 :                   IF(maxCellIndices(l).LT.realCellPos(l)) THEN
     217         974 :                      maxCellIndices(l) = FLOOR(realCellPos(l)) ! Is 'FLOOR' enough?
     218             :                   END IF
     219             :                END DO
     220             :             END DO
     221             :          END DO
     222             :       END DO
     223             : 
     224             : !        Store atoms in cubes and representative cube for each atom type
     225             : 
     226         534 :       DO i = minCellIndices(1), maxCellIndices(1)
     227        3358 :          DO j = minCellIndices(2), maxCellIndices(2)
     228       22504 :             DO k = minCellIndices(3), maxCellIndices(3)
     229       76912 :                DO l = 1, 3
     230       76912 :                   offsetPos(l) = i*amatAux(l,1) + j*amatAux(l,2) + k*amatAux(l,3)
     231             :                END DO
     232             :                iAtom = 0
     233       47067 :                DO n = 1, atoms%ntype
     234       74137 :                   DO na = 1, atoms%neq(n)
     235       29894 :                      iAtom = iAtom + 1
     236      119576 :                      pos(:) = posAux(:,iAtom) + offsetPos(:)
     237             :                      outOfBounds = .FALSE.
     238      119576 :                      DO l = 1, 3
     239       89682 :                         cubeIndex(l) = FLOOR(pos(l)/cubeLength)
     240       89682 :                         IF(cubeIndex(l).LT.minCubeIndex(l)) outOfBounds = .TRUE.
     241      119576 :                         IF(cubeIndex(l).GT.maxCubeIndex(l)) outOfBounds = .TRUE.
     242             :                      END DO
     243       54909 :                      IF(.NOT.outOfBounds) THEN
     244             :                         numAtomsInCubes(cubeIndex(1),cubeIndex(2),cubeIndex(3)) = &
     245       11701 :                            numAtomsInCubes(cubeIndex(1),cubeIndex(2),cubeIndex(3)) + 1
     246       11701 :                         numAtoms = numAtomsInCubes(cubeIndex(1),cubeIndex(2),cubeIndex(3))
     247       11701 :                         IF(numAtoms.GT.maxCubeAtoms) THEN
     248           0 :                            STOP 'ERROR: maxCubeAtoms is not large enough in chkmt.'
     249             :                         END IF
     250       11701 :                         atomRefsInCubes(numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = n
     251       11701 :                         atomsInCubes(numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = iAtom
     252       11701 :                         atomShiftsInCubes(1,numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = i - FLOOR(atoms%taual(1,na))
     253       11701 :                         atomShiftsInCubes(2,numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = j - FLOOR(atoms%taual(2,na))
     254       11701 :                         atomShiftsInCubes(3,numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = k - FLOOR(atoms%taual(3,na))
     255       46804 :                         posInCubes(:,numAtoms,cubeIndex(1),cubeIndex(2),cubeIndex(3)) = pos(:)
     256       11701 :                         IF((i.EQ.0).AND.(j.EQ.0).AND.(k.EQ.0).AND.(na.EQ.1)) THEN
     257         564 :                            refCubes(:,n) = cubeIndex(:)
     258         564 :                            refPos(:,n) = pos(:)
     259             :                         END IF
     260             :                      END IF
     261             :                   END DO
     262             :                END DO
     263             :             END DO
     264             :          END DO
     265             :       END DO
     266             : 
     267             : !     5. For each atom type in auxiliary unit cell select cube and collect shortest distances
     268             : !        to other atoms in neighborhood
     269             : 
     270          82 :       maxSqrDist = cubeLength**2
     271         246 :       ALLOCATE(sqrDistances(8*maxCubeAtoms)) ! Formally 27, but 8 should be enough due to maxSqrDist
     272         246 :       ALLOCATE(neighborAtomRefs(8*maxCubeAtoms))
     273         164 :       ALLOCATE(neighborAtoms(8*maxCubeAtoms))
     274         246 :       ALLOCATE(neighborShifts(3,8*maxCubeAtoms))
     275         164 :       ALLOCATE(distIndexList(8*maxCubeAtoms))
     276             : 
     277         223 :       DO n = 1, atoms%ntype
     278         564 :          cubeIndex(:) = refCubes(:,n)
     279      148117 :          neighborAtomRefs = 0
     280         141 :          iNeighborAtom = 0
     281         141 :          identicalAtoms = 0
     282         564 :          DO i = cubeIndex(1) - 1, cubeIndex(1) + 1
     283        1833 :             DO j = cubeIndex(2) - 1, cubeIndex(2) + 1
     284        5499 :                DO k = cubeIndex(3) - 1, cubeIndex(3) + 1
     285       13529 :                   DO iAtom = 1, numAtomsInCubes(i,j,k)
     286             :                      currentDist = (refPos(1,n) - posInCubes(1,iAtom,i,j,k))**2 + &
     287             :                                    (refPos(2,n) - posInCubes(2,iAtom,i,j,k))**2 + &
     288        8453 :                                    (refPos(3,n) - posInCubes(3,iAtom,i,j,k))**2
     289       12260 :                      IF (currentDist.LT.0.000001) THEN
     290         141 :                         identicalAtoms = identicalAtoms + 1
     291        8312 :                      ELSE IF (currentDist.LT.maxSqrDist) THEN
     292        1316 :                         iNeighborAtom = iNeighborAtom + 1
     293        1316 :                         neighborAtomRefs(iNeighborAtom) = atomRefsInCubes(iAtom,i,j,k)
     294        1316 :                         neighborAtoms(iNeighborAtom) = atomsInCubes(iAtom,i,j,k)
     295        5264 :                         neighborShifts(:,iNeighborAtom) = atomShiftsInCubes(:,iAtom,i,j,k)
     296        1316 :                         sqrDistances(iNeighborAtom) = currentDist
     297             :                      END IF
     298             :                   END DO
     299             :                END DO
     300             :             END DO
     301             :          END DO
     302         141 :          IF (identicalAtoms.GT.1) THEN
     303           0 :             WRITE(*,*) 'Position: ', refPos(:,n)
     304           0 :             CALL juDFT_error("Too many atoms at same position.",calledby ="chkmt")
     305             :          END IF
     306         141 :          numNearestNeighbors(n) = MIN(maxCubeAtoms,iNeighborAtom)
     307         141 :          CALL sort(distIndexList(:iNeighborAtom),sqrDistances(:iNeighborAtom))
     308        1539 :          DO i = 1, numNearestNeighbors(n)
     309        1316 :             nearestNeighborRefsSorted(i,n) = neighborAtomRefs(distIndexList(i))
     310        1316 :             nearestNeighborAtomsSorted(i,n) = neighborAtoms(distIndexList(i))
     311        5264 :             nearestNeighborShiftsSorted(:,i,n) = neighborShifts(:,distIndexList(i))
     312        1457 :             nearestNeighborDists(i,n) = SQRT(sqrDistances(distIndexList(i)))
     313             :          END DO
     314             :       END DO
     315             : 
     316          82 :       WRITE(ounit,*) ''
     317         223 :       DO i = 1, atoms%ntype
     318         223 :          IF(numNearestNeighbors(i).GE.1) THEN
     319         119 :             nearestAtoms(i) = nearestNeighborRefsSorted(1,i)
     320         119 :             nearestAtomDists(i) = nearestNeighborDists(1,i)
     321         119 :             WRITE(ounit,'(a,i6,a)') 'Nearest atoms, shifts for reference of atom type ', i, ":"
     322         119 :             WRITE(ounit,'(a)') '   atom       shifts'
     323         119 :             WRITE(ounit,'(4i6)') nearestNeighborAtomsSorted(1,i), nearestNeighborShiftsSorted(:,1,i)
     324         747 :             DO j = 2, numNearestNeighbors(i)
     325         709 :               IF ((nearestNeighborDists(j,i) - nearestAtomDists(i)).GT.0.0001) THEN
     326          81 :                  numNextNearestNeighbors(i) = j - 1
     327          81 :                  EXIT
     328             :               END IF
     329         628 :               IF (j.EQ.numNearestNeighbors(i)) numNextNearestNeighbors(i) = j
     330         666 :               WRITE(ounit,'(4i6)') nearestNeighborAtomsSorted(j,i), nearestNeighborShiftsSorted(:,j,i)
     331             :             END DO
     332             :          ELSE
     333          22 :             nearestAtoms(i) = -1
     334          22 :             nearestAtomDists(i) = 5000.0 * cubeLength
     335          22 :             numNextNearestNeighbors(i) = 0
     336             :          END IF
     337             :       END DO
     338             : 
     339             : 
     340          82 :       IF (PRESENT(l_gga)) THEN
     341             : !        Sort distances and set MT radii for the atoms
     342             : 
     343           0 :       CALL sort(sortedDistList,nearestAtomDists)
     344           0 :       rmt1 = -1.0
     345           0 :       minRmts = -1.0
     346           0 :       DO i = 1, atoms%ntype
     347           0 :          typeA = sortedDistList(i)
     348           0 :          typeB = nearestAtoms(typeA)
     349           0 :          IF(typeB.LT.0) CYCLE
     350           0 :          dist = nearestAtomDists(typeA)
     351           0 :          IF (dist.LT.0.5) THEN
     352           0 :             WRITE (*,*) "Distance between atoms too small!"
     353           0 :             WRITE (*,*) "atom type A: ", typeA
     354           0 :             WRITE (*,*) "atom type B: ", typeB
     355           0 :             WRITE (*,*) "distance: ", dist
     356           0 :             CALL juDFT_error("Distance between atoms too small!",calledby ="chkmt")
     357             :          END IF
     358           0 :          sum_r = 1.0 / ( t_rmt(atoms%nz(typeA)) + t_rmt(atoms%nz(typeB)) )
     359           0 :          facA = t_rmt(atoms%nz(typeA)) * sum_r
     360           0 :          facB = t_rmt(atoms%nz(typeB)) * sum_r
     361             :          ! Note: The result of this section may be slightly different from the old version
     362             :          !       iff the nearest atom is another atom of the same type
     363           0 :          IF (minRmts(atoms%nz(typeA)).LT.0.0) THEN
     364           0 :             IF (minRmts(atoms%nz(typeB)).LT.0.0) THEN
     365           0 :                minRmts(atoms%nz(typeA)) = rmtFac * dist * facA
     366           0 :                minRmts(atoms%nz(typeB)) = rmtFac * dist * facB
     367             :             ELSE
     368           0 :                minRmts(atoms%nz(typeA)) = rmtFac * (dist - minRmts(atoms%nz(typeB)))
     369             :             END IF
     370           0 :          ELSE IF (minRmts(atoms%nz(typeB)).LT.0.0) THEN
     371           0 :            minRmts(atoms%nz(typeB)) = rmtFac * (dist - minRmts(atoms%nz(typeA)))
     372             :          END IF
     373           0 :          minRmts(atoms%nz(typeA)) = min(minRmts(atoms%nz(typeA)),rmtMaxDefault) ! limit already here
     374           0 :          minRmts(atoms%nz(typeB)) = min(minRmts(atoms%nz(typeB)),rmtMaxDefault) ! to a reasonable value
     375             :       END DO
     376             : 
     377             : !     6. Correct bad choices and set missing MT radii, vacuum distances, and other parameters
     378             : 
     379           0 :       DO i = 1, atoms%ntype
     380           0 :          IF((minRmts(atoms%nz(i)).LT.0.0).OR.(minRmts(atoms%nz(i)).GE.rmtMaxDefault)) THEN
     381           0 :             minRmts(atoms%nz(i)) = rmtMaxDefault
     382             :          END IF
     383           0 :          rmt1(i) = minRmts(atoms%nz(i))
     384             :       END DO
     385             : 
     386             :       ! NOTE: The result of this section may be slightly different from the old version
     387             :       !       iff the old version would enlarge a MT sphere at this point.
     388             :       !       Also the old version does not propagate the changes of the MT radii to all
     389             :       !       atoms with the same atomic number
     390           0 :       DO i = 1, atoms%ntype
     391           0 :          DO j = 1, numNearestNeighbors(i)
     392           0 :             k = nearestNeighborRefsSorted(j,i)
     393           0 :             IF (rmt1(i)+rmt1(k).GE.nearestNeighborDists(j,i)) THEN
     394           0 :                minRmts(atoms%nz(i)) = MIN(rmtFac*nearestNeighborDists(j,i)/2.0,MIN(rmt1(i),minRmts(atoms%nz(i))))
     395           0 :                minRmts(atoms%nz(k)) = MIN(rmtFac*nearestNeighborDists(j,i)/2.0,MIN(rmt1(k),minRmts(atoms%nz(k))))
     396             :             END IF
     397             :          END DO
     398             :       END DO
     399             : 
     400           0 :       DO i = 1, atoms%ntype
     401           0 :          rmt1(i) = minRmts(atoms%nz(i))
     402             :       END DO
     403             : 
     404           0 :       WRITE (oUnit,*) '----------------------------------------------------'
     405           0 :       WRITE (oUnit,*) 'Suggested values for input: '
     406           0 :       WRITE (oUnit,*)
     407             : 
     408           0 :       dvac1 = 0.0
     409           0 :       IF (input%film) THEN
     410           0 :          iAtom = 0
     411           0 :          DO i = 1, atoms%ntype
     412           0 :             DO na = 1, atoms%neq(i)
     413           0 :                iAtom = iAtom + 1
     414             :                
     415           0 :                   dvac1 = MAX(dvac1, ABS(atoms%pos(3,iAtom))+rmt1(i))
     416             :                
     417             :             END DO
     418             :          END DO
     419           0 :          dvac1 = 2.0 * (dvac1+0.3)
     420           0 :          dtild = dvac1 + 1.5 * MAXVAL(rmt1(:))
     421           0 :          WRITE (oUnit,'("vacuum distance dvac =",f10.5)') dvac1
     422           0 :          WRITE (oUnit,'("extra vac.dist. dtild=",f10.5)') dtild
     423             :       END IF
     424             : 
     425           0 :       rkm = 0.0
     426           0 :       WRITE (oUnit,*) 'Atom Z  lmax jri    rmt         dx'
     427           0 :       DO n = 1, atoms%ntype
     428           0 :          IF (rmt1(n).LT.1.8) THEN
     429           0 :             lmax11 = 6
     430           0 :          ELSE IF (rmt1(n).LT.2.4) THEN
     431           0 :             lmax11 = 8
     432             :          ELSE
     433           0 :             lmax11 = 10
     434             :          END IF
     435           0 :          IF (l_gga) THEN
     436           0 :             jri11 = NINT(330*rmt1(n))
     437             :          ELSE
     438           0 :             jri11 = NINT(220*rmt1(n))
     439             :          END IF
     440           0 :          jri11 = NINT(jri11*0.5) * 2 + 1
     441           0 :          IF (atoms%nz(n) > 0) THEN
     442           0 :            dx11 = LOG(3200*atoms%nz(n)*rmt1(n))/(jri11-1)
     443             :          ELSE
     444           0 :            dx11 = LOG(3200*rmt1(n))/(jri11-1)
     445             :          ENDIF
     446           0 :          rkm = MAX(rkm, lmax11/rmt1(n))
     447           0 :          WRITE (oUnit,'(a3,i3,2i5,2f10.6)') noel(n),atoms%nz(n),lmax11,jri11,rmt1(n),dx11
     448           0 :          dx1(n) = dx11
     449           0 :          lmax1(n) = lmax11
     450           0 :          jri1(n) = jri11
     451             :       END DO
     452           0 :       WRITE (oUnit,'("k_max =",f8.5)') rkm
     453           0 :       WRITE (oUnit,'("G_max =",f8.5)') 3*rkm
     454           0 :       kmax = rkm
     455             :       ENDIF
     456             : 
     457             : !     7. Test old MT radii
     458             : 
     459          82 :       IF (l_test) THEN
     460          82 :          iAtom = 0
     461         223 :          DO i = 1, atoms%ntype
     462        1457 :             DO j = 1, numNearestNeighbors(i)
     463        1316 :                k = nearestNeighborRefsSorted(j,i)
     464        1457 :                IF (atoms%rmt(i)+atoms%rmt(k).GE.nearestNeighborDists(j,i)) THEN
     465           0 :                   error = .TRUE.
     466           0 :                   IF (PRESENT(overlap)) overlap(i,k)=atoms%rmt(i)+atoms%rmt(k)-nearestNeighborDists(j,i)
     467           0 :                   WRITE(oUnit,240) i,k,nearestNeighborDists(j,i),atoms%rmt(i),atoms%rmt(k)
     468           0 :                   IF (.NOT.PRESENT(overlap)) CALL juDFT_error("Overlapping MT-radii of two neighbours detected.",calledby ="chkmt")
     469             :                END IF
     470             :             END DO
     471         223 :             IF (input%film) THEN
     472          58 :                DO na = 1, atoms%neq(i)
     473          35 :                   iAtom = iAtom + 1
     474             :                  
     475          35 :                      IF (((atoms%pos(3,iAtom)+atoms%rmt(i)).GT. vacuum%dvac/2.).OR.&
     476          23 :                          ((atoms%pos(3,iAtom)-atoms%rmt(i)).LT.-vacuum%dvac/2.)) THEN
     477           0 :                         error=.TRUE.
     478           0 :                         WRITE(oUnit,241) i ,na
     479           0 :                         IF (PRESENT(overlap)) overlap(0,i)=MAX(overlap(0,i),abs(atoms%pos(3,iAtom))+atoms%rmt(i)-vacuum%dvac/2.)
     480           0 :                         WRITE(oUnit,*) atoms%pos(3,iAtom),atoms%rmt(i),vacuum%dvac/2.
     481           0 :                         IF (.NOT.PRESENT(overlap)) CALL juDFT_error("MT is partly inside the vacuum.",calledby ="chkmt")
     482             :                      ENDIF
     483             :                  
     484             :                END DO
     485             :             END IF
     486             :          END DO
     487          82 :          IF (error.AND..NOT.PRESENT(overlap)) CALL juDFT_error("Error checking M.T. radii",calledby ="chkmt")
     488             :       END IF
     489             : 
     490          82 :       DEALLOCATE(nearestNeighborRefsSorted,nearestNeighborAtomsSorted,nearestNeighborShiftsSorted,numNearestNeighbors,numNextNearestNeighbors,nearestNeighborDists)
     491          82 :       DEALLOCATE(distIndexList,neighborAtomRefs,neighborAtoms,neighborShifts,sqrDistances)
     492          82 :       DEALLOCATE(numAtomsInCubes,atomRefsInCubes,atomsInCubes,atomShiftsInCubes,posInCubes,refCubes,refPos)
     493             : 
     494             :   240 FORMAT('Error in muffin tin radii pair (',i5,',',i5,'):',3f10.5)
     495             :   241 FORMAT('   error: atom ',i3,' # ',i3,'reaches out into vaccuum')
     496             : 
     497         166 :    END SUBROUTINE chkmt
     498             : END MODULE m_chkmt

Generated by: LCOV version 1.14