assign_opb Subroutine

public subroutine assign_opb(bds, prm_buf)

Uses

  • proc~~assign_opb~~UsesGraph proc~assign_opb assign_opb module~mod_bonded mod_bonded proc~assign_opb->module~mod_bonded module~mod_constants mod_constants proc~assign_opb->module~mod_constants module~mod_memory mod_memory proc~assign_opb->module~mod_memory module~mod_bonded->module~mod_memory module~mod_topology mod_topology module~mod_bonded->module~mod_topology module~mod_io mod_io module~mod_bonded->module~mod_io 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_memory->module~mod_io module~mod_topology->module~mod_memory module~mod_adjacency_mat mod_adjacency_mat module~mod_topology->module~mod_adjacency_mat module~mod_io->module~mod_constants module~mod_adjacency_mat->module~mod_memory

Arguments

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

Bonded potential data structure

character(len=OMMP_STR_CHAR_MAX), intent(in) :: prm_buf(:)

Calls

proc~~assign_opb~~CallsGraph proc~assign_opb assign_opb proc~read_atom_cards read_atom_cards proc~assign_opb->proc~read_atom_cards interface~mallocate mallocate proc~assign_opb->interface~mallocate proc~tokenize tokenize proc~assign_opb->proc~tokenize proc~isreal isreal proc~assign_opb->proc~isreal proc~fatal_error fatal_error proc~assign_opb->proc~fatal_error proc~isint isint proc~assign_opb->proc~isint proc~opb_init opb_init proc~assign_opb->proc~opb_init interface~mfree mfree proc~assign_opb->interface~mfree proc~read_atom_cards->interface~mallocate proc~read_atom_cards->proc~tokenize proc~read_atom_cards->proc~fatal_error proc~read_atom_cards->proc~isint proc~read_atom_cards->interface~mfree proc~count_substr_occurence count_substr_occurence proc~read_atom_cards->proc~count_substr_occurence proc~i_alloc1 i_alloc1 interface~mallocate->proc~i_alloc1 proc~i_alloc3 i_alloc3 interface~mallocate->proc~i_alloc3 proc~l_alloc2 l_alloc2 interface~mallocate->proc~l_alloc2 proc~r_alloc3 r_alloc3 interface~mallocate->proc~r_alloc3 proc~i_alloc2 i_alloc2 interface~mallocate->proc~i_alloc2 proc~r_alloc1 r_alloc1 interface~mallocate->proc~r_alloc1 proc~r_alloc2 r_alloc2 interface~mallocate->proc~r_alloc2 proc~l_alloc1 l_alloc1 interface~mallocate->proc~l_alloc1 proc~ommp_message ommp_message proc~fatal_error->proc~ommp_message proc~close_output close_output proc~fatal_error->proc~close_output proc~opb_init->interface~mallocate proc~opb_init->proc~fatal_error proc~opb_init->proc~ommp_message proc~l_free1 l_free1 interface~mfree->proc~l_free1 proc~i_free2 i_free2 interface~mfree->proc~i_free2 proc~r_free3 r_free3 interface~mfree->proc~r_free3 proc~r_free2 r_free2 interface~mfree->proc~r_free2 proc~i_free1 i_free1 interface~mfree->proc~i_free1 proc~r_free1 r_free1 interface~mfree->proc~r_free1 proc~l_free2 l_free2 interface~mfree->proc~l_free2 proc~i_free3 i_free3 interface~mfree->proc~i_free3 proc~chk_free chk_free proc~l_free1->proc~chk_free proc~i_free2->proc~chk_free proc~r_free3->proc~chk_free proc~chk_alloc chk_alloc proc~i_alloc1->proc~chk_alloc proc~memory_init memory_init proc~i_alloc1->proc~memory_init proc~i_alloc3->proc~chk_alloc proc~i_alloc3->proc~memory_init proc~l_alloc2->proc~chk_alloc proc~l_alloc2->proc~memory_init proc~r_free2->proc~chk_free proc~close_output->proc~ommp_message proc~i_free1->proc~chk_free proc~r_free1->proc~chk_free proc~r_alloc3->proc~chk_alloc proc~r_alloc3->proc~memory_init proc~i_alloc2->proc~chk_alloc proc~i_alloc2->proc~memory_init proc~r_alloc1->proc~chk_alloc proc~r_alloc1->proc~memory_init proc~r_alloc2->proc~chk_alloc proc~r_alloc2->proc~memory_init proc~l_alloc1->proc~chk_alloc proc~l_alloc1->proc~memory_init proc~l_free2->proc~chk_free proc~i_free3->proc~chk_free proc~chk_free->proc~fatal_error proc~chk_alloc->proc~fatal_error

