assign_imptorsion Subroutine

public subroutine assign_imptorsion(bds, prm_buf)

Uses

  • proc~~assign_imptorsion~~UsesGraph proc~assign_imptorsion assign_imptorsion module~mod_bonded mod_bonded proc~assign_imptorsion->module~mod_bonded module~mod_constants mod_constants proc~assign_imptorsion->module~mod_constants module~mod_memory mod_memory proc~assign_imptorsion->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_imptorsion~~CallsGraph proc~assign_imptorsion assign_imptorsion proc~read_atom_cards read_atom_cards proc~assign_imptorsion->proc~read_atom_cards interface~mallocate mallocate proc~assign_imptorsion->interface~mallocate proc~tokenize tokenize proc~assign_imptorsion->proc~tokenize proc~isreal isreal proc~assign_imptorsion->proc~isreal proc~fatal_error fatal_error proc~assign_imptorsion->proc~fatal_error proc~isint isint proc~assign_imptorsion->proc~isint proc~imptorsion_init imptorsion_init proc~assign_imptorsion->proc~imptorsion_init interface~mfree mfree proc~assign_imptorsion->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~imptorsion_init->interface~mallocate 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_imptorsion~~CalledByGraph proc~assign_imptorsion assign_imptorsion proc~mmpol_init_from_xyz mmpol_init_from_xyz proc~mmpol_init_from_xyz->proc~assign_imptorsion proc~ommp_system_from_qm_helper ommp_system_from_qm_helper proc~ommp_system_from_qm_helper->proc~assign_imptorsion 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_imptorsion(bds, prm_buf)
        use mod_memory, only: mallocate, mfree
        use mod_bonded, only: imptorsion_init
        use mod_constants, only: kcalmol2au, deg2rad, eps_rp
        
        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, j, tokb, toke, it, nt, &
                       cla, clb, clc, cld, maxt, a, b, c, d, jb, jc, jd, iprm, ji, period
        character(len=OMMP_STR_CHAR_MAX) :: line, errstring
        integer(ip), allocatable :: classa(:), classb(:), classc(:), classd(:), &
                                    t_n(:,:), tmpat(:,:), tmpprm(:)
        real(rp), allocatable :: t_amp(:,:), t_pha(:,:)
        real(rp) :: amp, phase, imptorsion_unit = 1.0
        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
        
        ! Read all the lines of file just to count how large vector should be 
        ! allocated
        nt = 1
        do il=1, size(prm_buf) 
            line = prm_buf(il)
            if(line(:8) == 'imptors ') nt = nt + 1
        end do

        maxt = top%conn(4)%ri(top%mm_atoms+1)-1 
        call mallocate('assign_imptorsion [classa]', nt, classa)
        call mallocate('assign_imptorsion [classb]', nt, classb)
        call mallocate('assign_imptorsion [classc]', nt, classc)
        call mallocate('assign_imptorsion [classd]', nt, classd)
        call mallocate('assign_imptorsion [t_amp]', 3_ip, nt, t_amp)
        call mallocate('assign_imptorsion [t_pha]', 3_ip, nt, t_pha)
        call mallocate('assign_imptorsion [t_n]', 3_ip, nt, t_n)
        call mallocate('assign_imptorsion [tmpat]', 4_ip, maxt, tmpat)
        call mallocate('assign_imptorsion [tmpprm]', maxt, tmpprm)
        t_amp = 0.0
        t_pha = 0.0
        t_n = 1
        ! Restart the reading from the beginning to actually save the parameters
        it = 1
        i=1
        do il=1, size(prm_buf) 
            line = prm_buf(il)
                              
            if(line(:12) == 'imptorsunit ') then
                tokb = 13
                toke = tokenize(line, tokb)
                if(.not. isreal(line(tokb:toke))) then
                    write(errstring, *) "Wrong IMPTORSUNIT card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) imptorsion_unit

            else if(line(:8) == 'imptors ') then
                tokb = 9
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong IMPTORS card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classa(it)

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

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

                tokb = toke + 1
                toke = tokenize(line, tokb)
                if(.not. isint(line(tokb:toke))) then
                    write(errstring, *) "Wrong IMPTORS card"
                    call fatal_error(errstring)
                end if
                read(line(tokb:toke), *) classd(it)
                
                ji = 1
                t_n(:,it) = -1
                do j=1, 3
                    tokb = toke + 1
                    toke = tokenize(line, tokb)
                    if(toke < 0) exit

                    if(.not. isreal(line(tokb:toke))) then
                        write(errstring, *) "Wrong IMPTORS card"
                        call fatal_error(errstring)
                    end if
                    read(line(tokb:toke), *) amp
                    tokb = toke + 1
                    toke = tokenize(line, tokb)
                    if(.not. isreal(line(tokb:toke))) then
                        write(errstring, *) "Wrong IMPTORS card"
                        call fatal_error(errstring)
                    end if
                    read(line(tokb:toke), *) phase
                
                    tokb = toke + 1
                    toke = tokenize(line, tokb)
                    if(.not. isint(line(tokb:toke))) then
                        write(errstring, *) "Wrong IMPTORS card"
                        call fatal_error(errstring)
                    end if
                    read(line(tokb:toke), *) period

                    if(abs(amp) > eps_rp) then
                        t_amp(ji, it) = amp 
                        t_pha(ji, it) = phase
                        t_n(ji, it) = period
                        ji = ji + 1
                    end if
                end do

                if(j == 1) then
                    ! No parameter found
                    write(errstring, *) "Wrong IMPTORS card"
                    call fatal_error(errstring)
                end if
                
                it = it + 1
            end if
            i = i+1
        end do

        it = 1
        tmpat = 0
        
        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)
            
            jb=top%conn(1)%ri(a)
            b = top%conn(1)%ci(jb)
            clb = top%atclass(b)
            
            jc=top%conn(1)%ri(a)+1
            c = top%conn(1)%ci(jc)
            clc = top%atclass(c)
            
            jd=top%conn(1)%ri(a)+2
            d = top%conn(1)%ci(jd)
            cld = top%atclass(d)
              
            do iprm=1, nt
                if((classc(iprm) == cla)) then
                    if(clb == classa(iprm) .and. &
                       clc == classb(iprm) .and. &
                       cld == classd(iprm)) then
                        tmpat(1,it) = b
                        tmpat(2,it) = c
                        tmpat(3,it) = a
                        tmpat(4,it) = d
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                    if(clb == classa(iprm) .and. &
                            cld == classb(iprm) .and. &
                            clc == classd(iprm)) then
                        tmpat(1,it) = b
                        tmpat(2,it) = d
                        tmpat(3,it) = a
                        tmpat(4,it) = c
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                    if(clc == classa(iprm) .and. &
                            clb == classb(iprm) .and. &
                            cld == classd(iprm)) then
                        tmpat(1,it) = c
                        tmpat(2,it) = b
                        tmpat(3,it) = a
                        tmpat(4,it) = d
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                    if(clc == classa(iprm) .and. &
                            cld == classb(iprm) .and. &
                            clb == classd(iprm)) then
                        tmpat(1,it) = c
                        tmpat(2,it) = d
                        tmpat(3,it) = a
                        tmpat(4,it) = b
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                    if(cld == classa(iprm) .and. &
                            clb == classb(iprm) .and. &
                            clc == classd(iprm)) then
                        tmpat(1,it) = d
                        tmpat(2,it) = b
                        tmpat(3,it) = a
                        tmpat(4,it) = c
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                    if(cld == classa(iprm) .and. &
                            clc == classb(iprm) .and. &
                            clb == classd(iprm)) then
                        tmpat(1,it) = d
                        tmpat(2,it) = c
                        tmpat(3,it) = a
                        tmpat(4,it) = b
                        tmpprm(it) = iprm
                        it = it + 1
                    end if
                endif
            end do
        end do

        call imptorsion_init(bds, it-1)
        do i=1, it-1
           bds%imptorsionat(:,i) = tmpat(:,i) 
           bds%imptorsamp(:,i) = t_amp(:,tmpprm(i)) * kcalmol2au * imptorsion_unit
           ! If more than one parameter is used for the same trigonal center,
           ! then do an average
           bds%imptorsamp(:,i) = bds%imptorsamp(:,i) / count(tmpat(3,1:it-1) == tmpat(3,i))
           bds%imptorsphase(:,i) = t_pha(:,tmpprm(i)) * deg2rad
           bds%imptorsn(:,i) = t_n(:,tmpprm(i))
        end do
        
        call mfree('assign_imptorsion [classa]', classa)
        call mfree('assign_imptorsion [classb]', classb)
        call mfree('assign_imptorsion [classc]', classc)
        call mfree('assign_imptorsion [classd]', classd)
        call mfree('assign_imptorsion [t_amp]', t_amp)
        call mfree('assign_imptorsion [t_pha]', t_pha)
        call mfree('assign_imptorsion [t_n]', t_n)
        call mfree('assign_imptorsion [tmpat]', tmpat)
        call mfree('assign_imptorsion [tmpprm]', tmpprm)
       
    end subroutine assign_imptorsion