bond_geomgrad Subroutine

public subroutine bond_geomgrad(bds, grad)

Uses

  • proc~~bond_geomgrad~~UsesGraph proc~bond_geomgrad bond_geomgrad module~mod_jacobian_mat mod_jacobian_mat proc~bond_geomgrad->module~mod_jacobian_mat module~mod_constants mod_constants proc~bond_geomgrad->module~mod_constants module~mod_memory mod_memory module~mod_jacobian_mat->module~mod_memory iso_c_binding iso_c_binding module~mod_constants->iso_c_binding module~mod_memory->module~mod_constants module~mod_memory->iso_c_binding module~mod_io mod_io module~mod_memory->module~mod_io module~mod_io->module~mod_constants

Arguments

Type IntentOptional Attributes Name
type(ommp_bonded_type), intent(in) :: bds

Bonded potential data structure

real(kind=rp), intent(inout) :: grad(3,bds%top%mm_atoms)

Gradients of bond stretching terms of potential energy


Calls

proc~~bond_geomgrad~~CallsGraph proc~bond_geomgrad bond_geomgrad proc~rij_jacobian Rij_jacobian proc~bond_geomgrad->proc~rij_jacobian

Called by

proc~~bond_geomgrad~~CalledByGraph proc~bond_geomgrad bond_geomgrad proc~link_atom_bond_geomgrad link_atom_bond_geomgrad proc~link_atom_bond_geomgrad->proc~bond_geomgrad proc~ommp_bond_geomgrad ommp_bond_geomgrad proc~ommp_bond_geomgrad->proc~bond_geomgrad proc~ommp_bond_geomgrad->proc~link_atom_bond_geomgrad proc~ommp_full_bnd_geomgrad ommp_full_bnd_geomgrad proc~ommp_full_bnd_geomgrad->proc~bond_geomgrad proc~ommp_full_bnd_geomgrad->proc~link_atom_bond_geomgrad proc~qm_helper_link_atom_geomgrad qm_helper_link_atom_geomgrad proc~qm_helper_link_atom_geomgrad->proc~link_atom_bond_geomgrad proc~c_ommp_full_bnd_geomgrad C_ommp_full_bnd_geomgrad proc~c_ommp_full_bnd_geomgrad->proc~ommp_full_bnd_geomgrad proc~c_ommp_bond_geomgrad C_ommp_bond_geomgrad proc~c_ommp_bond_geomgrad->proc~ommp_bond_geomgrad proc~ommp_full_geomgrad ommp_full_geomgrad proc~ommp_full_geomgrad->proc~ommp_full_bnd_geomgrad proc~ommp_qm_helper_link_atom_geomgrad ommp_qm_helper_link_atom_geomgrad proc~ommp_qm_helper_link_atom_geomgrad->proc~qm_helper_link_atom_geomgrad proc~ommptest_totalqmmm_geomgrad ommptest_totalqmmm_geomgrad proc~ommptest_totalqmmm_geomgrad->proc~ommp_full_geomgrad proc~ommptest_totalqmmm_geomgrad->proc~ommp_qm_helper_link_atom_geomgrad proc~ommptest_fakeqm_internal_geomgrad ommptest_fakeqm_internal_geomgrad proc~ommptest_fakeqm_internal_geomgrad->proc~ommp_full_geomgrad proc~c_ommp_full_geomgrad C_ommp_full_geomgrad proc~c_ommp_full_geomgrad->proc~ommp_full_geomgrad proc~ommptest_fakeqm_linkatom_geomgrad ommptest_fakeqm_linkatom_geomgrad proc~ommptest_fakeqm_linkatom_geomgrad->proc~ommp_full_geomgrad proc~ommptest_fakeqm_linkatom_geomgrad->proc~ommp_qm_helper_link_atom_geomgrad proc~c_ommp_qm_helper_link_atom_geomgrad C_ommp_qm_helper_link_atom_geomgrad proc~c_ommp_qm_helper_link_atom_geomgrad->proc~ommp_qm_helper_link_atom_geomgrad

Contents

Source Code