Called by

proc~~assign_opb~~CalledByGraph proc~assign_opb assign_opb proc~mmpol_init_from_xyz mmpol_init_from_xyz proc~mmpol_init_from_xyz->proc~assign_opb proc~ommp_system_from_qm_helper ommp_system_from_qm_helper proc~ommp_system_from_qm_helper->proc~assign_opb proc~ommp_init_xyz ommp_init_xyz proc~ommp_init_xyz->proc~mmpol_init_from_xyz proc~c_ommp_system_from_qm_helper C_ommp_system_from_qm_helper proc~c_ommp_system_from_qm_helper->proc~ommp_system_from_qm_helper proc~c_ommp_init_xyz C_ommp_init_xyz proc~c_ommp_init_xyz->proc~ommp_init_xyz

Contents

Source Code


Source Code

    subroutine assign_opb(bds, prm_buf)
        use mod_memory, only: mallocate, mfree
        use mod_bonded, only: opb_init

        use mod_constants, only: kcalmol2au, rad2deg
        
        implicit none
        
        type(ommp_bonded_type), intent(inout) :: bds
        !! Bonded potential data structure
        character(len=OMMP_STR_CHAR_MAX), intent(in) :: prm_buf(:)

        integer(ip) :: il, i, tokb, toke, iopb, nopb, &
                       cla, clb, clc, cld, maxopb, a, b, c, d, jc, jb, iprm
        character(len=OMMP_STR_CHAR_MAX) :: line, errstring, opb_type
        integer(ip), allocatable :: classa(:), classb(:), classc(:), & 
                                    classd(:), tmpat(:,:)
        real(rp), allocatable :: kopbend(:), tmpk(:)
        type(ommp_topology_type), pointer :: top

        top => bds%top

        if(.not. top%atclass_initialized .or. .not. top%atz_initialized) then
            call read_atom_cards(top, prm_buf)
        end if

        ! Tinker manual default
        opb_type = "w-d-c"
        
        ! Read all the lines of file just to count how large vector should be 
        ! allocated
        nopb = 0
        do il=1, size(prm_buf) 
            line = prm_buf(il)
            if(line(:7) == 'opbend ') nopb = nopb + 1
        end do


        if(nopb == 0) then
           ! If there are no OPB terms, just stop here.
           return     
        end if
        maxopb = top%mm_atoms*3
        call mallocate('assign_opb [classa]', nopb, classa)
        call mallocate('assign_opb [classb]', nopb, classb)
        call mallocate('assign_opb [classc]', nopb, classc)
        call mallocate('assign_opb [classd]', nopb, classd)
        call mallocate('assign_opb [kopbend]', nopb, kopbend)
        call mallocate('assign_opb [tmpat]', 4_ip, maxopb, tmpat)
        call mallocate('assign_opb [tmpk]', maxopb, tmpk)

        ! Restart the reading from the beginning to actually save the parameters
        iopb = 1
        i=1
        do il=1, size(prm_buf) 
            line = prm_buf(il)
           
            if(line(:11) == 'opbendtype ') then
                tokb = 12
                toke = tokenize(line, tokb)
                read(line(tokb:toke), *) opb_type
            
            else if(line(:13) == 'opbend-cubic ') then
                tokb = 14
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND-CUBIC card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) bds%opb_cubic
                bds%opb_cubic = bds%opb_cubic * rad2deg
            
            else if(line(:15) == 'opbend-quartic ') then
                tokb = 16
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND-QUARTIC card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) bds%opb_quartic
                bds%opb_quartic = bds%opb_quartic * rad2deg**2
            
            else if(line(:14) == 'opbend-pentic ') then
                tokb = 15
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND-PENTIC card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) bds%opb_pentic
                bds%opb_pentic = bds%opb_pentic * rad2deg**3
            
            else if(line(:14) == 'opbend-sextic ') then
                tokb = 15
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND-SEXTIC card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) bds%opb_sextic
                bds%opb_sextic = bds%opb_sextic * rad2deg**4
            
            else if(line(:7) == 'opbend ') then
                tokb = 8
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classa(iopb)

                tokb = toke + 1
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classb(iopb)
                
                tokb = toke + 1
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classc(iopb)
                
                tokb = toke + 1
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classd(iopb)

                tokb = toke + 1
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong OPBEND card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) kopbend(iopb)
                
                iopb = iopb + 1
            end if
            i = i+1
        end do
       
        iopb = 1
        do a=1, top%mm_atoms
            ! Check if the center is trigonal
            if(top%conn(1)%ri(a+1) - top%conn(1)%ri(a) /= 3) cycle
            cla = top%atclass(a)
            ! Loop over the atoms connected to the trignonal center
            do jb=top%conn(1)%ri(a), top%conn(1)%ri(a+1)-1
                b = top%conn(1)%ci(jb)
                clb = top%atclass(b)
              
                c = -1
                d = -1
                clc = 0
                cld = 0
                do jc=top%conn(1)%ri(a), top%conn(1)%ri(a+1)-1
                    if(top%conn(1)%ci(jc) == b) cycle
                    if(c < 0) then
                        c = top%conn(1)%ci(jc)
                        clc = top%atclass(c)
                    else if(d < 0) then
                        d = top%conn(1)%ci(jc)
                        cld = top%atclass(d)
                    end if
                end do

                do iprm=1, nopb
                    if((classa(iprm) == clb) .and. &
                       (classb(iprm) == cla) .and. &
                       ((classc(iprm) == clc .and. & 
                         classd(iprm) == cld) .or. &
                        (classd(iprm) == clc .and. &
                         classc(iprm) == cld) .or. &
                        (classd(iprm) == 0 .and. &
                         (classc(iprm) == cld .or. classc(iprm) == clc)) .or. &
                        (classc(iprm) == 0 .and. &
                         (classd(iprm) == cld .or. classd(iprm) == clc)) .or. &
                        (classc(iprm) == 0 .or. classd(iprm) == 0))) then
                        ! The parameter is ok
                        tmpat(1,iopb) = a
                        tmpat(2,iopb) = b
                        tmpat(3,iopb) = c
                        tmpat(4,iopb) = d
                        tmpk(iopb) = kopbend(iprm)
                        iopb = iopb + 1
                        exit
                    endif
                end do
            end do
        end do

        call opb_init(bds, iopb-1, trim(opb_type))
        
        do i=1, iopb-1
            bds%kopb(i) = tmpk(i) * kcalmol2au
            bds%opbat(:,i) = tmpat(:,i)
        end do

        call mfree('assign_opb [classa]', classa)
        call mfree('assign_opb [classb]', classb)
        call mfree('assign_opb [classc]', classc)
        call mfree('assign_opb [classd]', classd)
        call mfree('assign_opb [kopbend]', kopbend)
        call mfree('assign_opb [tmpat]', tmpat)
        call mfree('assign_opb [tmpk]', tmpk)
    
    end subroutine assign_opb