| 4 |  | use force_globals | 
| 5 |  | use status | 
| 6 |  | use atype_module | 
| 7 | < | #ifdef MPI | 
| 7 | > | #ifdef IS_MPI | 
| 8 |  | use mpiSimulation | 
| 9 |  | #endif | 
| 10 |  | implicit none | 
| 14 |  | logical, save :: EAM_FF_initialized = .false. | 
| 15 |  | integer, save :: EAM_Mixing_Policy | 
| 16 |  | real(kind = dp), save :: EAM_rcut | 
| 17 | + | real(kind = dp), save :: EAM_rcut_orig | 
| 18 |  |  | 
| 19 | + | character(len = statusMsgSize) :: errMesg | 
| 20 | + | integer :: eam_err | 
| 21 | + |  | 
| 22 |  | character(len = 200) :: errMsg | 
| 23 |  | character(len=*), parameter :: RoutineName =  "EAM MODULE" | 
| 24 | + | !! Logical that determines if eam arrays should be zeroed | 
| 25 |  | logical :: cleanme = .true. | 
| 26 | + | logical :: nmflag  = .false. | 
| 27 |  |  | 
| 22 | – |  | 
| 28 |  |  | 
| 29 |  | type, private :: EAMtype | 
| 30 |  | integer           :: eam_atype | 
| 54 |  | real( kind = dp), dimension(:), allocatable :: rho | 
| 55 |  |  | 
| 56 |  | real( kind = dp), dimension(:), allocatable :: dfrhodrho | 
| 57 | < | !  real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho | 
| 57 | > | real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho | 
| 58 |  |  | 
| 59 |  |  | 
| 60 |  | !! Arrays for MPI storage | 
| 61 | < | #ifdef MPI | 
| 61 | > | #ifdef IS_MPI | 
| 62 |  | real( kind = dp), dimension(:), allocatable :: dfrhodrho_col | 
| 63 |  | real( kind = dp), dimension(:), allocatable :: dfrhodrho_row | 
| 64 |  | real( kind = dp), dimension(:), allocatable :: frho_row | 
| 65 |  | real( kind = dp), dimension(:), allocatable :: frho_col | 
| 66 |  | real( kind = dp), dimension(:), allocatable :: rho_row | 
| 67 |  | real( kind = dp), dimension(:), allocatable :: rho_col | 
| 68 | < |  | 
| 68 | > | real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho_col | 
| 69 | > | real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho_row | 
| 70 |  | #endif | 
| 71 |  |  | 
| 72 |  | type, private :: EAMTypeList | 
| 84 |  |  | 
| 85 |  | public :: init_EAM_FF | 
| 86 |  | !  public :: EAM_new_rcut | 
| 87 | < | !  public :: do_EAM_pair | 
| 87 | > | public :: do_eam_pair | 
| 88 |  | public :: newEAMtype | 
| 89 | < |  | 
| 89 | > | public :: calc_eam_prepair_rho | 
| 90 | > | public :: calc_eam_preforce_Frho | 
| 91 |  |  | 
| 92 |  |  | 
| 93 |  | contains | 
| 113 |  | integer                                :: alloc_stat | 
| 114 |  | integer                                :: current | 
| 115 |  | integer,pointer                        :: Matchlist(:) => null() | 
| 116 | + | type (EAMtype), pointer                :: makeEamtype => null() | 
| 117 |  | status = 0 | 
| 118 |  |  | 
| 119 |  | !! Assume that atypes has already been set and get the total number of types in atypes | 
| 131 |  | current = EAMList%currentAddition | 
| 132 |  |  | 
| 133 |  |  | 
| 134 | < | !call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat) | 
| 134 | > | call allocate_EAMType(eam_nrho,eam_nr,makeEamtype,stat=alloc_stat) | 
| 135 |  | if (alloc_stat /= 0) then | 
| 136 |  | status = -1 | 
| 137 |  | return | 
| 138 |  | end if | 
| 139 | + | makeEamtype => EAMList%EAMParams(current) | 
| 140 |  |  | 
| 132 | – |  | 
| 141 |  | ! this is a possible bug, we assume a correspondence between the vector atypes and | 
| 142 |  | ! EAMAtypes | 
| 143 |  |  | 
| 162 |  | integer :: alloc_stat | 
| 163 |  | integer :: number_r, number_rho | 
| 164 |  |  | 
| 165 | + |  | 
| 166 | + |  | 
| 167 |  | do i = 1, EAMList%currentAddition | 
| 168 |  |  | 
| 169 |  | EAMList%EAMParams(i)%eam_rvals(1:EAMList%EAMParams(i)%eam_nr) = & | 
| 208 |  | enddo | 
| 209 |  |  | 
| 210 |  | current_rcut_max = EAMList%EAMParams(1)%eam_rcut | 
| 211 | < | !! find the smallest rcut | 
| 211 | > | !! find the smallest rcut for any eam atype | 
| 212 |  | do i = 2, EAMList%currentAddition | 
| 213 |  | current_rcut_max = min(current_rcut_max,EAMList%EAMParams(i)%eam_rcut) | 
| 214 |  | end do | 
| 215 |  |  | 
| 216 |  | EAM_rcut = current_rcut_max | 
| 217 | + | EAM_rcut_orig = current_rcut_max | 
| 218 |  | !       do i = 1, EAMList%currentAddition | 
| 219 |  | !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i | 
| 220 |  | !       end do | 
| 235 |  | integer, intent(out) :: status | 
| 236 |  |  | 
| 237 |  | integer :: nlocal | 
| 238 | < | #ifdef MPI | 
| 238 | > | #ifdef IS_MPI | 
| 239 |  | integer :: nrow | 
| 240 |  | integer :: ncol | 
| 241 |  | #endif | 
| 244 |  |  | 
| 245 |  | nlocal = getNlocal() | 
| 246 |  |  | 
| 247 | < | #ifdef MPI | 
| 247 | > | #ifdef IS_MPI | 
| 248 |  | nrow = getNrow(plan_row) | 
| 249 |  | ncol = getNcol(plan_col) | 
| 250 |  | #endif | 
| 261 |  | status = -1 | 
| 262 |  | return | 
| 263 |  | end if | 
| 264 | + |  | 
| 265 |  | if (allocated(dfrhodrho)) deallocate(dfrhodrho) | 
| 266 |  | allocate(dfrhodrho(nlocal),stat=alloc_stat) | 
| 267 |  | if (alloc_stat /= 0) then | 
| 268 |  | status = -1 | 
| 269 |  | return | 
| 270 |  | end if | 
| 271 | + |  | 
| 272 | + | if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho) | 
| 273 | + | allocate(d2frhodrhodrho(nlocal),stat=alloc_stat) | 
| 274 | + | if (alloc_stat /= 0) then | 
| 275 | + | status = -1 | 
| 276 | + | return | 
| 277 | + | end if | 
| 278 |  |  | 
| 279 | < | #ifdef MPI | 
| 279 | > | #ifdef IS_MPI | 
| 280 |  |  | 
| 281 |  | if (allocated(frho_row)) deallocate(frho_row) | 
| 282 |  | allocate(frho_row(nrow),stat=alloc_stat) | 
| 296 |  | status = -1 | 
| 297 |  | return | 
| 298 |  | end if | 
| 299 | + | if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row) | 
| 300 | + | allocate(d2frhodrhodrho_row(nrow),stat=alloc_stat) | 
| 301 | + | if (alloc_stat /= 0) then | 
| 302 | + | status = -1 | 
| 303 | + | return | 
| 304 | + | end if | 
| 305 |  |  | 
| 306 | + |  | 
| 307 |  | ! Now do column arrays | 
| 308 |  |  | 
| 309 |  | if (allocated(frho_col)) deallocate(frho_col) | 
| 324 |  | status = -1 | 
| 325 |  | return | 
| 326 |  | end if | 
| 327 | < |  | 
| 327 | > | if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col) | 
| 328 | > | allocate(d2frhodrhodrho_col(ncol),stat=alloc_stat) | 
| 329 | > | if (alloc_stat /= 0) then | 
| 330 | > | status = -1 | 
| 331 | > | return | 
| 332 | > | end if | 
| 333 | > |  | 
| 334 |  | #endif | 
| 335 |  |  | 
| 336 |  | end subroutine allocateEAM | 
| 338 |  |  | 
| 339 |  | subroutine clean_EAM() | 
| 340 |  |  | 
| 341 | < | ! clean non-MPI first | 
| 341 | > | ! clean non-IS_MPI first | 
| 342 |  | frho = 0.0_dp | 
| 343 |  | rho  = 0.0_dp | 
| 344 |  | dfrhodrho = 0.0_dp | 
| 345 |  | ! clean MPI if needed | 
| 346 | < | #ifdef MPI | 
| 346 | > | #ifdef IS_MPI | 
| 347 |  | frho_row = 0.0_dp | 
| 348 |  | frho_col = 0.0_dp | 
| 349 |  | rho_row  = 0.0_dp | 
| 453 |  | real( kind = dp) :: drho,d2rho | 
| 454 |  | integer :: eam_err | 
| 455 |  |  | 
| 456 | + | integer :: myid_atom1 | 
| 457 | + | integer :: myid_atom2 | 
| 458 | + |  | 
| 459 | + | ! check to see if we need to be cleaned at the start of a force loop | 
| 460 |  | if (cleanme) call clean_EAM | 
| 461 |  | cleanme = .false. | 
| 462 | + |  | 
| 463 |  |  | 
| 464 | < | call  calc_eam_rho(r,rho_i_at_j,drho,d2rho,atom1) | 
| 464 | > | #ifdef IS_MPI | 
| 465 | > | myid_atom1 = atid_Row(atom1) | 
| 466 | > | myid_atom2 = atid_Col(atom2) | 
| 467 | > | #else | 
| 468 | > | myid_atom1 = atid(atom1) | 
| 469 | > | myid_atom2 = atid(atom2) | 
| 470 | > | #endif | 
| 471 |  |  | 
| 472 | < | #ifdef  MPI | 
| 473 | < | rho_col(atom2) = rho_col(atom2) + rho_i_at_j | 
| 472 | > | if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then | 
| 473 | > |  | 
| 474 | > |  | 
| 475 | > |  | 
| 476 | > | call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, & | 
| 477 | > | EAMList%EAMParams(myid_atom1)%eam_rvals, & | 
| 478 | > | EAMList%EAMParams(myid_atom1)%eam_rho_r, & | 
| 479 | > | EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, & | 
| 480 | > | r, rho_i_at_j,drho,d2rho) | 
| 481 | > |  | 
| 482 | > |  | 
| 483 | > |  | 
| 484 | > | #ifdef  IS_MPI | 
| 485 | > | rho_col(atom2) = rho_col(atom2) + rho_i_at_j | 
| 486 |  | #else | 
| 487 | < | rho(atom2) = rho(atom2) + rho_i_at_j | 
| 487 | > | rho(atom2) = rho(atom2) + rho_i_at_j | 
| 488 |  | #endif | 
| 489 | + | endif | 
| 490 |  |  | 
| 491 | < | call calc_eam_rho(r,rho_j_at_i,drho,d2rho,atom2) | 
| 491 | > | if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then | 
| 492 | > | call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, & | 
| 493 | > | EAMList%EAMParams(myid_atom2)%eam_rvals, & | 
| 494 | > | EAMList%EAMParams(myid_atom2)%eam_rho_r, & | 
| 495 | > | EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, & | 
| 496 | > | r, rho_j_at_i,drho,d2rho) | 
| 497 |  |  | 
| 498 | < | #ifdef  MPI | 
| 499 | < | rho_row(atom1) = rho_row(atom1) + rho_j_at_i | 
| 498 | > |  | 
| 499 | > |  | 
| 500 | > |  | 
| 501 | > | #ifdef  IS_MPI | 
| 502 | > | rho_row(atom1) = rho_row(atom1) + rho_j_at_i | 
| 503 |  | #else | 
| 504 | < | rho(atom1) = rho(atom1) + rho_j_at_i | 
| 504 | > | rho(atom1) = rho(atom1) + rho_j_at_i | 
| 505 |  | #endif | 
| 506 | + | endif | 
| 507 | + |  | 
| 508 |  | end subroutine calc_eam_prepair_rho | 
| 509 |  |  | 
| 510 | < | !! Calculate the functional F(rho) for all atoms | 
| 511 | < | subroutine calc_eam_prepair_Frho(nlocal,pot) | 
| 510 | > |  | 
| 511 | > |  | 
| 512 | > |  | 
| 513 | > | !! Calculate the functional F(rho) for all local atoms | 
| 514 | > | subroutine calc_eam_preforce_Frho(nlocal,pot) | 
| 515 |  | integer :: nlocal | 
| 516 |  | real(kind=dp) :: pot | 
| 517 |  | integer :: i,j | 
| 518 | + | integer :: atom | 
| 519 |  | real(kind=dp) :: U,U1,U2 | 
| 520 |  | integer :: atype1 | 
| 521 | + | integer :: me | 
| 522 | + | integer :: n_rho_points | 
| 523 |  | ! reset clean forces to be true at top of calc rho. | 
| 524 |  | cleanme = .true. | 
| 525 |  |  | 
| 526 | < | !! Scatter the electron density in pre-pair | 
| 527 | < | #ifdef MPI | 
| 526 | > | !! Scatter the electron density from  pre-pair calculation back to local atoms | 
| 527 | > | #ifdef IS_MPI | 
| 528 |  | call scatter(rho_row,rho,plan_row,eam_err) | 
| 529 |  | if (eam_err /= 0 ) then | 
| 530 |  | write(errMsg,*) " Error scattering rho_row into rho" | 
| 537 |  | endif | 
| 538 |  | #endif | 
| 539 |  |  | 
| 468 | – | do i = 1, nlocal | 
| 469 | – | call calc_eam_frho(rho(i),u,u1,u2,atype1) | 
| 470 | – | frho(i) = u | 
| 471 | – | dfrhodrho(i) = u1 | 
| 472 | – | !      d2frhodrhodrho(i) = u2 | 
| 473 | – | pot = pot + u | 
| 474 | – | enddo | 
| 540 |  |  | 
| 541 | < | #ifdef MPI | 
| 542 | < | !! communicate f(rho) and derivatives | 
| 541 | > | !! Calculate F(rho) and derivative | 
| 542 | > | do atom = 1, nlocal | 
| 543 | > | me = atid(atom) | 
| 544 | > | n_rho_points = EAMList%EAMParams(me)%eam_nrho | 
| 545 | > | !  Check to see that the density is not greater than the larges rho we have calculated | 
| 546 | > | if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then | 
| 547 | > | call eam_splint(n_rho_points, & | 
| 548 | > | EAMList%EAMParams(me)%eam_rhovals, & | 
| 549 | > | EAMList%EAMParams(me)%eam_f_rho, & | 
| 550 | > | EAMList%EAMParams(me)%eam_f_rho_pp, & | 
| 551 | > | rho(atom), & ! Actual Rho | 
| 552 | > | u, u1, u2) | 
| 553 | > | else | 
| 554 | > | ! Calculate F(rho with the largest available rho value | 
| 555 | > | call eam_splint(n_rho_points, & | 
| 556 | > | EAMList%EAMParams(me)%eam_rhovals, & | 
| 557 | > | EAMList%EAMParams(me)%eam_f_rho, & | 
| 558 | > | EAMList%EAMParams(me)%eam_f_rho_pp, & | 
| 559 | > | EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho | 
| 560 | > | u,u1,u2) | 
| 561 | > | end if | 
| 562 | > |  | 
| 563 | > |  | 
| 564 | > | frho(i) = u | 
| 565 | > | dfrhodrho(i) = u1 | 
| 566 | > | d2frhodrhodrho(i) = u2 | 
| 567 | > | pot = pot + u | 
| 568 | > | enddo | 
| 569 | > |  | 
| 570 | > |  | 
| 571 | > |  | 
| 572 | > | #ifdef IS_MPI | 
| 573 | > | !! communicate f(rho) and derivatives back into row and column arrays | 
| 574 |  | call gather(frho,frho_row,plan_row, eam_err) | 
| 575 |  | if (eam_err /=  0) then | 
| 576 |  | call handleError("cal_eam_forces()","MPI gather frho_row failure") | 
| 588 |  | call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure") | 
| 589 |  | endif | 
| 590 |  |  | 
| 591 | + |  | 
| 592 | + |  | 
| 593 | + |  | 
| 594 | + |  | 
| 595 |  | if (nmflag) then | 
| 596 |  | call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_row) | 
| 597 |  | call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_col) | 
| 598 |  | endif | 
| 599 |  | #endif | 
| 600 |  |  | 
| 601 | + | end subroutine calc_eam_preforce_Frho | 
| 602 |  |  | 
| 502 | – | end subroutine calc_eam_prepair_Frho | 
| 603 |  |  | 
| 604 |  |  | 
| 605 |  |  | 
| 606 | < |  | 
| 607 | < | subroutine calc_eam_pair(atom1,atom2,d,rij,r2,pot,f,do_pot,do_stress) | 
| 608 | < | !Arguments | 
| 606 | > | !! Does EAM pairwise Force calculation. | 
| 607 | > | subroutine do_eam_pair(atom1,atom2,d,rij,r2,pot,f,do_pot,do_stress) | 
| 608 | > | !Arguments | 
| 609 |  | integer, intent(in) ::  atom1, atom2 | 
| 610 |  | real( kind = dp ), intent(in) :: rij, r2 | 
| 611 |  | real( kind = dp ) :: pot | 
| 612 |  | real( kind = dp ), dimension(3,getNlocal()) :: f | 
| 613 |  | real( kind = dp ), intent(in), dimension(3) :: d | 
| 614 |  | logical, intent(in) :: do_pot, do_stress | 
| 615 | < |  | 
| 615 | > |  | 
| 616 |  | real( kind = dp ) :: drdx,drdy,drdz | 
| 617 | + | real( kind = dp ) :: d2 | 
| 618 |  | real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr | 
| 619 |  | real( kind = dp ) :: rha,drha,d2rha, dpha | 
| 620 |  | real( kind = dp ) :: rhb,drhb,d2rhb, dphb | 
| 625 |  | real( kind = dp ) :: d2rhojdrdr | 
| 626 |  | real( kind = dp ) :: Fx,Fy,Fz | 
| 627 |  | real( kind = dp ) :: r,d2pha,phb,d2phb | 
| 628 | + |  | 
| 629 |  | integer :: id1,id2 | 
| 630 | < | integer  :: atype1,atype2 | 
| 630 | > | integer  :: mytype_atom1 | 
| 631 | > | integer  :: mytype_atom2 | 
| 632 |  |  | 
| 633 |  |  | 
| 634 |  | !Local Variables | 
| 638 |  | phab = 0.0E0_DP | 
| 639 |  | dvpdr = 0.0E0_DP | 
| 640 |  | d2vpdrdr = 0.0E0_DP | 
| 641 | < |  | 
| 642 | < |  | 
| 641 | > |  | 
| 642 | > |  | 
| 643 |  | if (rij .lt. EAM_rcut) then | 
| 644 |  | #ifdef IS_MPI | 
| 645 |  | !!!!! FIX ME | 
| 646 | < | atype1 = atid_row(atom1) | 
| 646 | > | mytype_atom1 = atid_row(atom1) | 
| 647 |  | #else | 
| 648 | < | atype1 = atid(atom1) | 
| 648 | > | mytype_atom1 = atid(atom1) | 
| 649 |  | #endif | 
| 650 | < |  | 
| 650 | > |  | 
| 651 |  | drdx = d(1)/rij | 
| 652 |  | drdy = d(2)/rij | 
| 653 |  | drdz = d(3)/rij | 
| 654 |  |  | 
| 655 | < |  | 
| 656 | < | call calc_eam_rho(r, rha, drha, d2rha, atype1) | 
| 657 | < | call calc_eam_phi(r, pha, dpha, d2pha, atype1) | 
| 658 | < | !     rci = eam_rcut(eam_atype_map(atom1)) | 
| 655 | > |  | 
| 656 | > | call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, & | 
| 657 | > | EAMList%EAMParams(mytype_atom1)%eam_rvals, & | 
| 658 | > | EAMList%EAMParams(mytype_atom1)%eam_rho_r, & | 
| 659 | > | EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, & | 
| 660 | > | rij, rha,drha,d2rha) | 
| 661 | > |  | 
| 662 | > | !! Calculate Phi(r) for atom1. | 
| 663 | > | call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, & | 
| 664 | > | EAMList%EAMParams(mytype_atom1)%eam_rvals, & | 
| 665 | > | EAMList%EAMParams(mytype_atom1)%eam_phi_r, & | 
| 666 | > | EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, & | 
| 667 | > | rij, pha,dpha,d2pha) | 
| 668 | > |  | 
| 669 | > |  | 
| 670 | > | ! get cutoff for atom 1 | 
| 671 | > | rci = EAMList%EAMParams(mytype_atom1)%eam_rcut | 
| 672 |  | #ifdef IS_MPI | 
| 673 | < | atype2 = atid_col(atom2) | 
| 673 | > | mytype_atom2 = atid_col(atom2) | 
| 674 |  | #else | 
| 675 | < | atype2 = atid(atom2) | 
| 675 | > | mytype_atom2 = atid(atom2) | 
| 676 |  | #endif | 
| 561 | – |  | 
| 562 | – | call calc_eam_rho(r, rhb, drhb, d2rhb, atype2) | 
| 563 | – | call calc_eam_phi(r, phb, dphb, d2phb, atype2) | 
| 564 | – | !     rcj = eam_rcut(eam_atype_map(atype2)) | 
| 677 |  |  | 
| 678 | < | if (r.lt.rci) then | 
| 678 | > | ! Calculate rho,drho and d2rho for atom1 | 
| 679 | > | call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, & | 
| 680 | > | EAMList%EAMParams(mytype_atom2)%eam_rvals, & | 
| 681 | > | EAMList%EAMParams(mytype_atom2)%eam_rho_r, & | 
| 682 | > | EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, & | 
| 683 | > | rij, rhb,drhb,d2rhb) | 
| 684 | > |  | 
| 685 | > | !! Calculate Phi(r) for atom2. | 
| 686 | > | call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, & | 
| 687 | > | EAMList%EAMParams(mytype_atom2)%eam_rvals, & | 
| 688 | > | EAMList%EAMParams(mytype_atom2)%eam_phi_r, & | 
| 689 | > | EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, & | 
| 690 | > | rij, phb,dphb,d2phb) | 
| 691 | > |  | 
| 692 | > |  | 
| 693 | > | ! get type specific cutoff for atom 2 | 
| 694 | > | rcj = EAMList%EAMParams(mytype_atom1)%eam_rcut | 
| 695 | > |  | 
| 696 | > |  | 
| 697 | > |  | 
| 698 | > | if (rij.lt.rci) then | 
| 699 |  | phab = phab + 0.5E0_DP*(rhb/rha)*pha | 
| 700 |  | dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + & | 
| 701 |  | pha*((drhb/rha) - (rhb*drha/rha/rha))) | 
| 706 |  | endif | 
| 707 |  |  | 
| 708 |  |  | 
| 709 | < | if (r.lt.rcj) then | 
| 709 | > | if (rij.lt.rcj) then | 
| 710 |  | phab = phab + 0.5E0_DP*(rha/rhb)*phb | 
| 711 |  | dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + & | 
| 712 |  | phb*((drha/rhb) - (rha*drhb/rhb/rhb))) | 
| 723 |  | d2rhojdrdr = d2rhb | 
| 724 |  |  | 
| 725 |  |  | 
| 726 | < | #ifdef MPI | 
| 726 | > | #ifdef IS_MPI | 
| 727 |  | dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) & | 
| 728 |  | + dvpdr | 
| 729 |  |  | 
| 738 |  | fz = dudr * drdz | 
| 739 |  |  | 
| 740 |  |  | 
| 741 | < | #ifdef MPI | 
| 741 | > | #ifdef IS_MPI | 
| 742 |  | if (do_pot) then | 
| 743 |  | pot_Row(atom1) = pot_Row(atom1) + phab*0.5 | 
| 744 |  | pot_Col(atom2) = pot_Col(atom2) + phab*0.5 | 
| 747 |  | f_Row(1,atom1) = f_Row(1,atom1) + fx | 
| 748 |  | f_Row(2,atom1) = f_Row(2,atom1) + fy | 
| 749 |  | f_Row(3,atom1) = f_Row(3,atom1) + fz | 
| 750 | < |  | 
| 750 | > |  | 
| 751 |  | f_Col(1,atom2) = f_Col(1,atom2) - fx | 
| 752 |  | f_Col(2,atom2) = f_Col(2,atom2) - fy | 
| 753 |  | f_Col(3,atom2) = f_Col(3,atom2) - fz | 
| 754 |  | #else | 
| 755 |  | if(do_pot) pot = pot + phab | 
| 756 | < |  | 
| 756 | > |  | 
| 757 |  | f(1,atom1) = f(1,atom1) + fx | 
| 758 |  | f(2,atom1) = f(2,atom1) + fy | 
| 759 |  | f(3,atom1) = f(3,atom1) + fz | 
| 760 | < |  | 
| 760 | > |  | 
| 761 |  | f(1,atom2) = f(1,atom2) - fx | 
| 762 |  | f(2,atom2) = f(2,atom2) - fy | 
| 763 |  | f(3,atom2) = f(3,atom2) - fz | 
| 764 |  | #endif | 
| 765 | + |  | 
| 766 | + | if (nmflag) then | 
| 767 |  |  | 
| 768 | + | drhoidr = drha | 
| 769 | + | drhojdr = drhb | 
| 770 | + | d2rhoidrdr = d2rha | 
| 771 | + | d2rhojdrdr = d2rhb | 
| 772 |  |  | 
| 773 | + | #ifdef IS_MPI | 
| 774 | + | d2 = d2vpdrdr + & | 
| 775 | + | d2rhoidrdr*dfrhodrho_col(atom2) + & | 
| 776 | + | d2rhojdrdr*dfrhodrho_row(atom1) + & | 
| 777 | + | drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + & | 
| 778 | + | drhojdr*drhojdr*d2frhodrhodrho_row(atom1) | 
| 779 | + |  | 
| 780 | + | #else | 
| 781 |  |  | 
| 782 | + | d2 = d2vpdrdr + & | 
| 783 | + | d2rhoidrdr*dfrhodrho(atom2) + & | 
| 784 | + | d2rhojdrdr*dfrhodrho(atom1) + & | 
| 785 | + | drhoidr*drhoidr*d2frhodrhodrho(atom2) + & | 
| 786 | + | drhojdr*drhojdr*d2frhodrhodrho(atom1) | 
| 787 | + | #endif | 
| 788 | + | end if | 
| 789 |  |  | 
| 637 | – | if (do_stress) then | 
| 790 |  |  | 
| 791 | < | #ifdef MPI | 
| 791 | > |  | 
| 792 | > |  | 
| 793 | > | if (do_stress) then | 
| 794 | > |  | 
| 795 | > | #ifdef IS_MPI | 
| 796 |  | id1 = tagRow(atom1) | 
| 797 |  | id2 = tagColumn(atom2) | 
| 798 |  | #else | 
| 799 |  | id1 = atom1 | 
| 800 |  | id2 = atom2 | 
| 801 |  | #endif | 
| 802 | < |  | 
| 802 | > |  | 
| 803 |  | if (molMembershipList(id1) .ne. molMembershipList(id2)) then | 
| 804 |  |  | 
| 805 | < | tau_Temp(1) = tau_Temp(1) + fx * d(1) | 
| 806 | < | tau_Temp(2) = tau_Temp(2) + fx * d(2) | 
| 807 | < | tau_Temp(3) = tau_Temp(3) + fx * d(3) | 
| 808 | < | tau_Temp(4) = tau_Temp(4) + fy * d(1) | 
| 809 | < | tau_Temp(5) = tau_Temp(5) + fy * d(2) | 
| 810 | < | tau_Temp(6) = tau_Temp(6) + fy * d(3) | 
| 811 | < | tau_Temp(7) = tau_Temp(7) + fz * d(1) | 
| 812 | < | tau_Temp(8) = tau_Temp(8) + fz * d(2) | 
| 813 | < | tau_Temp(9) = tau_Temp(9) + fz * d(3) | 
| 805 | > |  | 
| 806 | > |  | 
| 807 | > |  | 
| 808 | > | tau_Temp(1) = tau_Temp(1) - d(1) * fx | 
| 809 | > | tau_Temp(2) = tau_Temp(2) - d(1) * fy | 
| 810 | > | tau_Temp(3) = tau_Temp(3) - d(1) * fz | 
| 811 | > | tau_Temp(4) = tau_Temp(4) - d(2) * fx | 
| 812 | > | tau_Temp(5) = tau_Temp(5) - d(2) * fy | 
| 813 | > | tau_Temp(6) = tau_Temp(6) - d(2) * fz | 
| 814 | > | tau_Temp(7) = tau_Temp(7) - d(3) * fx | 
| 815 | > | tau_Temp(8) = tau_Temp(8) - d(3) * fy | 
| 816 | > | tau_Temp(9) = tau_Temp(9) - d(3) * fz | 
| 817 | > |  | 
| 818 |  | virial_Temp = virial_Temp + & | 
| 819 |  | (tau_Temp(1) + tau_Temp(5) + tau_Temp(9)) | 
| 820 |  |  | 
| 821 |  | endif | 
| 822 | < | endif | 
| 663 | < |  | 
| 822 | > | endif | 
| 823 |  | endif | 
| 824 |  |  | 
| 825 | < |  | 
| 826 | < | end subroutine calc_eam_pair | 
| 668 | < |  | 
| 669 | < | !!$subroutine calc_eam_rho(r, rho, drho, d2rho, atype) | 
| 670 | < | !!$ | 
| 671 | < | !!$  !  include 'headers/sizes.h' | 
| 672 | < | !!$ | 
| 673 | < | !!$ | 
| 674 | < | !!$integer atype, etype, number_r | 
| 675 | < | !!$real( kind = DP )  :: r, rho, drho, d2rho | 
| 676 | < | !!$integer :: i | 
| 677 | < | !!$ | 
| 678 | < | !!$ | 
| 679 | < | !!$etype = eam_atype_map(atype) | 
| 680 | < | !!$ | 
| 681 | < | !!$if (r.lt.eam_rcut(etype)) then | 
| 682 | < | !!$number_r = eam_nr(etype) | 
| 683 | < | !!$call eam_splint(etype, number_r, eam_rvals, eam_rho_r, & | 
| 684 | < | !!$   eam_rho_r_pp, r, rho, drho, d2rho) | 
| 685 | < | !!$else | 
| 686 | < | !!$rho = 0.0E0_DP | 
| 687 | < | !!$drho = 0.0E0_DP | 
| 688 | < | !!$d2rho = 0.0E0_DP | 
| 689 | < | !!$endif | 
| 690 | < | !!$ | 
| 691 | < | !!$return | 
| 692 | < | !!$end subroutine calc_eam_rho | 
| 693 | < | !!$ | 
| 694 | < | !!$subroutine calc_eam_frho(dens, u, u1, u2, atype) | 
| 695 | < | !!$ | 
| 696 | < | !!$  ! include 'headers/sizes.h' | 
| 697 | < | !!$ | 
| 698 | < | !!$integer atype, etype, number_rho | 
| 699 | < | !!$real( kind = DP ) :: dens, u, u1, u2 | 
| 700 | < | !!$real( kind = DP ) :: rho_vals | 
| 701 | < | !!$ | 
| 702 | < | !!$etype = eam_atype_map(atype) | 
| 703 | < | !!$number_rho = eam_nrho(etype) | 
| 704 | < | !!$if (dens.lt.eam_rhovals(number_rho, etype)) then | 
| 705 | < | !!$call eam_splint(etype, number_rho, eam_rhovals, eam_f_rho, & | 
| 706 | < | !!$   eam_f_rho_pp, dens, u, u1, u2) | 
| 707 | < | !!$else | 
| 708 | < | !!$rho_vals = eam_rhovals(number_rho,etype) | 
| 709 | < | !!$call eam_splint(etype, number_rho, eam_rhovals, eam_f_rho, & | 
| 710 | < | !!$   eam_f_rho_pp, rho_vals, u, u1, u2) | 
| 711 | < | !!$endif | 
| 712 | < | !!$ | 
| 713 | < | !!$return | 
| 714 | < | !!$end subroutine calc_eam_frho | 
| 715 | < | !!$ | 
| 716 | < | !!$subroutine calc_eam_phi(r, phi, dphi, d2phi, atype) | 
| 717 | < | !!$ | 
| 718 | < | !!$ | 
| 719 | < | !!$ | 
| 720 | < | !!$ | 
| 721 | < | !!$integer atype, etype, number_r | 
| 722 | < | !!$real( kind = DP ) :: r, phi, dphi, d2phi | 
| 723 | < | !!$ | 
| 724 | < | !!$etype = eam_atype_map(atype) | 
| 725 | < | !!$ | 
| 726 | < | !!$if (r.lt.eam_rcut(etype)) then | 
| 727 | < | !!$number_r = eam_nr(etype) | 
| 728 | < | !!$call eam_splint(etype, number_r, eam_rvals, eam_phi_r, & | 
| 729 | < | !!$   eam_phi_r_pp, r, phi, dphi, d2phi) | 
| 730 | < | !!$else | 
| 731 | < | !!$phi = 0.0E0_DP | 
| 732 | < | !!$dphi = 0.0E0_DP | 
| 733 | < | !!$d2phi = 0.0E0_DP | 
| 734 | < | !!$endif | 
| 735 | < | !!$ | 
| 736 | < | !!$return | 
| 737 | < | !!$end subroutine calc_eam_phi | 
| 825 | > |  | 
| 826 | > | end subroutine do_eam_pair | 
| 827 |  |  | 
| 828 |  |  | 
| 829 |  | subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y) | 
| 830 |  |  | 
| 742 | – |  | 
| 831 |  | integer :: atype, nx, j | 
| 832 |  | real( kind = DP ), dimension(:) :: xa | 
| 833 |  | real( kind = DP ), dimension(:) :: ya | 
| 834 |  | real( kind = DP ), dimension(:) :: yppa | 
| 835 | < | real( kind = DP ) :: x, y, dy, d2y | 
| 835 | > | real( kind = DP ) :: x, y | 
| 836 | > | real( kind = DP ) :: dy, d2y | 
| 837 |  | real( kind = DP ) :: del, h, a, b, c, d | 
| 838 | + | integer :: pp_arraySize | 
| 839 |  |  | 
| 840 | < |  | 
| 751 | < |  | 
| 752 | < |  | 
| 753 | < |  | 
| 840 | > |  | 
| 841 |  | ! this spline code assumes that the x points are equally spaced | 
| 842 |  | ! do not attempt to use this code if they are not. | 
| 843 |  |  | 
| 844 |  |  | 
| 845 |  | ! find the closest point with a value below our own: | 
| 846 | < | j = FLOOR(dble(nx-1) * (x - xa(1)) / (xa(nx) - xa(1))) + 1 | 
| 846 | > | j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1 | 
| 847 |  |  | 
| 848 |  | ! check to make sure we're inside the spline range: | 
| 849 |  | if ((j.gt.nx).or.(j.lt.1)) then | 
| 850 | < | write(default_error,*) "EAM_splint: x is outside bounds of spline" | 
| 850 | > | write(errMSG,*) "EAM_splint: x is outside bounds of spline" | 
| 851 | > | call handleError(routineName,errMSG) | 
| 852 |  | endif | 
| 853 |  | ! check to make sure we haven't screwed up the calculation of j: | 
| 854 |  | if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then | 
| 855 |  | if (j.ne.nx) then | 
| 856 | < | write(default_error,*) "EAM_splint: x is outside bounding range" | 
| 856 | > | write(errMSG,*) "EAM_splint:",x," x is outside bounding range" | 
| 857 | > | call handleError(routineName,errMSG) | 
| 858 |  | endif | 
| 859 |  | endif | 
| 860 |  |  | 
| 867 |  | d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP | 
| 868 |  |  | 
| 869 |  | y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1) | 
| 870 | < |  | 
| 871 | < | dy = (ya(j+1)-ya(j))/h & | 
| 872 | < | - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP & | 
| 873 | < | + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP | 
| 874 | < |  | 
| 875 | < | d2y = a*yppa(j) + b*yppa(j+1) | 
| 870 | > |  | 
| 871 | > | dy = (ya(j+1)-ya(j))/h & | 
| 872 | > | - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP & | 
| 873 | > | + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP | 
| 874 | > |  | 
| 875 | > |  | 
| 876 | > | d2y = a*yppa(j) + b*yppa(j+1) | 
| 877 | > |  | 
| 878 |  |  | 
| 879 |  | end subroutine eam_splint | 
| 880 |  |  | 
| 881 | + |  | 
| 882 |  | subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary) | 
| 883 |  |  | 
| 792 | – |  | 
| 884 |  |  | 
| 794 | – |  | 
| 885 |  | ! yp1 and ypn are the first derivatives of y at the two endpoints | 
| 886 |  | ! if boundary is 'L' the lower derivative is used | 
| 887 |  | ! if boundary is 'U' the upper derivative is used | 
| 895 |  | real( kind = DP ), dimension(:)        :: yppa | 
| 896 |  | real( kind = DP ), dimension(size(xa)) :: u | 
| 897 |  | real( kind = DP ) :: yp1,ypn,un,qn,sig,p | 
| 898 | < | character boundary | 
| 898 | > | character(len=*) :: boundary | 
| 899 |  |  | 
| 900 | < |  | 
| 900 | > | ! make sure the sizes match | 
| 901 | > | if ((nx /= size(xa)) .or. (nx /= size(ya))) then | 
| 902 | > | call handleWarning("EAM_SPLINE","Array size mismatch") | 
| 903 | > | end if | 
| 904 | > |  | 
| 905 |  | if ((boundary.eq.'l').or.(boundary.eq.'L').or. & | 
| 906 |  | (boundary.eq.'b').or.(boundary.eq.'B')) then | 
| 907 |  | yppa(1) = -0.5E0_DP |