Source Code

    subroutine bond_geomgrad(bds, grad)
        use mod_constants, only : eps_rp
        use mod_jacobian_mat, only: Rij_jacobian

        implicit none

        type(ommp_bonded_type), intent(in) :: bds
        !! Bonded potential data structure
        real(rp), intent(inout) :: grad(3,bds%top%mm_atoms)
        !! Gradients of bond stretching terms of potential energy

        integer :: i, ia, ib
        logical(lp) :: use_cubic, use_quartic
        logical :: sk_a, sk_b
        real(rp) :: ca(3), cb(3), J_a(3), J_b(3), l, dl, g

        use_cubic = (abs(bds%bond_cubic) > eps_rp)
        use_quartic = (abs(bds%bond_quartic) > eps_rp)

        if(.not. bds%use_bond) return

        if(.not. use_cubic .and. .not. use_quartic) then
            ! This is just a regular harmonic potential
            !$omp parallel do default(shared) schedule(dynamic) & 
            !$omp private(i,ia,ib,sk_a,sk_b,ca,cb,dl,l,g,J_a,J_b) 
            do i=1, bds%nbond
                ia = bds%bondat(1,i)
                ib = bds%bondat(2,i)

                if(bds%top%use_frozen) then
                    sk_a = bds%top%frozen(ia)
                    sk_b = bds%top%frozen(ib)
                    if(sk_a .and. sk_b) cycle
                else
                    sk_a = .false.
                    sk_b = .false.
                end if

                ca = bds%top%cmm(:,ia)
                cb = bds%top%cmm(:,ib)

                call Rij_jacobian(ca, cb, l, J_a, J_b)
                dl = l - bds%l0bond(i)

                g = 2 * bds%kbond(i) * dl
                
                if(.not. sk_a) then
                    !$omp atomic update
                    grad(1,ia) = grad(1,ia) + J_a(1) * g
                    !$omp atomic update
                    grad(2,ia) = grad(2,ia) + J_a(2) * g
                    !$omp atomic update
                    grad(3,ia) = grad(3,ia) + J_a(3) * g
                end if

                if(.not. sk_b) then
                    !$omp atomic update
                    grad(1,ib) = grad(1,ib) + J_b(1) * g
                    !$omp atomic update
                    grad(2,ib) = grad(2,ib) + J_b(2) * g
                    !$omp atomic update
                    grad(3,ib) = grad(3,ib) + J_b(3) * g
                end if
            end do
        else
            !$omp parallel do default(shared) schedule(dynamic) & 
            !$omp private(i,ia,ib,sk_a,sk_b,ca,cb,dl,l,g,J_a,J_b) 
            do i=1, bds%nbond
                ia = bds%bondat(1,i)
                ib = bds%bondat(2,i)

                if(bds%top%use_frozen) then
                    sk_a = bds%top%frozen(ia)
                    sk_b = bds%top%frozen(ib)
                    if(sk_a .and. sk_b) cycle
                else
                    sk_a = .false.
                    sk_b = .false.
                end if

                ca = bds%top%cmm(:,ia)
                cb = bds%top%cmm(:,ib)

                call Rij_jacobian(ca, cb, l, J_a, J_b)
                dl = l - bds%l0bond(i)

                g = 2 * bds%kbond(i) * dl * (1.0_rp + 3.0/2.0*bds%bond_cubic*dl &
                                             + 2.0*bds%bond_quartic*dl**2)
                
                if(.not. sk_a) then
                    !$omp atomic update
                    grad(1,ia) = grad(1,ia) + J_a(1) * g
                    !$omp atomic update
                    grad(2,ia) = grad(2,ia) + J_a(2) * g
                    !$omp atomic update
                    grad(3,ia) = grad(3,ia) + J_a(3) * g
                end if

                if(.not. sk_b) then
                    !$omp atomic update
                    grad(1,ib) = grad(1,ib) + J_b(1) * g
                    !$omp atomic update
                    grad(2,ib) = grad(2,ib) + J_b(2) * g
                    !$omp atomic update
                    grad(3,ib) = grad(3,ib) + J_b(3) * g
                end if
            end do
        end if

    end subroutine bond_geomgrad