From 9ae79c8e98dcb1ebdf2ceeba08caa23c818c168b Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 01/57] First part about implementing transition states --- src/Fragment.f90 | 7 ------- src/FragmentsDB.f90 | 29 ++++++++++++++++++----------- src/Reactor.f90 | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Fragment.f90 b/src/Fragment.f90 index 513e4a4..f39cf10 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -389,15 +389,8 @@ end subroutine destroyFragment subroutine updateFormula( this ) class(Fragment) :: this - integer :: isLineal character(100), allocatable :: tokens(:) - if( this.isLineal() ) then - isLineal = 1 - else - isLineal = 0 - end if - this.dlabel_ = this.name call FString_split( this.name, tokens, "(" ) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index a62abaa..ee1834d 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -62,6 +62,7 @@ module FragmentsDB_ use StringIntegerMap_ use Fragment_ + use FragmentsList_ use ModelPotential_ use GOptionsM3C_ @@ -79,11 +80,11 @@ module FragmentsDB_ type(StringIntegerMap) :: forbiddenReactions logical :: useForbiddenReactionsDetails -! "C2(d1)+C(t1)-->C3(s1)" --> 5 --> transitionState(5) +! "C2(d1)+C(t1)-->C3(s1)" --> 5 . It means transitionState(5) ! |----------str2id_TS----------| type(Fragment), allocatable :: transitionState(:) type(StringIntegerMap) :: str2id_TS - logical, allocatable :: involvedInTS(:) ! One for each group. For speed purposes only. + logical, allocatable :: involvedInTS(:) ! One for each cluster. For speed purposes only. real(8), private :: energyReference_ logical, private :: useAtomicPotentials @@ -360,6 +361,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) character(100), allocatable :: tokens(:), tokens2(:), tokens3(:) real(8) :: rBuffer + ! Only for transition states. They are neccessary to calculate the right label (mass sorted) + type(FragmentsList) :: reactives + type(FragmentsList) :: products + if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -395,28 +400,28 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Choosing the reactives and products !------------------------------------------ if( size(tokens) >= 9 .and. this.transitionState(i).nAtoms() /= 1 ) then - call FString_split( trim(adjustl(tokens(9))), tokens2, "-->" ) + call FString_split( trim(adjustl(tokens(9))), tokens2, "<-->" ) - write(*,*) "Reactivos" call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) + call reactives.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + reactives.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do end do deallocate( tokens3 ) - write(*,*) "Productos" call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) + call products.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + products.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -425,8 +430,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens2 ) - write(*,*) "Agregado: ", FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), ">>", i - call this.str2id_TS.insert( FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), i ) + write(*,"(4X,A22,A)") "Path = ", trim(reactives.label())//"<-->"//trim(products.label()) + call this.str2id_TS.insert( FString_toString(trim(reactives.label())//"<-->"//trim(products.label())), i ) + call this.str2id_TS.insert( FString_toString(trim(products.label())//"<-->"//trim(reactives.label())), i ) + else call GOptions_error( & "Bad number of atoms in transition state (N=0)", & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index fe839c1..600948a 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -112,6 +112,7 @@ module Reactor_ procedure, private, NOPASS :: isSpinForbidden procedure, private, NOPASS :: reactorConstraint procedure, private, NOPASS :: reactionString + procedure, private, NOPASS :: reduceToTransitionStates procedure :: execute procedure :: executeMinFragmentationEnergy @@ -315,6 +316,11 @@ subroutine changeComposition( this, dNfrag ) maxIterForbidden = maxIterForbidden + 1 cycle else + + if( allocated(FragmentsDB_instance.transitionState) ) then + call reduceToTransitionStates( this.reactives, this.products ) + end if + exit end if @@ -464,6 +470,15 @@ function reactionString( reactives, products, details ) result( output ) output = trim(reactives.label( details=effDetails ))//"-->"//trim(products.label( details=effDetails )) end function reactionString + !> + !! @brief Replaces products for the corresponding transition states. Only composition is changed + !! + subroutine reduceToTransitionStates( reactives, products ) + type(FragmentsList), intent(in) :: reactives + type(FragmentsList), intent(inout) :: products + + end subroutine reduceToTransitionStates + !> !! @brief Change the composition of the system !! From 127e60378709a0e232752c0c2833893c029aea19 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 02/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 600948a..910d369 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -57,13 +57,13 @@ module Reactor_ use IOStream_ use Timer_ use UnitsConverter_ - use IVector_ use RandomUtils_ use StringList_ use AtomicElementsDB_ use BlocksIFileParser_ use RealHistogram_ use RealList_ + use IntegerVector_ use StringIntegerMap_ use StringRealMap_ use StringRealPair_ @@ -92,6 +92,9 @@ module Reactor_ type(FragmentsList) :: products logical :: state + type(FragmentsList) :: productsTS + logical :: replaceTS + character(3), private :: name integer, private :: type integer, allocatable :: dNFrag(:) @@ -318,7 +321,9 @@ subroutine changeComposition( this, dNfrag ) else if( allocated(FragmentsDB_instance.transitionState) ) then - call reduceToTransitionStates( this.reactives, this.products ) + call reduceToTransitionStates( this.reactives, this.products, this.productsTS ) + + if( this.productsTS.nMolecules() > 0 ) this.replaceTS = .true. end if exit @@ -473,10 +478,157 @@ end function reactionString !> !! @brief Replaces products for the corresponding transition states. Only composition is changed !! - subroutine reduceToTransitionStates( reactives, products ) + subroutine reduceToTransitionStates( reactives, products, productsTS ) type(FragmentsList), intent(in) :: reactives type(FragmentsList), intent(inout) :: products + type(FragmentsList), intent(out) :: productsTS + + integer :: i, j, id + integer :: ir, jr, kr + integer :: ip, jp, kp + type(IntegerVector) :: reactiveInTS + type(IntegerVector) :: productInTS + integer, allocatable :: reactiveInTScomb(:,:) + integer, allocatable :: productInTScomb(:,:) + integer :: nAtomsR, nAtomsP + integer :: massNumberR, massNumberP + type(FragmentsList) :: lReactives, lProducts + type(String) :: labelTS, label + logical :: locatedTS + + call reactiveInTS.init( resizeIncrement=reactives.nMolecules() ) + call productInTS.init( resizeIncrement=products.nMolecules() ) + + do i=1,reactives.nMolecules() + id = FragmentsDB_instance.getIdFromName( reactives.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call reactiveInTS.append( i ) + end if + end do + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -867,6 +1019,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -947,6 +1101,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From a9a625b1728d12d261608eadb2087a4e5dfde6ea Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 03/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 910d369..e3dd10b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -578,14 +578,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -593,8 +596,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1016,11 +1025,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 0664677f31e7427dd90e80500f2d165895bbb132 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 04/57] First version working with TS --- src/FragmentsDB.f90 | 1 + src/MarkovChain.f90 | 11 ++++++++--- src/Reactor.f90 | 35 ++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index ee1834d..3baaa84 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -377,6 +377,7 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) do i=1,size(transitionStatesTable) call this.transitionState(i).fromMassTableRow( transitionStatesTable(i).fstr, id=i, store=store.fstr ) + this.transitionState(i).isTransitionState = .true. call FString_split( transitionStatesTable(i).fstr, tokens, " " ) diff --git a/src/MarkovChain.f90 b/src/MarkovChain.f90 index a34d07c..2c8e433 100644 --- a/src/MarkovChain.f90 +++ b/src/MarkovChain.f90 @@ -442,7 +442,7 @@ subroutine run( this, reactives ) ! sBuffer = react.reactives.weightHistoryLine( origin ) ! end if ! end if - + call react.run() ! Si la energía cinetica es negativa @@ -483,7 +483,12 @@ subroutine run( this, reactives ) nTimesBlocked = 0 ! El bloqueo debe ser consecutivo, así que si no pasa por negative energy se cuenta nuevamente - Pi = react.products.LnW()-react.reactives.LnW() + if( react.replaceTS ) then + react.replaceTS = .false. + Pi = react.productsTS.LnW()-react.reactives.LnW() + else + Pi = react.products.LnW()-react.reactives.LnW() + end if if( Pi > 0.0_8 ) then if( trim(react.reactives.label( details=.false. )) /= trim(react.products.label( details=.false. )) ) then @@ -518,7 +523,7 @@ subroutine run( this, reactives ) sBuffer = trim(react.reactives.label( details=.true. ))//"-->"//trim(react.products.label( details=.true. )) call this.transitionDetHistogram.add( sBuffer ) end if - + react.reactives = react.products call GOptions_info( & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index e3dd10b..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -606,6 +606,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end if if( GOptions_debugLevel >= 2 ) then + write(*,*) " products = ", trim(products.label()) write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) end if @@ -1011,11 +1012,12 @@ subroutine run( this ) real(8) :: min_dLnW - integer :: n, nMin + integer :: nMin real(8) :: rBuffer type(String) :: sBuffer this.state = .true. + this.replaceTS = .false. call this.showReactorHeader() @@ -1025,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1039,16 +1039,37 @@ subroutine run( this ) ! call this.products.changeVibrationalEnergy() ! call this.products.changeGeometry() ! call this.products.changeOrientations() + + if( this.replaceTS ) then + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos + call this.productsTS.setReactorEnergy( this.reactives.reactorEnergy() ) + + ! Para que fuerce los centros aleatorios en la siguiente iteración + this.productsTS.forceRandomCenters = .true. + + ! Los productos utilizan parte de la energía + call this.productsTS.initialGuessFragmentsList() + +! write(*,*) "reactive ", trim(this.reactives.label()) +! write(*,*) "products ", trim(this.products.label()) +! write(*,*) "TS located ", trim(this.productsTS.label()) +! sBuffer = this.products.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) +! sBuffer = this.productsTS.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) + + end if case( VIBRATIONAL_REACTOR ) - + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía cinética en vibracional call this.products.changeVibrationalEnergy() - + case( TRANSLATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives @@ -1056,11 +1077,13 @@ subroutine run( this ) call this.products.changeGeometry() case( ROTATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía call this.products.changeOrientations() + end select if( GOptions_printLevel >= 2 ) then @@ -1110,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From 8d1b53a0cfb2b65a781b341c11761e81b38ed3ac Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:10:35 -0700 Subject: [PATCH 05/57] Version updated --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cd5ac03..2789166 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0 +2.1a From e7ea48b5b1d933daacbbf85e74a306ef3fdead59 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Thu, 28 Feb 2019 23:22:23 -0700 Subject: [PATCH 06/57] Gaussian template freqs updated to improve symmetry detection --- templates/b3lyp.freqs-GAUSSIAN.inp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/b3lyp.freqs-GAUSSIAN.inp b/templates/b3lyp.freqs-GAUSSIAN.inp index e8e1d55..0d144fa 100644 --- a/templates/b3lyp.freqs-GAUSSIAN.inp +++ b/templates/b3lyp.freqs-GAUSSIAN.inp @@ -1,4 +1,4 @@ -#p b3lyp/6-311++G(3df,2p) freq +#p b3lyp/6-311++G(3df,2p) freq IOp(2/17=3) IOp(2/18=3) b3lyp opt From 9755ba4201baf154da4e105158714155cdd043f5 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 3 Mar 2019 01:48:59 -0700 Subject: [PATCH 07/57] M3C.check now checks the right value of the multiplicity based on the stoichiometry and charge --- src/M3C.check | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/M3C.check b/src/M3C.check index 37c2f37..28fd605 100755 --- a/src/M3C.check +++ b/src/M3C.check @@ -146,8 +146,19 @@ function checkConsistence() kill $$ fi - if [[ ! "$multID" =~ ^m[1-9]+$ ]] + if [[ "$multID" =~ ^m[1-9]+$ ]] then + minMult=`molecule.minMult $ifile ${chargeID#q}` + + if [ ! "$multID" = "m$(($minMult+0))" -a ! "$multID" = "m$(($minMult+2))" \ + -a ! "$multID" = "m$(($minMult+4))" -a ! "$multID" = "m$(($minMult+6))" ] + then + echo "" + echo -n "### ERROR ### Inconsistency in multiplicity ( $multID --> " + echo "m$(($minMult+0)), m$(($minMult+2)), m$(($minMult+4)), or m$(($minMult+6)) ) )" + kill $$ + fi + else echo "" echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" kill $$ From 655336c80e694ecf7c977809fe148645a42e8c34 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 5 Mar 2019 20:46:53 -0700 Subject: [PATCH 08/57] oGaussian2rxyz bug fixed --- utils/oGaussian2rxyz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/oGaussian2rxyz.sh b/utils/oGaussian2rxyz.sh index 62be55e..b28e1a3 100755 --- a/utils/oGaussian2rxyz.sh +++ b/utils/oGaussian2rxyz.sh @@ -114,7 +114,7 @@ then echo "ELECTRONIC_STATE ??" else #group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` - group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}'` + group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}' | tail -n1` if [ "$group" = "Nop" -o "$group" = "NOp" ] then echo "SYMMETRY ??" From d2c7d410931f87774c0ccbf6af30e775a809b3f9 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 09/57] First part about implementing transition states --- src/Fragment.f90 | 7 ------- src/FragmentsDB.f90 | 29 ++++++++++++++++++----------- src/Reactor.f90 | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Fragment.f90 b/src/Fragment.f90 index 513e4a4..f39cf10 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -389,15 +389,8 @@ end subroutine destroyFragment subroutine updateFormula( this ) class(Fragment) :: this - integer :: isLineal character(100), allocatable :: tokens(:) - if( this.isLineal() ) then - isLineal = 1 - else - isLineal = 0 - end if - this.dlabel_ = this.name call FString_split( this.name, tokens, "(" ) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index a62abaa..ee1834d 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -62,6 +62,7 @@ module FragmentsDB_ use StringIntegerMap_ use Fragment_ + use FragmentsList_ use ModelPotential_ use GOptionsM3C_ @@ -79,11 +80,11 @@ module FragmentsDB_ type(StringIntegerMap) :: forbiddenReactions logical :: useForbiddenReactionsDetails -! "C2(d1)+C(t1)-->C3(s1)" --> 5 --> transitionState(5) +! "C2(d1)+C(t1)-->C3(s1)" --> 5 . It means transitionState(5) ! |----------str2id_TS----------| type(Fragment), allocatable :: transitionState(:) type(StringIntegerMap) :: str2id_TS - logical, allocatable :: involvedInTS(:) ! One for each group. For speed purposes only. + logical, allocatable :: involvedInTS(:) ! One for each cluster. For speed purposes only. real(8), private :: energyReference_ logical, private :: useAtomicPotentials @@ -360,6 +361,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) character(100), allocatable :: tokens(:), tokens2(:), tokens3(:) real(8) :: rBuffer + ! Only for transition states. They are neccessary to calculate the right label (mass sorted) + type(FragmentsList) :: reactives + type(FragmentsList) :: products + if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -395,28 +400,28 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Choosing the reactives and products !------------------------------------------ if( size(tokens) >= 9 .and. this.transitionState(i).nAtoms() /= 1 ) then - call FString_split( trim(adjustl(tokens(9))), tokens2, "-->" ) + call FString_split( trim(adjustl(tokens(9))), tokens2, "<-->" ) - write(*,*) "Reactivos" call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) + call reactives.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + reactives.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do end do deallocate( tokens3 ) - write(*,*) "Productos" call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) + call products.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + products.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -425,8 +430,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens2 ) - write(*,*) "Agregado: ", FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), ">>", i - call this.str2id_TS.insert( FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), i ) + write(*,"(4X,A22,A)") "Path = ", trim(reactives.label())//"<-->"//trim(products.label()) + call this.str2id_TS.insert( FString_toString(trim(reactives.label())//"<-->"//trim(products.label())), i ) + call this.str2id_TS.insert( FString_toString(trim(products.label())//"<-->"//trim(reactives.label())), i ) + else call GOptions_error( & "Bad number of atoms in transition state (N=0)", & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index fe839c1..600948a 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -112,6 +112,7 @@ module Reactor_ procedure, private, NOPASS :: isSpinForbidden procedure, private, NOPASS :: reactorConstraint procedure, private, NOPASS :: reactionString + procedure, private, NOPASS :: reduceToTransitionStates procedure :: execute procedure :: executeMinFragmentationEnergy @@ -315,6 +316,11 @@ subroutine changeComposition( this, dNfrag ) maxIterForbidden = maxIterForbidden + 1 cycle else + + if( allocated(FragmentsDB_instance.transitionState) ) then + call reduceToTransitionStates( this.reactives, this.products ) + end if + exit end if @@ -464,6 +470,15 @@ function reactionString( reactives, products, details ) result( output ) output = trim(reactives.label( details=effDetails ))//"-->"//trim(products.label( details=effDetails )) end function reactionString + !> + !! @brief Replaces products for the corresponding transition states. Only composition is changed + !! + subroutine reduceToTransitionStates( reactives, products ) + type(FragmentsList), intent(in) :: reactives + type(FragmentsList), intent(inout) :: products + + end subroutine reduceToTransitionStates + !> !! @brief Change the composition of the system !! From 8fdcc6045f8b94fb1dc104a30ed1064c7bbe7c23 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 10/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 600948a..910d369 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -57,13 +57,13 @@ module Reactor_ use IOStream_ use Timer_ use UnitsConverter_ - use IVector_ use RandomUtils_ use StringList_ use AtomicElementsDB_ use BlocksIFileParser_ use RealHistogram_ use RealList_ + use IntegerVector_ use StringIntegerMap_ use StringRealMap_ use StringRealPair_ @@ -92,6 +92,9 @@ module Reactor_ type(FragmentsList) :: products logical :: state + type(FragmentsList) :: productsTS + logical :: replaceTS + character(3), private :: name integer, private :: type integer, allocatable :: dNFrag(:) @@ -318,7 +321,9 @@ subroutine changeComposition( this, dNfrag ) else if( allocated(FragmentsDB_instance.transitionState) ) then - call reduceToTransitionStates( this.reactives, this.products ) + call reduceToTransitionStates( this.reactives, this.products, this.productsTS ) + + if( this.productsTS.nMolecules() > 0 ) this.replaceTS = .true. end if exit @@ -473,10 +478,157 @@ end function reactionString !> !! @brief Replaces products for the corresponding transition states. Only composition is changed !! - subroutine reduceToTransitionStates( reactives, products ) + subroutine reduceToTransitionStates( reactives, products, productsTS ) type(FragmentsList), intent(in) :: reactives type(FragmentsList), intent(inout) :: products + type(FragmentsList), intent(out) :: productsTS + + integer :: i, j, id + integer :: ir, jr, kr + integer :: ip, jp, kp + type(IntegerVector) :: reactiveInTS + type(IntegerVector) :: productInTS + integer, allocatable :: reactiveInTScomb(:,:) + integer, allocatable :: productInTScomb(:,:) + integer :: nAtomsR, nAtomsP + integer :: massNumberR, massNumberP + type(FragmentsList) :: lReactives, lProducts + type(String) :: labelTS, label + logical :: locatedTS + + call reactiveInTS.init( resizeIncrement=reactives.nMolecules() ) + call productInTS.init( resizeIncrement=products.nMolecules() ) + + do i=1,reactives.nMolecules() + id = FragmentsDB_instance.getIdFromName( reactives.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call reactiveInTS.append( i ) + end if + end do + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -867,6 +1019,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -947,6 +1101,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From ec3184353112fec3becc848576b1a2202a5ba8c5 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 11/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 910d369..e3dd10b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -578,14 +578,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -593,8 +596,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1016,11 +1025,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 5d1b6e75810b2fbe3e43d50979ab15558cdc1e35 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 12/57] First version working with TS --- src/FragmentsDB.f90 | 1 + src/MarkovChain.f90 | 11 ++++++++--- src/Reactor.f90 | 35 ++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index ee1834d..3baaa84 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -377,6 +377,7 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) do i=1,size(transitionStatesTable) call this.transitionState(i).fromMassTableRow( transitionStatesTable(i).fstr, id=i, store=store.fstr ) + this.transitionState(i).isTransitionState = .true. call FString_split( transitionStatesTable(i).fstr, tokens, " " ) diff --git a/src/MarkovChain.f90 b/src/MarkovChain.f90 index a34d07c..2c8e433 100644 --- a/src/MarkovChain.f90 +++ b/src/MarkovChain.f90 @@ -442,7 +442,7 @@ subroutine run( this, reactives ) ! sBuffer = react.reactives.weightHistoryLine( origin ) ! end if ! end if - + call react.run() ! Si la energía cinetica es negativa @@ -483,7 +483,12 @@ subroutine run( this, reactives ) nTimesBlocked = 0 ! El bloqueo debe ser consecutivo, así que si no pasa por negative energy se cuenta nuevamente - Pi = react.products.LnW()-react.reactives.LnW() + if( react.replaceTS ) then + react.replaceTS = .false. + Pi = react.productsTS.LnW()-react.reactives.LnW() + else + Pi = react.products.LnW()-react.reactives.LnW() + end if if( Pi > 0.0_8 ) then if( trim(react.reactives.label( details=.false. )) /= trim(react.products.label( details=.false. )) ) then @@ -518,7 +523,7 @@ subroutine run( this, reactives ) sBuffer = trim(react.reactives.label( details=.true. ))//"-->"//trim(react.products.label( details=.true. )) call this.transitionDetHistogram.add( sBuffer ) end if - + react.reactives = react.products call GOptions_info( & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index e3dd10b..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -606,6 +606,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end if if( GOptions_debugLevel >= 2 ) then + write(*,*) " products = ", trim(products.label()) write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) end if @@ -1011,11 +1012,12 @@ subroutine run( this ) real(8) :: min_dLnW - integer :: n, nMin + integer :: nMin real(8) :: rBuffer type(String) :: sBuffer this.state = .true. + this.replaceTS = .false. call this.showReactorHeader() @@ -1025,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1039,16 +1039,37 @@ subroutine run( this ) ! call this.products.changeVibrationalEnergy() ! call this.products.changeGeometry() ! call this.products.changeOrientations() + + if( this.replaceTS ) then + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos + call this.productsTS.setReactorEnergy( this.reactives.reactorEnergy() ) + + ! Para que fuerce los centros aleatorios en la siguiente iteración + this.productsTS.forceRandomCenters = .true. + + ! Los productos utilizan parte de la energía + call this.productsTS.initialGuessFragmentsList() + +! write(*,*) "reactive ", trim(this.reactives.label()) +! write(*,*) "products ", trim(this.products.label()) +! write(*,*) "TS located ", trim(this.productsTS.label()) +! sBuffer = this.products.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) +! sBuffer = this.productsTS.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) + + end if case( VIBRATIONAL_REACTOR ) - + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía cinética en vibracional call this.products.changeVibrationalEnergy() - + case( TRANSLATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives @@ -1056,11 +1077,13 @@ subroutine run( this ) call this.products.changeGeometry() case( ROTATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía call this.products.changeOrientations() + end select if( GOptions_printLevel >= 2 ) then @@ -1110,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From af1095bf022b20cef1585850be866b83647eaee6 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:10:35 -0700 Subject: [PATCH 13/57] Version updated --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cd5ac03..2789166 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0 +2.1a From f302f27460790cc1ff722eae11e3397d647c8f0d Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Thu, 28 Feb 2019 23:22:23 -0700 Subject: [PATCH 14/57] Gaussian template freqs updated to improve symmetry detection --- templates/b3lyp.freqs-GAUSSIAN.inp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/b3lyp.freqs-GAUSSIAN.inp b/templates/b3lyp.freqs-GAUSSIAN.inp index e8e1d55..0d144fa 100644 --- a/templates/b3lyp.freqs-GAUSSIAN.inp +++ b/templates/b3lyp.freqs-GAUSSIAN.inp @@ -1,4 +1,4 @@ -#p b3lyp/6-311++G(3df,2p) freq +#p b3lyp/6-311++G(3df,2p) freq IOp(2/17=3) IOp(2/18=3) b3lyp opt From 85071b367b0dc14425d7dac08e132aacb274385a Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 3 Mar 2019 01:48:59 -0700 Subject: [PATCH 15/57] M3C.check now checks the right value of the multiplicity based on the stoichiometry and charge --- src/M3C.check | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/M3C.check b/src/M3C.check index d55c056..31afbaf 100755 --- a/src/M3C.check +++ b/src/M3C.check @@ -165,20 +165,22 @@ function checkConsistence() fi - if [[ ! "$multID" =~ ^m[1-9]+$ ]] + if [[ "$multID" =~ ^m[1-9]+$ ]] then - - if [ "$REMOVE_WRONGFORMAT" = "TRUE" ] + minMult=`molecule.minMult $ifile ${chargeID#q}` + + if [ ! "$multID" = "m$(($minMult+0))" -a ! "$multID" = "m$(($minMult+2))" \ + -a ! "$multID" = "m$(($minMult+4))" -a ! "$multID" = "m$(($minMult+6))" ] then - echo "--> Removed ($ifile) Inconsistency in multID ( $multID --> m[1-9]+ )" - rm $ifile - continue - else echo "" - echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + echo -n "### ERROR ### Inconsistency in multiplicity ( $multID --> " + echo "m$(($minMult+0)), m$(($minMult+2)), m$(($minMult+4)), or m$(($minMult+6)) ) )" kill $$ fi - + else + echo "" + echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + kill $$ fi if [[ ! "$isomerID" =~ ^[0-9]+$ ]] From 06bf8ff34a6e6b031ccffe5f193e1886764bf3a1 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 5 Mar 2019 20:46:53 -0700 Subject: [PATCH 16/57] oGaussian2rxyz bug fixed --- utils/oGaussian2rxyz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/oGaussian2rxyz.sh b/utils/oGaussian2rxyz.sh index 62be55e..b28e1a3 100755 --- a/utils/oGaussian2rxyz.sh +++ b/utils/oGaussian2rxyz.sh @@ -114,7 +114,7 @@ then echo "ELECTRONIC_STATE ??" else #group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` - group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}'` + group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}' | tail -n1` if [ "$group" = "Nop" -o "$group" = "NOp" ] then echo "SYMMETRY ??" From d1d82778ed027af39aba95e04e02fff395b0ad72 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 17/57] First part about implementing transition states --- src/Fragment.f90 | 7 ------- src/FragmentsDB.f90 | 29 ++++++++++++++++++----------- src/Reactor.f90 | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Fragment.f90 b/src/Fragment.f90 index 513e4a4..f39cf10 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -389,15 +389,8 @@ end subroutine destroyFragment subroutine updateFormula( this ) class(Fragment) :: this - integer :: isLineal character(100), allocatable :: tokens(:) - if( this.isLineal() ) then - isLineal = 1 - else - isLineal = 0 - end if - this.dlabel_ = this.name call FString_split( this.name, tokens, "(" ) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index a62abaa..ee1834d 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -62,6 +62,7 @@ module FragmentsDB_ use StringIntegerMap_ use Fragment_ + use FragmentsList_ use ModelPotential_ use GOptionsM3C_ @@ -79,11 +80,11 @@ module FragmentsDB_ type(StringIntegerMap) :: forbiddenReactions logical :: useForbiddenReactionsDetails -! "C2(d1)+C(t1)-->C3(s1)" --> 5 --> transitionState(5) +! "C2(d1)+C(t1)-->C3(s1)" --> 5 . It means transitionState(5) ! |----------str2id_TS----------| type(Fragment), allocatable :: transitionState(:) type(StringIntegerMap) :: str2id_TS - logical, allocatable :: involvedInTS(:) ! One for each group. For speed purposes only. + logical, allocatable :: involvedInTS(:) ! One for each cluster. For speed purposes only. real(8), private :: energyReference_ logical, private :: useAtomicPotentials @@ -360,6 +361,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) character(100), allocatable :: tokens(:), tokens2(:), tokens3(:) real(8) :: rBuffer + ! Only for transition states. They are neccessary to calculate the right label (mass sorted) + type(FragmentsList) :: reactives + type(FragmentsList) :: products + if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -395,28 +400,28 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Choosing the reactives and products !------------------------------------------ if( size(tokens) >= 9 .and. this.transitionState(i).nAtoms() /= 1 ) then - call FString_split( trim(adjustl(tokens(9))), tokens2, "-->" ) + call FString_split( trim(adjustl(tokens(9))), tokens2, "<-->" ) - write(*,*) "Reactivos" call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) + call reactives.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + reactives.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do end do deallocate( tokens3 ) - write(*,*) "Productos" call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) + call products.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + products.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -425,8 +430,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens2 ) - write(*,*) "Agregado: ", FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), ">>", i - call this.str2id_TS.insert( FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), i ) + write(*,"(4X,A22,A)") "Path = ", trim(reactives.label())//"<-->"//trim(products.label()) + call this.str2id_TS.insert( FString_toString(trim(reactives.label())//"<-->"//trim(products.label())), i ) + call this.str2id_TS.insert( FString_toString(trim(products.label())//"<-->"//trim(reactives.label())), i ) + else call GOptions_error( & "Bad number of atoms in transition state (N=0)", & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index fe839c1..600948a 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -112,6 +112,7 @@ module Reactor_ procedure, private, NOPASS :: isSpinForbidden procedure, private, NOPASS :: reactorConstraint procedure, private, NOPASS :: reactionString + procedure, private, NOPASS :: reduceToTransitionStates procedure :: execute procedure :: executeMinFragmentationEnergy @@ -315,6 +316,11 @@ subroutine changeComposition( this, dNfrag ) maxIterForbidden = maxIterForbidden + 1 cycle else + + if( allocated(FragmentsDB_instance.transitionState) ) then + call reduceToTransitionStates( this.reactives, this.products ) + end if + exit end if @@ -464,6 +470,15 @@ function reactionString( reactives, products, details ) result( output ) output = trim(reactives.label( details=effDetails ))//"-->"//trim(products.label( details=effDetails )) end function reactionString + !> + !! @brief Replaces products for the corresponding transition states. Only composition is changed + !! + subroutine reduceToTransitionStates( reactives, products ) + type(FragmentsList), intent(in) :: reactives + type(FragmentsList), intent(inout) :: products + + end subroutine reduceToTransitionStates + !> !! @brief Change the composition of the system !! From 13555e234e5c3be631c48d2b3749496bbee17cd8 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 18/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 600948a..910d369 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -57,13 +57,13 @@ module Reactor_ use IOStream_ use Timer_ use UnitsConverter_ - use IVector_ use RandomUtils_ use StringList_ use AtomicElementsDB_ use BlocksIFileParser_ use RealHistogram_ use RealList_ + use IntegerVector_ use StringIntegerMap_ use StringRealMap_ use StringRealPair_ @@ -92,6 +92,9 @@ module Reactor_ type(FragmentsList) :: products logical :: state + type(FragmentsList) :: productsTS + logical :: replaceTS + character(3), private :: name integer, private :: type integer, allocatable :: dNFrag(:) @@ -318,7 +321,9 @@ subroutine changeComposition( this, dNfrag ) else if( allocated(FragmentsDB_instance.transitionState) ) then - call reduceToTransitionStates( this.reactives, this.products ) + call reduceToTransitionStates( this.reactives, this.products, this.productsTS ) + + if( this.productsTS.nMolecules() > 0 ) this.replaceTS = .true. end if exit @@ -473,10 +478,157 @@ end function reactionString !> !! @brief Replaces products for the corresponding transition states. Only composition is changed !! - subroutine reduceToTransitionStates( reactives, products ) + subroutine reduceToTransitionStates( reactives, products, productsTS ) type(FragmentsList), intent(in) :: reactives type(FragmentsList), intent(inout) :: products + type(FragmentsList), intent(out) :: productsTS + + integer :: i, j, id + integer :: ir, jr, kr + integer :: ip, jp, kp + type(IntegerVector) :: reactiveInTS + type(IntegerVector) :: productInTS + integer, allocatable :: reactiveInTScomb(:,:) + integer, allocatable :: productInTScomb(:,:) + integer :: nAtomsR, nAtomsP + integer :: massNumberR, massNumberP + type(FragmentsList) :: lReactives, lProducts + type(String) :: labelTS, label + logical :: locatedTS + + call reactiveInTS.init( resizeIncrement=reactives.nMolecules() ) + call productInTS.init( resizeIncrement=products.nMolecules() ) + + do i=1,reactives.nMolecules() + id = FragmentsDB_instance.getIdFromName( reactives.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call reactiveInTS.append( i ) + end if + end do + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -867,6 +1019,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -947,6 +1101,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From 40b34ebb40242c3c9d8e5a46ddfd2638c07574e5 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 19/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 910d369..e3dd10b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -578,14 +578,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -593,8 +596,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1016,11 +1025,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From d4c9617d8655656fccd50ec853e9f72f00bb0eae Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 20/57] First version working with TS --- src/FragmentsDB.f90 | 1 + src/MarkovChain.f90 | 11 ++++++++--- src/Reactor.f90 | 35 ++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index ee1834d..3baaa84 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -377,6 +377,7 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) do i=1,size(transitionStatesTable) call this.transitionState(i).fromMassTableRow( transitionStatesTable(i).fstr, id=i, store=store.fstr ) + this.transitionState(i).isTransitionState = .true. call FString_split( transitionStatesTable(i).fstr, tokens, " " ) diff --git a/src/MarkovChain.f90 b/src/MarkovChain.f90 index a34d07c..2c8e433 100644 --- a/src/MarkovChain.f90 +++ b/src/MarkovChain.f90 @@ -442,7 +442,7 @@ subroutine run( this, reactives ) ! sBuffer = react.reactives.weightHistoryLine( origin ) ! end if ! end if - + call react.run() ! Si la energía cinetica es negativa @@ -483,7 +483,12 @@ subroutine run( this, reactives ) nTimesBlocked = 0 ! El bloqueo debe ser consecutivo, así que si no pasa por negative energy se cuenta nuevamente - Pi = react.products.LnW()-react.reactives.LnW() + if( react.replaceTS ) then + react.replaceTS = .false. + Pi = react.productsTS.LnW()-react.reactives.LnW() + else + Pi = react.products.LnW()-react.reactives.LnW() + end if if( Pi > 0.0_8 ) then if( trim(react.reactives.label( details=.false. )) /= trim(react.products.label( details=.false. )) ) then @@ -518,7 +523,7 @@ subroutine run( this, reactives ) sBuffer = trim(react.reactives.label( details=.true. ))//"-->"//trim(react.products.label( details=.true. )) call this.transitionDetHistogram.add( sBuffer ) end if - + react.reactives = react.products call GOptions_info( & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index e3dd10b..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -606,6 +606,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end if if( GOptions_debugLevel >= 2 ) then + write(*,*) " products = ", trim(products.label()) write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) end if @@ -1011,11 +1012,12 @@ subroutine run( this ) real(8) :: min_dLnW - integer :: n, nMin + integer :: nMin real(8) :: rBuffer type(String) :: sBuffer this.state = .true. + this.replaceTS = .false. call this.showReactorHeader() @@ -1025,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1039,16 +1039,37 @@ subroutine run( this ) ! call this.products.changeVibrationalEnergy() ! call this.products.changeGeometry() ! call this.products.changeOrientations() + + if( this.replaceTS ) then + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos + call this.productsTS.setReactorEnergy( this.reactives.reactorEnergy() ) + + ! Para que fuerce los centros aleatorios en la siguiente iteración + this.productsTS.forceRandomCenters = .true. + + ! Los productos utilizan parte de la energía + call this.productsTS.initialGuessFragmentsList() + +! write(*,*) "reactive ", trim(this.reactives.label()) +! write(*,*) "products ", trim(this.products.label()) +! write(*,*) "TS located ", trim(this.productsTS.label()) +! sBuffer = this.products.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) +! sBuffer = this.productsTS.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) + + end if case( VIBRATIONAL_REACTOR ) - + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía cinética en vibracional call this.products.changeVibrationalEnergy() - + case( TRANSLATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives @@ -1056,11 +1077,13 @@ subroutine run( this ) call this.products.changeGeometry() case( ROTATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía call this.products.changeOrientations() + end select if( GOptions_printLevel >= 2 ) then @@ -1110,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From eed0c50440a6970e1330546bdda4aeb9f51cf979 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:10:35 -0700 Subject: [PATCH 21/57] Version updated --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cd5ac03..2789166 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0 +2.1a From 57c930b41c41f9aeb7a1a593787eabffe7c270c9 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Thu, 28 Feb 2019 23:22:23 -0700 Subject: [PATCH 22/57] Gaussian template freqs updated to improve symmetry detection --- templates/b3lyp.freqs-GAUSSIAN.inp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/b3lyp.freqs-GAUSSIAN.inp b/templates/b3lyp.freqs-GAUSSIAN.inp index e8e1d55..0d144fa 100644 --- a/templates/b3lyp.freqs-GAUSSIAN.inp +++ b/templates/b3lyp.freqs-GAUSSIAN.inp @@ -1,4 +1,4 @@ -#p b3lyp/6-311++G(3df,2p) freq +#p b3lyp/6-311++G(3df,2p) freq IOp(2/17=3) IOp(2/18=3) b3lyp opt From dd5fb4f8ae2d5a6cef8b62da4f442686ceca117f Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 3 Mar 2019 01:48:59 -0700 Subject: [PATCH 23/57] M3C.check now checks the right value of the multiplicity based on the stoichiometry and charge --- src/M3C.check | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/M3C.check b/src/M3C.check index d55c056..31afbaf 100755 --- a/src/M3C.check +++ b/src/M3C.check @@ -165,20 +165,22 @@ function checkConsistence() fi - if [[ ! "$multID" =~ ^m[1-9]+$ ]] + if [[ "$multID" =~ ^m[1-9]+$ ]] then - - if [ "$REMOVE_WRONGFORMAT" = "TRUE" ] + minMult=`molecule.minMult $ifile ${chargeID#q}` + + if [ ! "$multID" = "m$(($minMult+0))" -a ! "$multID" = "m$(($minMult+2))" \ + -a ! "$multID" = "m$(($minMult+4))" -a ! "$multID" = "m$(($minMult+6))" ] then - echo "--> Removed ($ifile) Inconsistency in multID ( $multID --> m[1-9]+ )" - rm $ifile - continue - else echo "" - echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + echo -n "### ERROR ### Inconsistency in multiplicity ( $multID --> " + echo "m$(($minMult+0)), m$(($minMult+2)), m$(($minMult+4)), or m$(($minMult+6)) ) )" kill $$ fi - + else + echo "" + echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + kill $$ fi if [[ ! "$isomerID" =~ ^[0-9]+$ ]] From 20804508c84bab0879b93f48a611c809d3acd61e Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 24/57] First part about implementing transition states --- src/Reactor.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 4a74d46..1a0960b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -639,6 +639,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) if( allocated(productInTScomb) ) deallocate( productInTScomb ) + end subroutine reduceToTransitionStates !> From 3301641a04a7c6e1c1399f02c0556ff8139d6035 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 25/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 1a0960b..3ee5cea 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -640,6 +640,129 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) if( allocated(productInTScomb) ) deallocate( productInTScomb ) + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -1031,6 +1154,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -1134,6 +1259,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From d0fba4a6d10a76b667652f20882c9839f43571bc Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 26/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 3ee5cea..07bfba6 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -712,14 +712,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -727,8 +730,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1151,11 +1160,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 5a65369d0226b6aa765c0deb03748b822c941ff2 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 27/57] First version working with TS --- src/Reactor.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 07bfba6..311f983 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1160,8 +1160,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1268,8 +1266,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From 3c76f16ee615468ad71c8fef2af8703025459ab7 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 5 Mar 2019 20:46:53 -0700 Subject: [PATCH 28/57] oGaussian2rxyz bug fixed --- utils/oGaussian2rxyz.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/oGaussian2rxyz.sh b/utils/oGaussian2rxyz.sh index deff9e1..b226483 100755 --- a/utils/oGaussian2rxyz.sh +++ b/utils/oGaussian2rxyz.sh @@ -113,7 +113,8 @@ then echo "SYMMETRY R3" echo "ELECTRONIC_STATE ??" else - group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` + #group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` + group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}' | tail -n1` if [ "$group" = "Nop" -o "$group" = "NOp" ] then echo "SYMMETRY ??" From 8dff71b9015a8ee51f7fc833f0a9ee5dcc15bf50 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 8 Mar 2020 10:02:22 +0100 Subject: [PATCH 29/57] Files needed to compile --- utils/libmsym/CMakeCache.txt | 89 ++++++++++++++++++++-- utils/libmsym/Makefile | 119 ++++++++++++++++-------------- utils/libmsym/cmake_install.cmake | 20 ++++- 3 files changed, 162 insertions(+), 66 deletions(-) diff --git a/utils/libmsym/CMakeCache.txt b/utils/libmsym/CMakeCache.txt index 87baf04..e51f32a 100644 --- a/utils/libmsym/CMakeCache.txt +++ b/utils/libmsym/CMakeCache.txt @@ -1,5 +1,5 @@ # This is the CMakeCache file. -# For build in directory: /home/nestor/Develop/M3C/utils/libmsym +# For build in directory: /home/natalia/Develop/M3C/utils/libmsym # It was generated by CMake: /usr/bin/cmake # You can edit this file to change values found and used by cmake. # If you do not want to change any of the values, simply exit the editor. @@ -14,6 +14,9 @@ # EXTERNAL cache entries ######################## +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + //Choose the type of build, options are: None(CMAKE_CXX_FLAGS or // CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. CMAKE_BUILD_TYPE:STRING= @@ -21,6 +24,17 @@ CMAKE_BUILD_TYPE:STRING= //Enable/Disable color output during build. CMAKE_COLOR_MAKEFILE:BOOL=ON +//CXX compiler +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + //Flags used by the compiler during all build types. CMAKE_CXX_FLAGS:STRING= @@ -37,6 +51,17 @@ CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG //Flags used by the compiler during release builds with debug info. CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG +//C compiler +CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + //Flags used by the compiler during all build types. CMAKE_C_FLAGS:STRING= @@ -74,6 +99,9 @@ CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF //Install path prefix, prepended onto install directories. CMAKE_INSTALL_PREFIX:PATH=/usr/local +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + //Path to a program. CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make @@ -92,9 +120,21 @@ CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= //Flags used by the linker during Release with Debug Info builds. CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + //Value Computed by CMake CMAKE_PROJECT_NAME:STATIC=msym +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + //Flags used by the linker during the creation of dll's. CMAKE_SHARED_LINKER_FLAGS:STRING= @@ -132,6 +172,9 @@ CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= //Flags used by the linker during Release with Debug Info builds. CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + //If this value is on, makefiles will be generated without the // .SILENT directive, and all commands will be echoed to the console // during the make. This is useful for debugging only. With Visual @@ -139,25 +182,27 @@ CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE //Value Computed by CMake -msym_BINARY_DIR:STATIC=/home/nestor/Develop/M3C/utils/libmsym +msym_BINARY_DIR:STATIC=/home/natalia/Develop/M3C/utils/libmsym //Dependencies for target msym_LIB_DEPENDS:STATIC= //Value Computed by CMake -msym_SOURCE_DIR:STATIC=/home/nestor/Develop/M3C/utils/libmsym +msym_SOURCE_DIR:STATIC=/home/natalia/Develop/M3C/utils/libmsym ######################## # INTERNAL cache entries ######################## +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 //This is the directory where this CMakeCache.txt was created -CMAKE_CACHEFILE_DIR:INTERNAL=/home/nestor/Develop/M3C/utils/libmsym +CMAKE_CACHEFILE_DIR:INTERNAL=/home/natalia/Develop/M3C/utils/libmsym //Major version of cmake used to create the current loaded cache CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 //Minor version of cmake used to create the current loaded cache -CMAKE_CACHE_MINOR_VERSION:INTERNAL=5 +CMAKE_CACHE_MINOR_VERSION:INTERNAL=9 //Patch version of cmake used to create the current loaded cache CMAKE_CACHE_PATCH_VERSION:INTERNAL=1 //ADVANCED property for variable: CMAKE_COLOR_MAKEFILE @@ -168,6 +213,12 @@ CMAKE_COMMAND:INTERNAL=/usr/bin/cmake CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack //Path to ctest program executable. CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR +CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB +CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG @@ -178,6 +229,12 @@ CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_AR +CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB +CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG @@ -188,6 +245,8 @@ CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF //ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG @@ -210,9 +269,11 @@ CMAKE_GENERATOR_PLATFORM:INTERNAL= CMAKE_GENERATOR_TOOLSET:INTERNAL= //Source directory with the top level CMakeLists.txt file for this // project -CMAKE_HOME_DIRECTORY:INTERNAL=/home/nestor/Develop/M3C/utils/libmsym +CMAKE_HOME_DIRECTORY:INTERNAL=/home/natalia/Develop/M3C/utils/libmsym //Install .so files without execute permission. CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MAKE_PROGRAM CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS @@ -225,10 +286,20 @@ CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 //number of local generators CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 //Path to CMake installation. -CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5 +CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.9 //ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG @@ -253,6 +324,10 @@ CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname //ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 diff --git a/utils/libmsym/Makefile b/utils/libmsym/Makefile index 15632a7..1e9a3f5 100644 --- a/utils/libmsym/Makefile +++ b/utils/libmsym/Makefile @@ -1,5 +1,5 @@ # CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 3.5 +# Generated by "Unix Makefiles" Generator, CMake Version 3.9 # Default target executed when no arguments are given to make. default_target: all @@ -48,35 +48,37 @@ RM = /usr/bin/cmake -E remove -f EQUALS = = # The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/nestor/Develop/M3C/utils/libmsym +CMAKE_SOURCE_DIR = /home/natalia/Develop/M3C/utils/libmsym # The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/nestor/Develop/M3C/utils/libmsym +CMAKE_BINARY_DIR = /home/natalia/Develop/M3C/utils/libmsym #============================================================================= # Targets provided globally by CMake. -# Special rule for the target install -install: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip -# Special rule for the target install -install/fast: preinstall/fast - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install/fast +# Special rule for the target install/strip +install/strip/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip/fast -# Special rule for the target list_install_components -list_install_components: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" -.PHONY : list_install_components - -# Special rule for the target list_install_components -list_install_components/fast: list_install_components +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local -.PHONY : list_install_components/fast +# Special rule for the target install/local +install/local/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local/fast # Special rule for the target rebuild_cache rebuild_cache: @@ -89,17 +91,6 @@ rebuild_cache/fast: rebuild_cache .PHONY : rebuild_cache/fast -# Special rule for the target install/local -install/local: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." - /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake -.PHONY : install/local - -# Special rule for the target install/local -install/local/fast: install/local - -.PHONY : install/local/fast - # Special rule for the target edit_cache edit_cache: @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." @@ -111,11 +102,33 @@ edit_cache/fast: edit_cache .PHONY : edit_cache/fast +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components + +.PHONY : list_install_components/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + # The main all target all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles/progress.marks + $(CMAKE_COMMAND) -E cmake_progress_start /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles/progress.marks $(MAKE) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles 0 + $(CMAKE_COMMAND) -E cmake_progress_start /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles 0 .PHONY : all # The main clean target @@ -143,19 +156,6 @@ depend: $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 .PHONY : depend -#============================================================================= -# Target rules for targets named msym - -# Build rule for target. -msym: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 msym -.PHONY : msym - -# fast build rule for target. -msym/fast: - $(MAKE) -f CMakeFiles/msym.dir/build.make CMakeFiles/msym.dir/build -.PHONY : msym/fast - #============================================================================= # Target rules for targets named molecule.symmetrize @@ -169,10 +169,18 @@ molecule.symmetrize/fast: $(MAKE) -f CMakeFiles/molecule.symmetrize.dir/build.make CMakeFiles/molecule.symmetrize.dir/build .PHONY : molecule.symmetrize/fast -# Manual pre-install relink rule for target. -molecule.symmetrize/preinstall: - $(MAKE) -f CMakeFiles/molecule.symmetrize.dir/build.make CMakeFiles/molecule.symmetrize.dir/preinstall -.PHONY : molecule.symmetrize/preinstall +#============================================================================= +# Target rules for targets named msym + +# Build rule for target. +msym: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 msym +.PHONY : msym + +# fast build rule for target. +msym/fast: + $(MAKE) -f CMakeFiles/msym.dir/build.make CMakeFiles/msym.dir/build +.PHONY : msym/fast basis_function.o: basis_function.c.o @@ -666,13 +674,14 @@ help: @echo "... all (the default if no target is provided)" @echo "... clean" @echo "... depend" - @echo "... install" - @echo "... list_install_components" - @echo "... rebuild_cache" - @echo "... msym" + @echo "... install/strip" @echo "... install/local" @echo "... molecule.symmetrize" + @echo "... rebuild_cache" + @echo "... msym" @echo "... edit_cache" + @echo "... list_install_components" + @echo "... install" @echo "... basis_function.o" @echo "... basis_function.i" @echo "... basis_function.s" diff --git a/utils/libmsym/cmake_install.cmake b/utils/libmsym/cmake_install.cmake index e5c8fb2..1e314eb 100644 --- a/utils/libmsym/cmake_install.cmake +++ b/utils/libmsym/cmake_install.cmake @@ -1,4 +1,4 @@ -# Install script for directory: /home/nestor/Develop/M3C/utils/libmsym +# Install script for directory: /home/natalia/Develop/M3C/utils/libmsym # Set the install prefix if(NOT DEFINED CMAKE_INSTALL_PREFIX) @@ -32,8 +32,20 @@ if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) set(CMAKE_INSTALL_SO_NO_EXE "1") endif() -if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/nestor/Develop/M3C/utils/libmsym/CMakeFiles/CMakeRelink.dir/molecule.symmetrize") +if("${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT) + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + file(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" + RPATH "") + endif() + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/natalia/Develop/M3C/utils/molecule.symmetrize") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + if(CMAKE_INSTALL_DO_STRIP) + execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + endif() + endif() endif() if(CMAKE_INSTALL_COMPONENT) @@ -44,5 +56,5 @@ endif() string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT "${CMAKE_INSTALL_MANIFEST_FILES}") -file(WRITE "/home/nestor/Develop/M3C/utils/libmsym/${CMAKE_INSTALL_MANIFEST}" +file(WRITE "/home/natalia/Develop/M3C/utils/libmsym/${CMAKE_INSTALL_MANIFEST}" "${CMAKE_INSTALL_MANIFEST_CONTENT}") From 326d8d4b1608e5664aac58168cdcd9c674619f6a Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 30/57] First part about implementing transition states --- src/Fragment.f90 | 7 ------- src/FragmentsDB.f90 | 29 ++++++++++++++++++----------- src/Reactor.f90 | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Fragment.f90 b/src/Fragment.f90 index a45db2c..59ca9ad 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -391,15 +391,8 @@ end subroutine destroyFragment subroutine updateFormula( this ) class(Fragment) :: this - integer :: isLineal character(100), allocatable :: tokens(:) - if( this.isLineal() ) then - isLineal = 1 - else - isLineal = 0 - end if - this.dlabel_ = this.name call FString_split( this.name, tokens, "(" ) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index a62abaa..ee1834d 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -62,6 +62,7 @@ module FragmentsDB_ use StringIntegerMap_ use Fragment_ + use FragmentsList_ use ModelPotential_ use GOptionsM3C_ @@ -79,11 +80,11 @@ module FragmentsDB_ type(StringIntegerMap) :: forbiddenReactions logical :: useForbiddenReactionsDetails -! "C2(d1)+C(t1)-->C3(s1)" --> 5 --> transitionState(5) +! "C2(d1)+C(t1)-->C3(s1)" --> 5 . It means transitionState(5) ! |----------str2id_TS----------| type(Fragment), allocatable :: transitionState(:) type(StringIntegerMap) :: str2id_TS - logical, allocatable :: involvedInTS(:) ! One for each group. For speed purposes only. + logical, allocatable :: involvedInTS(:) ! One for each cluster. For speed purposes only. real(8), private :: energyReference_ logical, private :: useAtomicPotentials @@ -360,6 +361,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) character(100), allocatable :: tokens(:), tokens2(:), tokens3(:) real(8) :: rBuffer + ! Only for transition states. They are neccessary to calculate the right label (mass sorted) + type(FragmentsList) :: reactives + type(FragmentsList) :: products + if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -395,28 +400,28 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Choosing the reactives and products !------------------------------------------ if( size(tokens) >= 9 .and. this.transitionState(i).nAtoms() /= 1 ) then - call FString_split( trim(adjustl(tokens(9))), tokens2, "-->" ) + call FString_split( trim(adjustl(tokens(9))), tokens2, "<-->" ) - write(*,*) "Reactivos" call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) + call reactives.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + reactives.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do end do deallocate( tokens3 ) - write(*,*) "Productos" call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) + call products.init( size(tokens3) ) + do j=1,size(tokens3) - write(*,*) "token = ", trim(tokens3(j)) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then - write(IO_STDOUT,*) k, this.clusters(k).id + products.clusters(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -425,8 +430,10 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens2 ) - write(*,*) "Agregado: ", FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), ">>", i - call this.str2id_TS.insert( FString_toString(trim(adjustl(tokens(9)))//"-->"//trim(adjustl(tokens(10)))), i ) + write(*,"(4X,A22,A)") "Path = ", trim(reactives.label())//"<-->"//trim(products.label()) + call this.str2id_TS.insert( FString_toString(trim(reactives.label())//"<-->"//trim(products.label())), i ) + call this.str2id_TS.insert( FString_toString(trim(products.label())//"<-->"//trim(reactives.label())), i ) + else call GOptions_error( & "Bad number of atoms in transition state (N=0)", & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index fe839c1..600948a 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -112,6 +112,7 @@ module Reactor_ procedure, private, NOPASS :: isSpinForbidden procedure, private, NOPASS :: reactorConstraint procedure, private, NOPASS :: reactionString + procedure, private, NOPASS :: reduceToTransitionStates procedure :: execute procedure :: executeMinFragmentationEnergy @@ -315,6 +316,11 @@ subroutine changeComposition( this, dNfrag ) maxIterForbidden = maxIterForbidden + 1 cycle else + + if( allocated(FragmentsDB_instance.transitionState) ) then + call reduceToTransitionStates( this.reactives, this.products ) + end if + exit end if @@ -464,6 +470,15 @@ function reactionString( reactives, products, details ) result( output ) output = trim(reactives.label( details=effDetails ))//"-->"//trim(products.label( details=effDetails )) end function reactionString + !> + !! @brief Replaces products for the corresponding transition states. Only composition is changed + !! + subroutine reduceToTransitionStates( reactives, products ) + type(FragmentsList), intent(in) :: reactives + type(FragmentsList), intent(inout) :: products + + end subroutine reduceToTransitionStates + !> !! @brief Change the composition of the system !! From 4b5ffed0dcc19edccf74c23d5e11bcf343fb402e Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 31/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 162 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 600948a..910d369 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -57,13 +57,13 @@ module Reactor_ use IOStream_ use Timer_ use UnitsConverter_ - use IVector_ use RandomUtils_ use StringList_ use AtomicElementsDB_ use BlocksIFileParser_ use RealHistogram_ use RealList_ + use IntegerVector_ use StringIntegerMap_ use StringRealMap_ use StringRealPair_ @@ -92,6 +92,9 @@ module Reactor_ type(FragmentsList) :: products logical :: state + type(FragmentsList) :: productsTS + logical :: replaceTS + character(3), private :: name integer, private :: type integer, allocatable :: dNFrag(:) @@ -318,7 +321,9 @@ subroutine changeComposition( this, dNfrag ) else if( allocated(FragmentsDB_instance.transitionState) ) then - call reduceToTransitionStates( this.reactives, this.products ) + call reduceToTransitionStates( this.reactives, this.products, this.productsTS ) + + if( this.productsTS.nMolecules() > 0 ) this.replaceTS = .true. end if exit @@ -473,10 +478,157 @@ end function reactionString !> !! @brief Replaces products for the corresponding transition states. Only composition is changed !! - subroutine reduceToTransitionStates( reactives, products ) + subroutine reduceToTransitionStates( reactives, products, productsTS ) type(FragmentsList), intent(in) :: reactives type(FragmentsList), intent(inout) :: products + type(FragmentsList), intent(out) :: productsTS + + integer :: i, j, id + integer :: ir, jr, kr + integer :: ip, jp, kp + type(IntegerVector) :: reactiveInTS + type(IntegerVector) :: productInTS + integer, allocatable :: reactiveInTScomb(:,:) + integer, allocatable :: productInTScomb(:,:) + integer :: nAtomsR, nAtomsP + integer :: massNumberR, massNumberP + type(FragmentsList) :: lReactives, lProducts + type(String) :: labelTS, label + logical :: locatedTS + + call reactiveInTS.init( resizeIncrement=reactives.nMolecules() ) + call productInTS.init( resizeIncrement=products.nMolecules() ) + + do i=1,reactives.nMolecules() + id = FragmentsDB_instance.getIdFromName( reactives.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call reactiveInTS.append( i ) + end if + end do + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -867,6 +1019,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -947,6 +1101,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From cf595577e6436fa7f020f59f94a8f997628fae70 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 32/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 910d369..e3dd10b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -578,14 +578,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -593,8 +596,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1016,11 +1025,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 17395aa1305c56879663ccc3a6da69dbd3e04a69 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 33/57] First version working with TS --- src/FragmentsDB.f90 | 1 + src/MarkovChain.f90 | 11 ++++++++--- src/Reactor.f90 | 35 ++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index ee1834d..3baaa84 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -377,6 +377,7 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) do i=1,size(transitionStatesTable) call this.transitionState(i).fromMassTableRow( transitionStatesTable(i).fstr, id=i, store=store.fstr ) + this.transitionState(i).isTransitionState = .true. call FString_split( transitionStatesTable(i).fstr, tokens, " " ) diff --git a/src/MarkovChain.f90 b/src/MarkovChain.f90 index a34d07c..2c8e433 100644 --- a/src/MarkovChain.f90 +++ b/src/MarkovChain.f90 @@ -442,7 +442,7 @@ subroutine run( this, reactives ) ! sBuffer = react.reactives.weightHistoryLine( origin ) ! end if ! end if - + call react.run() ! Si la energía cinetica es negativa @@ -483,7 +483,12 @@ subroutine run( this, reactives ) nTimesBlocked = 0 ! El bloqueo debe ser consecutivo, así que si no pasa por negative energy se cuenta nuevamente - Pi = react.products.LnW()-react.reactives.LnW() + if( react.replaceTS ) then + react.replaceTS = .false. + Pi = react.productsTS.LnW()-react.reactives.LnW() + else + Pi = react.products.LnW()-react.reactives.LnW() + end if if( Pi > 0.0_8 ) then if( trim(react.reactives.label( details=.false. )) /= trim(react.products.label( details=.false. )) ) then @@ -518,7 +523,7 @@ subroutine run( this, reactives ) sBuffer = trim(react.reactives.label( details=.true. ))//"-->"//trim(react.products.label( details=.true. )) call this.transitionDetHistogram.add( sBuffer ) end if - + react.reactives = react.products call GOptions_info( & diff --git a/src/Reactor.f90 b/src/Reactor.f90 index e3dd10b..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -606,6 +606,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end if if( GOptions_debugLevel >= 2 ) then + write(*,*) " products = ", trim(products.label()) write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) end if @@ -1011,11 +1012,12 @@ subroutine run( this ) real(8) :: min_dLnW - integer :: n, nMin + integer :: nMin real(8) :: rBuffer type(String) :: sBuffer this.state = .true. + this.replaceTS = .false. call this.showReactorHeader() @@ -1025,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1039,16 +1039,37 @@ subroutine run( this ) ! call this.products.changeVibrationalEnergy() ! call this.products.changeGeometry() ! call this.products.changeOrientations() + + if( this.replaceTS ) then + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos + call this.productsTS.setReactorEnergy( this.reactives.reactorEnergy() ) + + ! Para que fuerce los centros aleatorios en la siguiente iteración + this.productsTS.forceRandomCenters = .true. + + ! Los productos utilizan parte de la energía + call this.productsTS.initialGuessFragmentsList() + +! write(*,*) "reactive ", trim(this.reactives.label()) +! write(*,*) "products ", trim(this.products.label()) +! write(*,*) "TS located ", trim(this.productsTS.label()) +! sBuffer = this.products.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) +! sBuffer = this.productsTS.energyHistoryLine() +! write(*,"(A)") trim(sBuffer.fstr) + + end if case( VIBRATIONAL_REACTOR ) - + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía cinética en vibracional call this.products.changeVibrationalEnergy() - + case( TRANSLATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives @@ -1056,11 +1077,13 @@ subroutine run( this ) call this.products.changeGeometry() case( ROTATIONAL_REACTOR ) + ! La composición es igual antes y después this.products = this.reactives ! Los productos utilizan parte de la energía call this.products.changeOrientations() + end select if( GOptions_printLevel >= 2 ) then @@ -1110,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From d4563a833fc1c36195daa7816501c92565051d84 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:10:35 -0700 Subject: [PATCH 34/57] Version updated --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cd5ac03..2789166 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0 +2.1a From 20f7cc367014654936320752e81166ed9af8a376 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Thu, 28 Feb 2019 23:22:23 -0700 Subject: [PATCH 35/57] Gaussian template freqs updated to improve symmetry detection --- templates/b3lyp.freqs-GAUSSIAN.inp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/b3lyp.freqs-GAUSSIAN.inp b/templates/b3lyp.freqs-GAUSSIAN.inp index e8e1d55..0d144fa 100644 --- a/templates/b3lyp.freqs-GAUSSIAN.inp +++ b/templates/b3lyp.freqs-GAUSSIAN.inp @@ -1,4 +1,4 @@ -#p b3lyp/6-311++G(3df,2p) freq +#p b3lyp/6-311++G(3df,2p) freq IOp(2/17=3) IOp(2/18=3) b3lyp opt From 0ae740c2dc8eb4be29db4632693b866fe6255a3e Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 3 Mar 2019 01:48:59 -0700 Subject: [PATCH 36/57] M3C.check now checks the right value of the multiplicity based on the stoichiometry and charge --- src/M3C.check | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/M3C.check b/src/M3C.check index d55c056..31afbaf 100755 --- a/src/M3C.check +++ b/src/M3C.check @@ -165,20 +165,22 @@ function checkConsistence() fi - if [[ ! "$multID" =~ ^m[1-9]+$ ]] + if [[ "$multID" =~ ^m[1-9]+$ ]] then - - if [ "$REMOVE_WRONGFORMAT" = "TRUE" ] + minMult=`molecule.minMult $ifile ${chargeID#q}` + + if [ ! "$multID" = "m$(($minMult+0))" -a ! "$multID" = "m$(($minMult+2))" \ + -a ! "$multID" = "m$(($minMult+4))" -a ! "$multID" = "m$(($minMult+6))" ] then - echo "--> Removed ($ifile) Inconsistency in multID ( $multID --> m[1-9]+ )" - rm $ifile - continue - else echo "" - echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + echo -n "### ERROR ### Inconsistency in multiplicity ( $multID --> " + echo "m$(($minMult+0)), m$(($minMult+2)), m$(($minMult+4)), or m$(($minMult+6)) ) )" kill $$ fi - + else + echo "" + echo "### ERROR ### Inconsistency in multID ( $multID --> m[1-9]+ )" + kill $$ fi if [[ ! "$isomerID" =~ ^[0-9]+$ ]] From 8e157b2bec6c2bbd35ea987682f5960bd870724e Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 5 Mar 2019 20:46:53 -0700 Subject: [PATCH 37/57] oGaussian2rxyz bug fixed --- utils/oGaussian2rxyz.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/oGaussian2rxyz.sh b/utils/oGaussian2rxyz.sh index deff9e1..b226483 100755 --- a/utils/oGaussian2rxyz.sh +++ b/utils/oGaussian2rxyz.sh @@ -113,7 +113,8 @@ then echo "SYMMETRY R3" echo "ELECTRONIC_STATE ??" else - group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` + #group=`grep "Full point group" $iFile | tail -n1 | gawk '{print $4}'` + group=`grep "Framework group" $iFile | sed 's/\[/ /g' | gawk '{print $3}' | tail -n1` if [ "$group" = "Nop" -o "$group" = "NOp" ] then echo "SYMMETRY ??" From c15a6a9f2c5195caa6108bfba80d28017b6afca4 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 38/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 4a74d46..49f5ee3 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1030,6 +1030,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -1133,6 +1135,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From 145fc8a250009a21e4df9c9c3a8ef92855d6edb1 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 39/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 49f5ee3..7b6b5a2 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1027,11 +1027,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From ee566cafb2b10b635b854ce08012d169d45465cd Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 40/57] First version working with TS --- src/Reactor.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 7b6b5a2..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1027,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1135,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From cca1ebe202c9eac3ca68009dd2adb1eb0d3306a7 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 41/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 4a74d46..49f5ee3 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1030,6 +1030,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -1133,6 +1135,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From f4b394be1f8f6abcdafa4e0552a263f5f0c379da Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 42/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 49f5ee3..7b6b5a2 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1027,11 +1027,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 0d400f53ec324447ca2a78d805b415ef255608f7 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 43/57] First version working with TS --- src/Reactor.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 7b6b5a2..4a74d46 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1027,8 +1027,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1135,8 +1133,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From ecb1761dbf9115c31b7ab8fc521222acc6865f72 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 9 Feb 2019 21:23:43 -0700 Subject: [PATCH 44/57] First part about implementing transition states --- src/Reactor.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 4a74d46..1a0960b 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -639,6 +639,7 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) if( allocated(productInTScomb) ) deallocate( productInTScomb ) + end subroutine reduceToTransitionStates !> From 65737b1c34b8a8bb308d7cb5caa431ac9e6d9c92 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 16:31:15 -0700 Subject: [PATCH 45/57] Second trial for TS. There is a bug when all products fit with one TS --- src/Reactor.f90 | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 1a0960b..3ee5cea 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -640,6 +640,129 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) if( allocated(productInTScomb) ) deallocate( productInTScomb ) + do i=1,products.nMolecules() + id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + if( FragmentsDB_instance.involvedInTS( id ) ) then + call productInTS.append( i ) + end if + end do + + if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then +! write(*,"(A)",advance="no") "Reactives " +! do i=1,reactives.nMolecules() +! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) +! write(*,"(A)",advance="no") "Products " +! do i=1,products.nMolecules() +! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! end do +! write(*,*) "" +! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) + + locatedTS = .false. + + do ir=1,reactiveInTS.size() + call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) + + do jr=1,size(reactiveInTScomb,dim=1) + + nAtomsR = 0 + massNumberR = 0 + do kr=1,size(reactiveInTScomb,dim=2) + massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() + nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() + end do + + do ip=1,productInTS.size() + call Math_combinations( productInTS.size(), ip, productInTScomb ) + + do jp=1,size(productInTScomb,dim=1) + + nAtomsP = 0 + massNumberP = 0 + do kp=1,size(productInTScomb,dim=2) + massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() + nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() + end do + + if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then + + call lReactives.init( size(reactiveInTScomb,dim=2) ) + call lProducts.init( size(productInTScomb,dim=2) ) + + do kr=1,size(reactiveInTScomb,dim=2) + lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) + end do + + do kp=1,size(productInTScomb,dim=2) + lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) + end do + + if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + + labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " reactives = ", trim(reactives.label()) + write(*,*) " products = ", trim(products.label()) + write(*,*) " TS located = ", trim(labelTS.fstr) + end if + + call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) + ! En este caso nunca se entra en el if + j=1 + do i=1,products.nMolecules() + do kp=1,size(productInTScomb,dim=2) + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) + if( label /= trim(products.clusters(i).label()) & + .and. j<=lProducts.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + exit + end if + end do + end do + + call productsTS.set( j, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + + if( GOptions_debugLevel >= 2 ) then + write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + end if + + locatedTS = .true. + exit ! Only one TS is accepted. The one with minimum size + + end if + + end if + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + if( locatedTS ) exit + + end do + + end if + + if( GOptions_debugLevel >= 2 ) then + write(*,*) "" + end if + + if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) + if( allocated(productInTScomb) ) deallocate( productInTScomb ) end subroutine reduceToTransitionStates !> @@ -1031,6 +1154,8 @@ subroutine run( this ) ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) + if( this.replaceTS ) this.products = this.productsTS + ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. @@ -1134,6 +1259,8 @@ subroutine run( this ) this.state = .false. end if + if( this.replaceTS ) this.replaceTS = .false. + end subroutine run !> From f11d9eca69d937357b8fe06f7a6b1383dda7e2e4 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 10 Feb 2019 17:05:57 -0700 Subject: [PATCH 46/57] Bug replacing products by TS fixed --- src/Reactor.f90 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 3ee5cea..07bfba6 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -712,14 +712,17 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) + call productsTS.set( 1, & + FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if - j=1 + j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) if( label /= trim(products.clusters(i).label()) & - .and. j<=lProducts.nMolecules() ) then + .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 exit @@ -727,8 +730,14 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end do end do - call productsTS.set( j, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + if( j==2 ) then + do i=1,products.nMolecules() + if( j<=productsTS.nMolecules() ) then + call productsTS.set( j, products.clusters(i) ) + j = j+1 + end if + end do + end if if( GOptions_debugLevel >= 2 ) then write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) @@ -1151,11 +1160,11 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) + if( this.replaceTS ) this.products = this.productsTS + ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) - if( this.replaceTS ) this.products = this.productsTS - ! Para que fuerce los centros aleatorios en la siguiente iteración this.products.forceRandomCenters = .true. From 32c3bbabd77e3185748ce101753a22ed7bfe91e5 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Wed, 13 Feb 2019 22:09:08 -0700 Subject: [PATCH 47/57] First version working with TS --- src/Reactor.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 07bfba6..311f983 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -1160,8 +1160,6 @@ subroutine run( this ) ! Se actualiza la composición call this.changeComposition( this.dNFrag ) - if( this.replaceTS ) this.products = this.productsTS - ! Se le asocia la energía del reactor para asegurar que calcula un peso Wt es adecuado para los productos call this.products.setReactorEnergy( this.reactives.reactorEnergy() ) @@ -1268,8 +1266,6 @@ subroutine run( this ) this.state = .false. end if - if( this.replaceTS ) this.replaceTS = .false. - end subroutine run !> From 4eda88e5ae7c4f9b5e4f4fc5386755e8cf4bc1f3 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 8 Mar 2020 10:02:22 +0100 Subject: [PATCH 48/57] Files needed to compile --- utils/libmsym/CMakeCache.txt | 89 ++++++++++++++++++++-- utils/libmsym/Makefile | 119 ++++++++++++++++-------------- utils/libmsym/cmake_install.cmake | 20 ++++- 3 files changed, 162 insertions(+), 66 deletions(-) diff --git a/utils/libmsym/CMakeCache.txt b/utils/libmsym/CMakeCache.txt index 87baf04..e51f32a 100644 --- a/utils/libmsym/CMakeCache.txt +++ b/utils/libmsym/CMakeCache.txt @@ -1,5 +1,5 @@ # This is the CMakeCache file. -# For build in directory: /home/nestor/Develop/M3C/utils/libmsym +# For build in directory: /home/natalia/Develop/M3C/utils/libmsym # It was generated by CMake: /usr/bin/cmake # You can edit this file to change values found and used by cmake. # If you do not want to change any of the values, simply exit the editor. @@ -14,6 +14,9 @@ # EXTERNAL cache entries ######################## +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + //Choose the type of build, options are: None(CMAKE_CXX_FLAGS or // CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. CMAKE_BUILD_TYPE:STRING= @@ -21,6 +24,17 @@ CMAKE_BUILD_TYPE:STRING= //Enable/Disable color output during build. CMAKE_COLOR_MAKEFILE:BOOL=ON +//CXX compiler +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + //Flags used by the compiler during all build types. CMAKE_CXX_FLAGS:STRING= @@ -37,6 +51,17 @@ CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG //Flags used by the compiler during release builds with debug info. CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG +//C compiler +CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + //Flags used by the compiler during all build types. CMAKE_C_FLAGS:STRING= @@ -74,6 +99,9 @@ CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF //Install path prefix, prepended onto install directories. CMAKE_INSTALL_PREFIX:PATH=/usr/local +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + //Path to a program. CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make @@ -92,9 +120,21 @@ CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= //Flags used by the linker during Release with Debug Info builds. CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + //Value Computed by CMake CMAKE_PROJECT_NAME:STATIC=msym +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + //Flags used by the linker during the creation of dll's. CMAKE_SHARED_LINKER_FLAGS:STRING= @@ -132,6 +172,9 @@ CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= //Flags used by the linker during Release with Debug Info builds. CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + //If this value is on, makefiles will be generated without the // .SILENT directive, and all commands will be echoed to the console // during the make. This is useful for debugging only. With Visual @@ -139,25 +182,27 @@ CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE //Value Computed by CMake -msym_BINARY_DIR:STATIC=/home/nestor/Develop/M3C/utils/libmsym +msym_BINARY_DIR:STATIC=/home/natalia/Develop/M3C/utils/libmsym //Dependencies for target msym_LIB_DEPENDS:STATIC= //Value Computed by CMake -msym_SOURCE_DIR:STATIC=/home/nestor/Develop/M3C/utils/libmsym +msym_SOURCE_DIR:STATIC=/home/natalia/Develop/M3C/utils/libmsym ######################## # INTERNAL cache entries ######################## +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 //This is the directory where this CMakeCache.txt was created -CMAKE_CACHEFILE_DIR:INTERNAL=/home/nestor/Develop/M3C/utils/libmsym +CMAKE_CACHEFILE_DIR:INTERNAL=/home/natalia/Develop/M3C/utils/libmsym //Major version of cmake used to create the current loaded cache CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 //Minor version of cmake used to create the current loaded cache -CMAKE_CACHE_MINOR_VERSION:INTERNAL=5 +CMAKE_CACHE_MINOR_VERSION:INTERNAL=9 //Patch version of cmake used to create the current loaded cache CMAKE_CACHE_PATCH_VERSION:INTERNAL=1 //ADVANCED property for variable: CMAKE_COLOR_MAKEFILE @@ -168,6 +213,12 @@ CMAKE_COMMAND:INTERNAL=/usr/bin/cmake CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack //Path to ctest program executable. CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR +CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB +CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG @@ -178,6 +229,12 @@ CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_AR +CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB +CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG @@ -188,6 +245,8 @@ CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF //ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG @@ -210,9 +269,11 @@ CMAKE_GENERATOR_PLATFORM:INTERNAL= CMAKE_GENERATOR_TOOLSET:INTERNAL= //Source directory with the top level CMakeLists.txt file for this // project -CMAKE_HOME_DIRECTORY:INTERNAL=/home/nestor/Develop/M3C/utils/libmsym +CMAKE_HOME_DIRECTORY:INTERNAL=/home/natalia/Develop/M3C/utils/libmsym //Install .so files without execute permission. CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MAKE_PROGRAM CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS @@ -225,10 +286,20 @@ CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 //number of local generators CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 //Path to CMake installation. -CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5 +CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.9 //ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG @@ -253,6 +324,10 @@ CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 //ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname //ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 diff --git a/utils/libmsym/Makefile b/utils/libmsym/Makefile index 15632a7..1e9a3f5 100644 --- a/utils/libmsym/Makefile +++ b/utils/libmsym/Makefile @@ -1,5 +1,5 @@ # CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 3.5 +# Generated by "Unix Makefiles" Generator, CMake Version 3.9 # Default target executed when no arguments are given to make. default_target: all @@ -48,35 +48,37 @@ RM = /usr/bin/cmake -E remove -f EQUALS = = # The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/nestor/Develop/M3C/utils/libmsym +CMAKE_SOURCE_DIR = /home/natalia/Develop/M3C/utils/libmsym # The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/nestor/Develop/M3C/utils/libmsym +CMAKE_BINARY_DIR = /home/natalia/Develop/M3C/utils/libmsym #============================================================================= # Targets provided globally by CMake. -# Special rule for the target install -install: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip -# Special rule for the target install -install/fast: preinstall/fast - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install/fast +# Special rule for the target install/strip +install/strip/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip/fast -# Special rule for the target list_install_components -list_install_components: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" -.PHONY : list_install_components - -# Special rule for the target list_install_components -list_install_components/fast: list_install_components +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local -.PHONY : list_install_components/fast +# Special rule for the target install/local +install/local/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local/fast # Special rule for the target rebuild_cache rebuild_cache: @@ -89,17 +91,6 @@ rebuild_cache/fast: rebuild_cache .PHONY : rebuild_cache/fast -# Special rule for the target install/local -install/local: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." - /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake -.PHONY : install/local - -# Special rule for the target install/local -install/local/fast: install/local - -.PHONY : install/local/fast - # Special rule for the target edit_cache edit_cache: @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." @@ -111,11 +102,33 @@ edit_cache/fast: edit_cache .PHONY : edit_cache/fast +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components + +.PHONY : list_install_components/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + # The main all target all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles/progress.marks + $(CMAKE_COMMAND) -E cmake_progress_start /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles/progress.marks $(MAKE) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /home/nestor/Develop/M3C/utils/libmsym/CMakeFiles 0 + $(CMAKE_COMMAND) -E cmake_progress_start /home/natalia/Develop/M3C/utils/libmsym/CMakeFiles 0 .PHONY : all # The main clean target @@ -143,19 +156,6 @@ depend: $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 .PHONY : depend -#============================================================================= -# Target rules for targets named msym - -# Build rule for target. -msym: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 msym -.PHONY : msym - -# fast build rule for target. -msym/fast: - $(MAKE) -f CMakeFiles/msym.dir/build.make CMakeFiles/msym.dir/build -.PHONY : msym/fast - #============================================================================= # Target rules for targets named molecule.symmetrize @@ -169,10 +169,18 @@ molecule.symmetrize/fast: $(MAKE) -f CMakeFiles/molecule.symmetrize.dir/build.make CMakeFiles/molecule.symmetrize.dir/build .PHONY : molecule.symmetrize/fast -# Manual pre-install relink rule for target. -molecule.symmetrize/preinstall: - $(MAKE) -f CMakeFiles/molecule.symmetrize.dir/build.make CMakeFiles/molecule.symmetrize.dir/preinstall -.PHONY : molecule.symmetrize/preinstall +#============================================================================= +# Target rules for targets named msym + +# Build rule for target. +msym: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 msym +.PHONY : msym + +# fast build rule for target. +msym/fast: + $(MAKE) -f CMakeFiles/msym.dir/build.make CMakeFiles/msym.dir/build +.PHONY : msym/fast basis_function.o: basis_function.c.o @@ -666,13 +674,14 @@ help: @echo "... all (the default if no target is provided)" @echo "... clean" @echo "... depend" - @echo "... install" - @echo "... list_install_components" - @echo "... rebuild_cache" - @echo "... msym" + @echo "... install/strip" @echo "... install/local" @echo "... molecule.symmetrize" + @echo "... rebuild_cache" + @echo "... msym" @echo "... edit_cache" + @echo "... list_install_components" + @echo "... install" @echo "... basis_function.o" @echo "... basis_function.i" @echo "... basis_function.s" diff --git a/utils/libmsym/cmake_install.cmake b/utils/libmsym/cmake_install.cmake index e5c8fb2..1e314eb 100644 --- a/utils/libmsym/cmake_install.cmake +++ b/utils/libmsym/cmake_install.cmake @@ -1,4 +1,4 @@ -# Install script for directory: /home/nestor/Develop/M3C/utils/libmsym +# Install script for directory: /home/natalia/Develop/M3C/utils/libmsym # Set the install prefix if(NOT DEFINED CMAKE_INSTALL_PREFIX) @@ -32,8 +32,20 @@ if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) set(CMAKE_INSTALL_SO_NO_EXE "1") endif() -if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/nestor/Develop/M3C/utils/libmsym/CMakeFiles/CMakeRelink.dir/molecule.symmetrize") +if("${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT) + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + file(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" + RPATH "") + endif() + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/natalia/Develop/M3C/utils/molecule.symmetrize") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + if(CMAKE_INSTALL_DO_STRIP) + execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/molecule.symmetrize") + endif() + endif() endif() if(CMAKE_INSTALL_COMPONENT) @@ -44,5 +56,5 @@ endif() string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT "${CMAKE_INSTALL_MANIFEST_FILES}") -file(WRITE "/home/nestor/Develop/M3C/utils/libmsym/${CMAKE_INSTALL_MANIFEST}" +file(WRITE "/home/natalia/Develop/M3C/utils/libmsym/${CMAKE_INSTALL_MANIFEST}" "${CMAKE_INSTALL_MANIFEST_CONTENT}") From 269c08ba85029d3268c1393fc8073b403b22ad48 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 8 Mar 2020 11:37:28 +0100 Subject: [PATCH 49/57] Examples directory included --- examples/ts/TS-examples/C2.m3c | 69 ++++++++++++++++++++++ examples/ts/TS-examples/C2ts.q0.m1-1.rxyz | 10 ++++ examples/ts/TS-examples/C3.m3c | 71 +++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 examples/ts/TS-examples/C2.m3c create mode 100644 examples/ts/TS-examples/C2ts.q0.m1-1.rxyz create mode 100644 examples/ts/TS-examples/C3.m3c diff --git a/examples/ts/TS-examples/C2.m3c b/examples/ts/TS-examples/C2.m3c new file mode 100644 index 0000000..22b92af --- /dev/null +++ b/examples/ts/TS-examples/C2.m3c @@ -0,0 +1,69 @@ +BEGIN EXCITATION_ENERGY_SCAN + excitationEnergy = 0:12:13 # dE = 1.0 eV +END EXCITATION_ENERGY_SCAN + +BEGIN GOPTIONS + systemRadius = 10.0 + overlappingRadius = 0.2 + + useRandomWalkers = FALSE + randomWalkStepRadius = 1.0 + + useZPECorrection = FALSE + useSpinConservationRules = FALSE + + angularMomentumCouplingScheme = JJL + #debugLevel = 3 +END GOPTIONS + +BEGIN MARKOV_CHAIN + task = 5*V,T,R,S:0,5*V,T,R,S:-1:1 + burnInFraction = 0.0 + + reactives = C2(s1) + excitationEnergy = 7.0 + + tracking = weight + +# numberOfExperiments = 6 +# numberOfEvents = 100000 + numberOfExperiments = 3 +# numberOfEvents = 50000 + numberOfEvents = 20000 +# historyFileFrequency = 100 + historyFileFrequency = 1 + +# geometryHistoryFilePrefix = geom + energyHistoryFile = energy.dat + weightHistoryFile = weight.dat +# JHistoryFile = J.dat +# LHistoryFile = L.dat + histogramFile = histogram.dat +END MARKOV_CHAIN + +BEGIN FRAGMENTS_DATABASE + + store = /home/nestor/Develop/M3C-store/master/6-311++G.3df.2p/ccsdt + reference = C2(s1) + + #-------------------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib + #-------------------------------------------------------------------------------------- + C(s1) 0 1 5 1 C.q0.m1-1.rxyz -1026.574168 # ¹D (2s²2p²) + C(t1) 0 3 3 1 C.q0.m3-1.rxyz -1028.024016 # ³P (2s²2p²) + + C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz -2062.151541 C(t1)+C(t1) # 6.10351 ^1\Sigma_g^+ + #C2(t1) 0 3 2 2 C2.q0.m3-1.rxyz -2062.058719 C(t1)+C(t1) # 6.01069 ^3\Pi_u + #-------------------------------------------------------------------------------------- +END FRAGMENTS_DATABASE + +BEGIN TRANSITION_STATES_DATABASE + + store = . + + #-------------------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib TS + #-------------------------------------------------------------------------------------- + C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.048032 4.0 C2(s1)<-->C(t1)+C(t1) + #-------------------------------------------------------------------------------------- +END TRANSITION_STATES_DATABASE diff --git a/examples/ts/TS-examples/C2ts.q0.m1-1.rxyz b/examples/ts/TS-examples/C2ts.q0.m1-1.rxyz new file mode 100644 index 0000000..1668844 --- /dev/null +++ b/examples/ts/TS-examples/C2ts.q0.m1-1.rxyz @@ -0,0 +1,10 @@ +2 +Energy = -75.8561424407255 + C 0.823543 0.000000 0.000000 + C -0.823543 0.000000 0.000000 + +FREQUENCIES 1 +1872.9045 + +SYMMETRY D*H +ELECTRONIC_STATE 1-SGG diff --git a/examples/ts/TS-examples/C3.m3c b/examples/ts/TS-examples/C3.m3c new file mode 100644 index 0000000..78bbf8b --- /dev/null +++ b/examples/ts/TS-examples/C3.m3c @@ -0,0 +1,71 @@ +BEGIN EXCITATION_ENERGY_SCAN + excitationEnergy = 0:20:21 # dE = 1.0 eV +END EXCITATION_ENERGY_SCAN + +BEGIN GOPTIONS + systemRadius = 10.0 + overlappingRadius = 0.2 + + useRandomWalkers = FALSE + randomWalkStepRadius = 1.0 + + useZPECorrection = FALSE + useSpinConservationRules = FALSE + + angularMomentumCouplingScheme = JJL + debugLevel = 2 +END GOPTIONS + +BEGIN MARKOV_CHAIN + task = 5*V,T,R,S:0,5*V,T,R,S:-1:1 + burnInFraction = 0.0 + +# reactives = C3(s1) + reactives = C(t1)+C2(s1) + excitationEnergy = 20.0 + + tracking = energy + +# numberOfExperiments = 6 +# numberOfEvents = 100000 + numberOfExperiments = 3 +# numberOfEvents = 50000 + numberOfEvents = 30000 + historyFileFrequency = 100 + +# geometryHistoryFilePrefix = geom + energyHistoryFile = energy.dat + weightHistoryFile = weight.dat +# JHistoryFile = J.dat +# LHistoryFile = L.dat + histogramFile = histogram.dat +END MARKOV_CHAIN + +BEGIN FRAGMENTS_DATABASE + + store = /home/nestor/Develop/M3C-store/master/6-311++G.3df.2p/ccsdt + reference = C3(s1) + + #-------------------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib + #-------------------------------------------------------------------------------------- + C(s1) 0 1 5 1 C.q0.m1-1.rxyz -1026.574168 # ¹D (2s²2p²) + C(t1) 0 3 3 1 C.q0.m3-1.rxyz -1028.024016 # ³P (2s²2p²) + + C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz -2062.151541 C(t1)+C(t1) # 6.10351 ^1\Sigma_g^+ + C2(t1) 0 3 2 2 C2.q0.m3-1.rxyz -2062.058719 C(t1)+C(t1) # 6.01069 ^3\Pi_u + + C3(s1) 0 1 1 2 C3.q0.m1-1.rxyz -3097.545476 C(t1)+C2(s1) # 7.36992 D*H, 1-SGG + #-------------------------------------------------------------------------------------- +END FRAGMENTS_DATABASE + +BEGIN TRANSITION_STATES_DATABASE + + store = . + + #-------------------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib TS + #-------------------------------------------------------------------------------------- + C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2064.151541 4.0 C2(s1)<-->C(t1)+C(t1) + #-------------------------------------------------------------------------------------- +END TRANSITION_STATES_DATABASE From 0f27436815d02225519572af8673d4e1427dc8fd Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 8 Mar 2020 21:30:33 +0100 Subject: [PATCH 50/57] First trial of fixing the cyclic dependency. --- src/FragmentsDB.f90 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index 3baaa84..5e5f462 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -364,6 +364,8 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Only for transition states. They are neccessary to calculate the right label (mass sorted) type(FragmentsList) :: reactives type(FragmentsList) :: products +! type(Fragment), allocatable :: reactives(:) +! type(Fragment), allocatable :: products(:) if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -405,11 +407,13 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) call reactives.init( size(tokens3) ) +! allocate( reactives(size(tokens3)) ) do j=1,size(tokens3) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then reactives.clusters(j) = this.clusters(k) +! reactives(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -418,11 +422,13 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) call products.init( size(tokens3) ) +! allocate( products(size(tokens3)) ) do j=1,size(tokens3) do k=1,size(this.clusters) if( trim(tokens3(j)) == this.clusters(k).label() ) then products.clusters(j) = this.clusters(k) +! products(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -450,6 +456,9 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) call GOptions_section( "END TRANSITION_STATES DATABASE INITIALIZATION", indent=1 ) +! deallocate(reactives) +! deallocate(products) + end subroutine setTransitionStatesTable !> From 14256adef41551280fcd02dd6ef9ffcd6dd8948c Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sun, 8 Mar 2020 21:45:34 +0100 Subject: [PATCH 51/57] Improvement of examples --- examples/ts/TS-examples/C.q0.m1-1.rxyz | 8 ++++++++ examples/ts/TS-examples/C.q0.m3-1.rxyz | 8 ++++++++ examples/ts/TS-examples/C2.m3c | 7 ++++--- examples/ts/TS-examples/C2.q0.m1-1.rxyz | 10 ++++++++++ examples/ts/TS-examples/C2.q0.m3-1.rxyz | 10 ++++++++++ examples/ts/TS-examples/C3.m3c | 4 ++-- examples/ts/TS-examples/C3.q0.m1-1.rxyz | 14 ++++++++++++++ 7 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 examples/ts/TS-examples/C.q0.m1-1.rxyz create mode 100644 examples/ts/TS-examples/C.q0.m3-1.rxyz create mode 100644 examples/ts/TS-examples/C2.q0.m1-1.rxyz create mode 100644 examples/ts/TS-examples/C2.q0.m3-1.rxyz create mode 100644 examples/ts/TS-examples/C3.q0.m1-1.rxyz diff --git a/examples/ts/TS-examples/C.q0.m1-1.rxyz b/examples/ts/TS-examples/C.q0.m1-1.rxyz new file mode 100644 index 0000000..87d71e5 --- /dev/null +++ b/examples/ts/TS-examples/C.q0.m1-1.rxyz @@ -0,0 +1,8 @@ +1 +Energy = -37.7258911420 + C 0.00000000 0.00000000 0.00000000 + +FREQUENCIES 0 + +SYMMETRY R3 +ELECTRONIC_STATE 1-D diff --git a/examples/ts/TS-examples/C.q0.m3-1.rxyz b/examples/ts/TS-examples/C.q0.m3-1.rxyz new file mode 100644 index 0000000..c64a6bd --- /dev/null +++ b/examples/ts/TS-examples/C.q0.m3-1.rxyz @@ -0,0 +1,8 @@ +1 +Energy = -37.7791720550 + C 0.00000000 0.00000000 0.00000000 + +FREQUENCIES 0 + +SYMMETRY R3 +ELECTRONIC_STATE 3-P diff --git a/examples/ts/TS-examples/C2.m3c b/examples/ts/TS-examples/C2.m3c index 22b92af..0c5b563 100644 --- a/examples/ts/TS-examples/C2.m3c +++ b/examples/ts/TS-examples/C2.m3c @@ -21,7 +21,7 @@ BEGIN MARKOV_CHAIN burnInFraction = 0.0 reactives = C2(s1) - excitationEnergy = 7.0 + excitationEnergy = 10.0 tracking = weight @@ -39,11 +39,12 @@ BEGIN MARKOV_CHAIN # JHistoryFile = J.dat # LHistoryFile = L.dat histogramFile = histogram.dat + debugLevel = 4 END MARKOV_CHAIN BEGIN FRAGMENTS_DATABASE - store = /home/nestor/Develop/M3C-store/master/6-311++G.3df.2p/ccsdt + store = . reference = C2(s1) #-------------------------------------------------------------------------------------- @@ -64,6 +65,6 @@ BEGIN TRANSITION_STATES_DATABASE #-------------------------------------------------------------------------------------- # Label Z M WL SYM geomFile Eelec maxVib TS #-------------------------------------------------------------------------------------- - C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.048032 4.0 C2(s1)<-->C(t1)+C(t1) + C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.048032 4.0 C2(s1)<-->C(s1)+C(t1) #-------------------------------------------------------------------------------------- END TRANSITION_STATES_DATABASE diff --git a/examples/ts/TS-examples/C2.q0.m1-1.rxyz b/examples/ts/TS-examples/C2.q0.m1-1.rxyz new file mode 100644 index 0000000..bb05d1e --- /dev/null +++ b/examples/ts/TS-examples/C2.q0.m1-1.rxyz @@ -0,0 +1,10 @@ +2 +Energy = -75.7826438160 + C 0.623543 0.000000 0.000000 + C -0.623543 0.000000 0.000000 + +FREQUENCIES 1 +1872.9045 + +SYMMETRY D*H +ELECTRONIC_STATE 1-SGG diff --git a/examples/ts/TS-examples/C2.q0.m3-1.rxyz b/examples/ts/TS-examples/C2.q0.m3-1.rxyz new file mode 100644 index 0000000..440aa4d --- /dev/null +++ b/examples/ts/TS-examples/C2.q0.m3-1.rxyz @@ -0,0 +1,10 @@ +2 +Energy = -75.7792326870 + C 0.650535 0.000000 0.000000 + C -0.650535 0.000000 0.000000 + +FREQUENCIES 1 +1693.6178 + +SYMMETRY D*H +ELECTRONIC_STATE 3-PIU diff --git a/examples/ts/TS-examples/C3.m3c b/examples/ts/TS-examples/C3.m3c index 78bbf8b..15be2c3 100644 --- a/examples/ts/TS-examples/C3.m3c +++ b/examples/ts/TS-examples/C3.m3c @@ -13,7 +13,7 @@ BEGIN GOPTIONS useSpinConservationRules = FALSE angularMomentumCouplingScheme = JJL - debugLevel = 2 +# debugLevel = 2 END GOPTIONS BEGIN MARKOV_CHAIN @@ -43,7 +43,7 @@ END MARKOV_CHAIN BEGIN FRAGMENTS_DATABASE - store = /home/nestor/Develop/M3C-store/master/6-311++G.3df.2p/ccsdt + store = . reference = C3(s1) #-------------------------------------------------------------------------------------- diff --git a/examples/ts/TS-examples/C3.q0.m1-1.rxyz b/examples/ts/TS-examples/C3.q0.m1-1.rxyz new file mode 100644 index 0000000..6f24579 --- /dev/null +++ b/examples/ts/TS-examples/C3.q0.m1-1.rxyz @@ -0,0 +1,14 @@ +3 +Energy = -113.8326552900 + C 1.290898 0.000000 -0.000000 + C -0.000000 -0.000000 0.000000 + C -1.290898 0.000000 -0.000000 + +FREQUENCIES 4 +154.6817 +154.6817 +1226.0212 +2119.4308 + +SYMMETRY D*H +ELECTRONIC_STATE 1-SGG From 0d12ffcf3b051ef18ebea85bdc64fee7300d5011 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 10 Mar 2020 00:39:50 +0100 Subject: [PATCH 52/57] 1) Bug fixed: Cyclic dependence between FragmentsList and FragmentsListDB 2) Some refactoring of the code --- .../{ts/TS-examples => TS}/C.q0.m1-1.rxyz | 0 .../{ts/TS-examples => TS}/C.q0.m3-1.rxyz | 0 examples/{ts/TS-examples => TS}/C2.m3c | 14 +- .../{ts/TS-examples => TS}/C2.q0.m1-1.rxyz | 0 .../{ts/TS-examples => TS}/C2.q0.m3-1.rxyz | 0 .../{ts/TS-examples => TS}/C2ts.q0.m1-1.rxyz | 0 examples/{ts/TS-examples => TS}/C3.m3c | 0 .../{ts/TS-examples => TS}/C3.q0.m1-1.rxyz | 0 src/Fragment.f90 | 65 +++++- src/FragmentsDB.f90 | 91 ++++++--- src/FragmentsList.f90 | 2 +- src/FragmentsListBase.f90 | 57 +----- src/MarkovChain.f90 | 14 +- src/Reactor.f90 | 185 +++--------------- 14 files changed, 176 insertions(+), 252 deletions(-) rename examples/{ts/TS-examples => TS}/C.q0.m1-1.rxyz (100%) rename examples/{ts/TS-examples => TS}/C.q0.m3-1.rxyz (100%) rename examples/{ts/TS-examples => TS}/C2.m3c (74%) rename examples/{ts/TS-examples => TS}/C2.q0.m1-1.rxyz (100%) rename examples/{ts/TS-examples => TS}/C2.q0.m3-1.rxyz (100%) rename examples/{ts/TS-examples => TS}/C2ts.q0.m1-1.rxyz (100%) rename examples/{ts/TS-examples => TS}/C3.m3c (100%) rename examples/{ts/TS-examples => TS}/C3.q0.m1-1.rxyz (100%) diff --git a/examples/ts/TS-examples/C.q0.m1-1.rxyz b/examples/TS/C.q0.m1-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C.q0.m1-1.rxyz rename to examples/TS/C.q0.m1-1.rxyz diff --git a/examples/ts/TS-examples/C.q0.m3-1.rxyz b/examples/TS/C.q0.m3-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C.q0.m3-1.rxyz rename to examples/TS/C.q0.m3-1.rxyz diff --git a/examples/ts/TS-examples/C2.m3c b/examples/TS/C2.m3c similarity index 74% rename from examples/ts/TS-examples/C2.m3c rename to examples/TS/C2.m3c index 0c5b563..576b381 100644 --- a/examples/ts/TS-examples/C2.m3c +++ b/examples/TS/C2.m3c @@ -13,7 +13,7 @@ BEGIN GOPTIONS useSpinConservationRules = FALSE angularMomentumCouplingScheme = JJL - #debugLevel = 3 +# debugLevel = 3 END GOPTIONS BEGIN MARKOV_CHAIN @@ -29,7 +29,7 @@ BEGIN MARKOV_CHAIN # numberOfEvents = 100000 numberOfExperiments = 3 # numberOfEvents = 50000 - numberOfEvents = 20000 + numberOfEvents = 2000 # historyFileFrequency = 100 historyFileFrequency = 1 @@ -39,7 +39,6 @@ BEGIN MARKOV_CHAIN # JHistoryFile = J.dat # LHistoryFile = L.dat histogramFile = histogram.dat - debugLevel = 4 END MARKOV_CHAIN BEGIN FRAGMENTS_DATABASE @@ -50,11 +49,8 @@ BEGIN FRAGMENTS_DATABASE #-------------------------------------------------------------------------------------- # Label Z M WL SYM geomFile Eelec maxVib #-------------------------------------------------------------------------------------- - C(s1) 0 1 5 1 C.q0.m1-1.rxyz -1026.574168 # ¹D (2s²2p²) - C(t1) 0 3 3 1 C.q0.m3-1.rxyz -1028.024016 # ³P (2s²2p²) - - C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz -2062.151541 C(t1)+C(t1) # 6.10351 ^1\Sigma_g^+ - #C2(t1) 0 3 2 2 C2.q0.m3-1.rxyz -2062.058719 C(t1)+C(t1) # 6.01069 ^3\Pi_u + C(t1) 0 3 3 1 C.q0.m3-1.rxyz 3.0 # ³P (2s²2p²) + C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz 0.0 C(t1)+C(t1) # 6.0 ^1\Sigma_g^+ #-------------------------------------------------------------------------------------- END FRAGMENTS_DATABASE @@ -65,6 +61,6 @@ BEGIN TRANSITION_STATES_DATABASE #-------------------------------------------------------------------------------------- # Label Z M WL SYM geomFile Eelec maxVib TS #-------------------------------------------------------------------------------------- - C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.048032 4.0 C2(s1)<-->C(s1)+C(t1) + C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz 8.0 4.0 C2(s1)<-->C(t1)+C(t1) #-------------------------------------------------------------------------------------- END TRANSITION_STATES_DATABASE diff --git a/examples/ts/TS-examples/C2.q0.m1-1.rxyz b/examples/TS/C2.q0.m1-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C2.q0.m1-1.rxyz rename to examples/TS/C2.q0.m1-1.rxyz diff --git a/examples/ts/TS-examples/C2.q0.m3-1.rxyz b/examples/TS/C2.q0.m3-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C2.q0.m3-1.rxyz rename to examples/TS/C2.q0.m3-1.rxyz diff --git a/examples/ts/TS-examples/C2ts.q0.m1-1.rxyz b/examples/TS/C2ts.q0.m1-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C2ts.q0.m1-1.rxyz rename to examples/TS/C2ts.q0.m1-1.rxyz diff --git a/examples/ts/TS-examples/C3.m3c b/examples/TS/C3.m3c similarity index 100% rename from examples/ts/TS-examples/C3.m3c rename to examples/TS/C3.m3c diff --git a/examples/ts/TS-examples/C3.q0.m1-1.rxyz b/examples/TS/C3.q0.m1-1.rxyz similarity index 100% rename from examples/ts/TS-examples/C3.q0.m1-1.rxyz rename to examples/TS/C3.q0.m1-1.rxyz diff --git a/src/Fragment.f90 b/src/Fragment.f90 index 59ca9ad..d868191 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -69,6 +69,7 @@ module Fragment_ private public :: & + Fragment_getLabelFragments, & Fragment_test type, public, extends( Molecule ):: Fragment @@ -110,7 +111,7 @@ module Fragment_ procedure :: copyFragment final :: destroyFragment - procedure, private :: updateFormula + procedure, private :: updateLabel procedure :: label ! procedure, private :: loadRXYZ @@ -291,6 +292,7 @@ subroutine fromMassTableRow( this, strRow, id, store ) ! if( GOptions_printLevel >= 4 ) then write(IO_STDOUT,"(A)") "" +! write(IO_STDOUT,"(4X,A22,I15)") "id = ", this.id write(IO_STDOUT,"(4X,A22,A)") "file name = ", this.fileName write(IO_STDOUT,"(4X,A22,A)") "name = ", this.name write(IO_STDOUT,"(4X,A22,A)") "formula = ", trim(this.chemicalFormula()) @@ -388,7 +390,7 @@ end subroutine destroyFragment !> !! @brief !! - subroutine updateFormula( this ) + subroutine updateLabel( this ) class(Fragment) :: this character(100), allocatable :: tokens(:) @@ -400,7 +402,7 @@ subroutine updateFormula( this ) this.label_ = trim(tokens(1)) deallocate( tokens ) - end subroutine updateFormula + end subroutine updateLabel !> !! @brief @@ -416,7 +418,7 @@ function label( this, details ) result( output ) if( present(details) ) effDetails = details if( .not. this.testLabel_ ) then - call this.updateFormula() + call this.updateLabel() this.testLabel_ = .true. end if @@ -1297,6 +1299,61 @@ end function spinAvailable ! endIf ! Return ! End + + !> + !! @brief + !! + subroutine Fragment_getLabelFragments( clusters, label, dlabel, idSorted ) + type(Fragment), allocatable, intent(in) :: clusters(:) + character(200), intent(out) :: label + character(200), intent(out) :: dlabel + integer, allocatable, intent(out), optional :: idSorted(:) + + integer :: i + real(8), allocatable :: massVec(:) ! @todo Hay que hacer el Math_sort para enteros + integer, allocatable :: effIdSorted(:) + + allocate( massVec(size(clusters)) ) + allocate( effIdSorted(size(clusters)) ) + + do i=1,size(clusters) + + massVec(i) = clusters(i).mass()/amu & + + clusters(i).charge/10.0 & + + clusters(i).multiplicity/100.0_8 + +! massVec(i) = 10000000*clusters(i).mass()/amu + 1000000*clusters(i).nAtoms() + 100*clusters(i).charge & +! + clusters(i).multiplicity + + end do + + call Math_sort( massVec, effIdSorted ) + + label = "" + dlabel = "" + do i=1,size(clusters) + if( i /= size(clusters) ) then + label = trim(label)//trim(clusters( effIdSorted(i) ).label( details=.false. ))//"+" + dlabel = trim(dlabel)//trim(clusters( effIdSorted(i) ).label( details=.true. ))//"+" + else + label = trim(label)//trim(clusters( effIdSorted(i) ).label( details=.false. )) + dlabel = trim(dlabel)//trim(clusters( effIdSorted(i) ).label( details=.true. )) + end if + end do + + if( present(idSorted) ) then + if( allocated(idSorted) .and. size(idSorted) == size(effIdSorted) ) then + idSorted = effIdSorted + else + if( allocated(idSorted) ) deallocate(idSorted) + allocate( idSorted(size(clusters)) ) + idSorted = effIdSorted + end if + end if + + deallocate( massVec ) + deallocate( effIdSorted ) + end subroutine Fragment_getLabelFragments !> !! @brief Test method diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index 5e5f462..2e8af74 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -62,7 +62,6 @@ module FragmentsDB_ use StringIntegerMap_ use Fragment_ - use FragmentsList_ use ModelPotential_ use GOptionsM3C_ @@ -102,7 +101,8 @@ module FragmentsDB_ procedure, private :: checkPotentials final :: destroyFragmentsDB procedure :: nMolecules - procedure :: getIdFromName + procedure :: getIdClusterFromLabel + procedure :: getIdTransitionStateFromLabel procedure :: getEelecFromName procedure :: extendFragmentsListName procedure :: potential @@ -359,13 +359,19 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) integer :: i, j, k, n character(100), allocatable :: tokens(:), tokens2(:), tokens3(:) + type(String) :: path real(8) :: rBuffer ! Only for transition states. They are neccessary to calculate the right label (mass sorted) - type(FragmentsList) :: reactives - type(FragmentsList) :: products -! type(Fragment), allocatable :: reactives(:) -! type(Fragment), allocatable :: products(:) +! type(FragmentsList) :: reactives +! type(FragmentsList) :: products + logical :: useDetailsInLabel + type(Fragment), allocatable :: reactives(:) + type(Fragment), allocatable :: products(:) + character(200) :: reactivesLabel, reactivesdLabel + character(200) :: productsLabel, productsdLabel + + useDetailsInLabel = .true. if( allocated(this.transitionState) ) deallocate( this.transitionState ) allocate( this.transitionState(size(transitionStatesTable)) ) @@ -403,17 +409,18 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) ! Choosing the reactives and products !------------------------------------------ if( size(tokens) >= 9 .and. this.transitionState(i).nAtoms() /= 1 ) then - call FString_split( trim(adjustl(tokens(9))), tokens2, "<-->" ) + path = trim(adjustl(tokens(9))) + call path.split( tokens2, "<-->" ) call FString_split( trim(adjustl(tokens2(1))), tokens3, "+" ) - call reactives.init( size(tokens3) ) -! allocate( reactives(size(tokens3)) ) +! call reactives.init( size(tokens3) ) + allocate( reactives(size(tokens3)) ) do j=1,size(tokens3) do k=1,size(this.clusters) - if( trim(tokens3(j)) == this.clusters(k).label() ) then - reactives.clusters(j) = this.clusters(k) -! reactives(j) = this.clusters(k) + if( trim(tokens3(j)) == this.clusters(k).label( details=useDetailsInLabel ) ) then +! reactives.clusters(j) = this.clusters(k) + reactives(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -421,14 +428,14 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens3 ) call FString_split( trim(adjustl(tokens2(2))), tokens3, "+" ) - call products.init( size(tokens3) ) -! allocate( products(size(tokens3)) ) +! call products.init( size(tokens3) ) + allocate( products(size(tokens3)) ) do j=1,size(tokens3) do k=1,size(this.clusters) - if( trim(tokens3(j)) == this.clusters(k).label() ) then - products.clusters(j) = this.clusters(k) -! products(j) = this.clusters(k) + if( trim(tokens3(j)) == this.clusters(k).label( details=useDetailsInLabel ) ) then +! products.clusters(j) = this.clusters(k) + products(j) = this.clusters(k) this.involvedInTS(k) = .true. end if end do @@ -437,9 +444,16 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) deallocate( tokens2 ) - write(*,"(4X,A22,A)") "Path = ", trim(reactives.label())//"<-->"//trim(products.label()) - call this.str2id_TS.insert( FString_toString(trim(reactives.label())//"<-->"//trim(products.label())), i ) - call this.str2id_TS.insert( FString_toString(trim(products.label())//"<-->"//trim(reactives.label())), i ) + call Fragment_getLabelFragments( reactives, reactivesLabel, reactivesdLabel ) + call Fragment_getLabelFragments( products, productsLabel, productsdLabel ) + + write(*,"(4X,A22,A)") "Path = ", trim(path.fstr) +! call this.str2id_TS.insert( FString_toString(trim(reactivesLabel)//"<-->"//trim(productsLabel)), i ) +! call this.str2id_TS.insert( FString_toString(trim(productsLabel)//"<-->"//trim(reactivesLabel)), i ) +! write(*,"(4X,A22,A)") "Interpreted Path = ", trim(reactivesLabel)//"<-->"//trim(productsLabel) + call this.str2id_TS.insert( FString_toString(trim(reactivesdLabel)//"<-->"//trim(productsdLabel)), i ) + call this.str2id_TS.insert( FString_toString(trim(productsdLabel)//"<-->"//trim(reactivesdLabel)), i ) + write(*,"(4X,A22,A)") "Interpreted Path = ", trim(reactivesdLabel)//"<-->"//trim(productsdLabel) else call GOptions_error( & @@ -679,8 +693,8 @@ subroutine setPotentialTable( this, potentialTable, coulombContribution ) if( size(cols) >= 2 ) then call FString_split( cols(1), tokens, "+" ) - idR1 = this.getIdFromName( tokens(1) ) - idR2 = this.getIdFromName( tokens(2) ) + idR1 = this.getIdClusterFromLabel( tokens(1) ) + idR2 = this.getIdClusterFromLabel( tokens(2) ) write(*,"(X,A10,A10,5X,2I3)", advance="no") & this.clusters(idR1).name, this.clusters(idR2).name, idR1, idR2 @@ -908,7 +922,7 @@ end function nMolecules !> !! @brief !! - function getIdFromName( this, name ) result( output ) + function getIdClusterFromLabel( this, name ) result( output ) class(FragmentsDB), intent(in) :: this character(*), intent(in) :: name integer :: output @@ -925,9 +939,28 @@ function getIdFromName( this, name ) result( output ) call GOptions_error( & "The cluster --"//trim(adjustl(name))//"-- doesn't exist in the database", & - "FragmentsDB.getIdFromName()" & + "FragmentsDB.getIdClusterFromLabel()" & ) - end function getIdFromName + end function getIdClusterFromLabel + + !> + !! @brief + !! + function getIdTransitionStateFromLabel( this, name ) result( output ) + class(FragmentsDB), intent(in) :: this + character(*), intent(in) :: name + integer :: output + + if( this.str2id_TS.contains( FString_toString(name) ) ) then + output = this.str2id_TS.at( FString_toString(name) ) + else +! call GOptions_error( & +! "The transition state --"//trim(adjustl(name))//"-- doesn't exist in the database", & +! "FragmentsDB.getIdTransitionStateFromLabel()" & +! ) + output = -1 + end if + end function getIdTransitionStateFromLabel !> !! @brief @@ -949,10 +982,10 @@ function getEelecFromName( this, name ) result( output ) if( size(subTokens) < 2 ) then - id = this.getIdFromName( subTokens(1) ) + id = this.getIdClusterFromLabel( subTokens(1) ) factor = 1 else - id = this.getIdFromName( subTokens(2) ) + id = this.getIdClusterFromLabel( subTokens(2) ) factor = FString_toInteger( subTokens(1) ) end if @@ -1193,7 +1226,7 @@ subroutine FragmentsDB_test() ! call FString_split( tokens(i), items, "," ) ! ! do j=1,size(items) -! write(*,*) i, trim(adjustl(items(j))), db.getIdFromName( items(j) ) +! write(*,*) i, trim(adjustl(items(j))), db.getIdClusterFromLabel( items(j) ) ! end do ! write(*,*) "" ! end do @@ -1219,7 +1252,7 @@ subroutine FragmentsDB_test() ! r = 0.0_8 ! do while( r <= 10.0_8 ) -! write(*,*) r, db.potential( db.getIdFromName( "tC1" ), db.getIdFromName( "tC1" ), r*angs )/eV +! write(*,*) r, db.potential( db.getIdClusterFromLabel( "tC1" ), db.getIdClusterFromLabel( "tC1" ), r*angs )/eV ! r = r + 0.2 ! end do diff --git a/src/FragmentsList.f90 b/src/FragmentsList.f90 index 0bfbd6c..c145292 100644 --- a/src/FragmentsList.f90 +++ b/src/FragmentsList.f90 @@ -1324,7 +1324,7 @@ subroutine FragmentsList_test() ! call FString_split( tokens(i), items, "," ) ! ! do j=1,size(items) -! write(*,*) i, trim(adjustl(items(j))), RigidMoleculeDatabase_instance.getIdFromName( items(j) ) +! write(*,*) i, trim(adjustl(items(j))), RigidMoleculeDatabase_instance.getIdClusterFromLabel( items(j) ) ! end do ! write(*,*) "" ! end do diff --git a/src/FragmentsListBase.f90 b/src/FragmentsListBase.f90 index 9c8b159..0e3c551 100644 --- a/src/FragmentsListBase.f90 +++ b/src/FragmentsListBase.f90 @@ -77,7 +77,7 @@ module FragmentsListBase_ type, abstract, public :: FragmentsListBase type(Fragment), allocatable :: clusters(:) !< Fragment list - integer, allocatable :: idSorted(:) !< Position of the molecule sorted by mass. It is calculated in updateFormula procedure + integer, allocatable :: idSorted(:) !< Position of the molecule sorted by mass. It is calculated in updateLabel procedure !< this.clusters(i) ----> this.clusters( this.idSorted(i) ) real(8) :: diagInertiaTensor(3) !< Main inertia tensor components [ Ixx, Iyy, Izz ]. It is calculated into updateInertiaTensor procedure @@ -109,8 +109,6 @@ module FragmentsListBase_ logical :: forceRandomCenters !< Fuerza a utilizar randomCenters en el siguiente llamado a changeGeometryFragmentsListBase logical :: forceInitializing !< Fuerza a utilizar initialGuessFragmentsListBase - integer :: totalComposition( AtomicElementsDB_nElems ) !< [ n1, n2, ..., nN ] n=numberOfAtomsWithZ, pos = atomicNumber - real(8) :: L_(3) ! Orbital angular momentum integer, allocatable :: currentProducts(:,:) !< This allows to get the current potential energy surface @see updateIntermolecularPotential @@ -130,7 +128,7 @@ module FragmentsListBase_ procedure, NON_OVERRIDABLE :: nAtoms procedure, NON_OVERRIDABLE :: charge procedure, NON_OVERRIDABLE :: mass - procedure, private :: updateFormula + procedure, private :: updateLabel procedure, NON_OVERRIDABLE :: label generic :: set => setFromFragment procedure, NON_OVERRIDABLE :: setFromFragment @@ -238,8 +236,6 @@ subroutine initFragmentsListBase( this, nMolecules ) this.forceRandomCenters = .true. this.forceInitializing = .true. - this.totalComposition = -1 - this.L_ = 0.0_8 if( allocated(this.currentProducts) ) deallocate(this.currentProducts) @@ -295,8 +291,6 @@ subroutine copyFragmentsListBase( this, other ) this.forceRandomCenters = other.forceRandomCenters this.forceInitializing = other.forceInitializing - this.totalComposition = other.totalComposition - this.L_ = other.L_ if( allocated(this.currentProducts) ) deallocate(this.currentProducts) @@ -451,7 +445,7 @@ subroutine loadXYZ( this, fileName ) y = FString_toReal( tokens(3) )*angs z = FString_toReal( tokens(4) )*angs - idClus = FragmentsDB_instance.getIdFromName( name.fstr ) + idClus = FragmentsDB_instance.getIdClusterFromLabel( name.fstr ) call this.setFromFragment( i, FragmentsDB_instance.clusters( idClus ) ) call this.clusters(i).setCenter( [ x, y, z ] ) @@ -527,45 +521,12 @@ end function mass !> !! @brief !! - subroutine updateFormula( this ) + subroutine updateLabel( this ) class(FragmentsListBase) :: this - integer :: i - real(8), allocatable :: massVec(:) ! @todo Hay que hacer el Math_sort para enteros - - allocate( massVec(size(this.clusters)) ) - - this.totalComposition = 0 - do i=1,size(this.clusters) - - massVec(i) = this.clusters(i).mass()/amu & - + this.clusters(i).charge/10.0 & - + this.clusters(i).multiplicity/100.0_8 - -! massVec(i) = 10000000*this.clusters(i).mass()/amu + 1000000*this.clusters(i).nAtoms() + 100*this.clusters(i).charge & -! + this.clusters(i).multiplicity - - this.totalComposition = this.totalComposition + this.clusters( i ).composition - end do - - call Math_sort( massVec, this.idSorted ) - - this.label_ = "" - this.dlabel_ = "" - do i=1,size(this.clusters) - if( i /= size(this.clusters) ) then - this.label_ = trim(this.label_)//trim(this.clusters( this.idSorted(i) ).label( details=.false. ))//"+" - this.dlabel_ = trim(this.dlabel_)//trim(this.clusters( this.idSorted(i) ).label( details=.true. ))//"+" - else - this.label_ = trim(this.label_)//trim(this.clusters( this.idSorted(i) ).label( details=.false. )) - this.dlabel_ = trim(this.dlabel_)//trim(this.clusters( this.idSorted(i) ).label( details=.true. )) - end if - end do - + call Fragment_getLabelFragments( this.clusters, this.label_, this.dlabel_, this.idSorted ) this.testLabel_ = .true. - - deallocate( massVec ) - end subroutine updateFormula + end subroutine updateLabel !> !! @brief @@ -581,7 +542,7 @@ function label( this, details ) result( output ) if( present(details) ) effDetails = details if( .not. this.testLabel_ ) then - call this.updateFormula() + call this.updateLabel() end if if( effDetails ) then @@ -705,7 +666,7 @@ subroutine initialGuessFragmentsListBase( this ) call this.orient() - call this.updateFormula() + call this.updateLabel() call this.updateLogGFactor() @@ -2372,7 +2333,7 @@ subroutine executeRadiusOptimization( this, iParser ) call this.init( size(reactiveTokens) ) do i=1,size(reactiveTokens) - iBuffer = FragmentsDB_instance.getIdFromName( reactiveTokens(i) ) + iBuffer = FragmentsDB_instance.getIdClusterFromLabel( reactiveTokens(i) ) call this.set( i, FragmentsDB_instance.clusters(iBuffer) ) end do end if diff --git a/src/MarkovChain.f90 b/src/MarkovChain.f90 index 2c8e433..655ebb1 100644 --- a/src/MarkovChain.f90 +++ b/src/MarkovChain.f90 @@ -384,7 +384,7 @@ subroutine run( this, reactives ) write(6,"(A)") "#------------------------------------" write(6,"(A)") "# ENERGY HISTORY" write(6,"(A)") "#------------------------------------" - write(6,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "formula" + write(6,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "label" write(6,"(A1,3X,5A15,5X,A)") "#", "eV", "eV", "eV", "eV", "" write(6,"(A1,3X,5A15,5X,A)") "#", "-------", "--------", "-------", "-----", "-------" @@ -393,7 +393,7 @@ subroutine run( this, reactives ) write(6,"(A)") "#------------------------------------" write(6,"(A)") "# WEIGHT HISTORY" write(6,"(A)") "#------------------------------------" - write(6,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "formula" + write(6,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "label" write(6,"(A1,3X,6A15,5X,A)") "#", "arb.", "arb.", "arb.", "arb.", "arb.", "arb.", "" write(6,"(A1,3X,6A15,5X,A)") "#", "-------", "-------", "--------", "--------", "--------", "-------", "-------" @@ -821,7 +821,7 @@ end subroutine showAverHistogram ! write(unit,"(A)") "#------------------------------------" ! write(unit,"(A)") "# ENERGY HISTORY" ! write(unit,"(A)") "#------------------------------------" -! write(unit,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "formula" +! write(unit,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "label" ! write(unit,"(A1,3X,5A15,5X,A)") "#", "eV", "eV", "eV", "eV", "" ! write(unit,"(A1,3X,5A15,5X,A)") "#", "-------", "--------", "-------", "-----", "-------" ! @@ -870,7 +870,7 @@ end subroutine showAverHistogram ! write(unit,"(A)") "#------------------------------------" ! write(unit,"(A)") "# WEIGHT HISTORY" ! write(unit,"(A)") "#------------------------------------" -! write(unit,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "formula" +! write(unit,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "label" ! write(unit,"(A1,3X,6A15,5X,A)") "#", "arb.", "arb.", "arb.", "arb.", "arb.", "arb.", "" ! write(unit,"(A1,3X,6A15,5X,A)") "#", "-------", "-------", "--------", "--------", "--------", "-------", "-------" ! @@ -1382,7 +1382,7 @@ subroutine execute( this, iParser ) call reactives.init( size(reactiveTokens) ) do i=1,size(reactiveTokens) - iBuffer = FragmentsDB_instance.getIdFromName( reactiveTokens(i) ) + iBuffer = FragmentsDB_instance.getIdClusterFromLabel( reactiveTokens(i) ) call reactives.set( i, FragmentsDB_instance.clusters(iBuffer) ) end do end if @@ -1420,7 +1420,7 @@ subroutine execute( this, iParser ) write(this.energyHistoryFile.unit,"(A)") "#------------------------------------" write(this.energyHistoryFile.unit,"(A)") "# ENERGY HISTORY" write(this.energyHistoryFile.unit,"(A)") "#------------------------------------" - write(this.energyHistoryFile.unit,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "formula" + write(this.energyHistoryFile.unit,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "label" write(this.energyHistoryFile.unit,"(A1,3X,5A15,5X,A)") "#", "eV", "eV", "eV", "eV", "" write(this.energyHistoryFile.unit,"(A1,3X,5A15,5X,A)") "#", "-------", "--------", "-------", "-----", "-------" @@ -1434,7 +1434,7 @@ subroutine execute( this, iParser ) write(this.weightHistoryFile.unit,"(A)") "#------------------------------------" write(this.weightHistoryFile.unit,"(A)") "# WEIGHT HISTORY" write(this.weightHistoryFile.unit,"(A)") "#------------------------------------" - write(this.weightHistoryFile.unit,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "formula" + write(this.weightHistoryFile.unit,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "label" write(this.weightHistoryFile.unit,"(A1,3X,6A15,5X,A)") "#", "arb.", "arb.", "arb.", "arb.", "arb.", "arb.", "" write(this.weightHistoryFile.unit,"(A1,3X,6A15,5X,A)") "#", "-------", "-------", "--------", "--------", "--------", "-------", "-------" diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 311f983..3ea3f41 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -495,37 +495,41 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) type(FragmentsList) :: lReactives, lProducts type(String) :: labelTS, label logical :: locatedTS + logical :: useDetailsInLabel + integer :: transitionStateId + + useDetailsInLabel = .true. call reactiveInTS.init( resizeIncrement=reactives.nMolecules() ) call productInTS.init( resizeIncrement=products.nMolecules() ) do i=1,reactives.nMolecules() - id = FragmentsDB_instance.getIdFromName( reactives.clusters(i).label() ) + id = FragmentsDB_instance.getIdClusterFromLabel( reactives.clusters(i).label( details=useDetailsInLabel ) ) if( FragmentsDB_instance.involvedInTS( id ) ) then - call reactiveInTS.append( i ) + call reactiveInTS.append( i ) end if end do do i=1,products.nMolecules() - id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) + id = FragmentsDB_instance.getIdClusterFromLabel( products.clusters(i).label( details=useDetailsInLabel ) ) if( FragmentsDB_instance.involvedInTS( id ) ) then call productInTS.append( i ) end if end do if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then -! write(*,"(A)",advance="no") "Reactives " -! do i=1,reactives.nMolecules() -! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" +! write(*,"(A,A)") "Reactives = ", trim(reactives.label( details=useDetailsInLabel )) +! write(*,"(A)",advance="no") "reactiveInTS = " +! do i=1,reactiveInTS.size() +! write(*,"(A)",advance="no") trim(reactives.clusters(reactiveInTS.data(i)).label( details=useDetailsInLabel ))//"+" ! end do ! write(*,*) "" -! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) -! write(*,"(A)",advance="no") "Products " -! do i=1,products.nMolecules() -! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" +! write(*,"(A,A)") "Products = ", trim(products.label( details=useDetailsInLabel )) +! write(*,"(A)",advance="no") "productInTS = " +! do i=1,productInTS.size() +! write(*,"(A)",advance="no") trim(products.clusters(productInTS.data(i)).label( details=useDetailsInLabel ))//"+" ! end do ! write(*,*) "" -! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) locatedTS = .false. @@ -566,162 +570,34 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) end do - if( trim(lReactives.label()) /= trim(lProducts.label()) ) then + if( trim(lReactives.label( details=useDetailsInLabel )) /= trim(lProducts.label( details=useDetailsInLabel )) ) then - labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) + labelTS = trim(lReactives.label( details=useDetailsInLabel ))//"<-->"//trim(lProducts.label( details=useDetailsInLabel )) if( GOptions_debugLevel >= 2 ) then - write(*,*) " reactives = ", trim(reactives.label()) - write(*,*) " products = ", trim(products.label()) + write(*,*) " reactives = ", trim(reactives.label( details=useDetailsInLabel )) + write(*,*) " products = ", trim(products.label( details=useDetailsInLabel )) write(*,*) " TS located = ", trim(labelTS.fstr) end if - call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) - - call productsTS.set( 1, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) - - ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) - ! En este caso nunca se entra en el if - j=2 - do i=1,products.nMolecules() - do kp=1,size(productInTScomb,dim=2) - label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) - if( label /= trim(products.clusters(i).label()) & - .and. j<=productsTS.nMolecules() ) then - call productsTS.set( j, products.clusters(i) ) - j = j+1 - exit - end if - end do - end do - - if( j==2 ) then - do i=1,products.nMolecules() - if( j<=productsTS.nMolecules() ) then - call productsTS.set( j, products.clusters(i) ) - j = j+1 - end if - end do - end if + transitionStateId = FragmentsDB_instance.getIdTransitionStateFromLabel( trim(labelTS.fstr) ) if( GOptions_debugLevel >= 2 ) then - write(*,*) " products = ", trim(products.label()) - write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + write(*,*) " TS id = ", transitionStateId end if - locatedTS = .true. - exit ! Only one TS is accepted. The one with minimum size - - end if - - end if - - end do - - if( locatedTS ) exit - - end do - - if( locatedTS ) exit - - end do - - if( locatedTS ) exit - - end do - - end if - - if( GOptions_debugLevel >= 2 ) then - write(*,*) "" - end if - - if( allocated(reactiveInTScomb) ) deallocate( reactiveInTScomb ) - if( allocated(productInTScomb) ) deallocate( productInTScomb ) - - do i=1,products.nMolecules() - id = FragmentsDB_instance.getIdFromName( products.clusters(i).label() ) - if( FragmentsDB_instance.involvedInTS( id ) ) then - call productInTS.append( i ) - end if - end do - - if( .not. reactiveInTS.isEmpty() .and. .not. productInTS.isEmpty() ) then -! write(*,"(A)",advance="no") "Reactives " -! do i=1,reactives.nMolecules() -! write(*,"(A)",advance="no") trim(reactives.clusters(i).label())//"+" -! end do -! write(*,*) "" -! write(*,*) "reactiveInTS = ", reactiveInTS.data(1:reactiveInTS.size()) -! write(*,"(A)",advance="no") "Products " -! do i=1,products.nMolecules() -! write(*,"(A)",advance="no") trim(products.clusters(i).label())//"+" -! end do -! write(*,*) "" -! write(*,*) "productInTS = ", productInTS.data(1:productInTS.size()) - - locatedTS = .false. - - do ir=1,reactiveInTS.size() - call Math_combinations( reactiveInTS.size(), ir, reactiveInTScomb ) - - do jr=1,size(reactiveInTScomb,dim=1) - - nAtomsR = 0 - massNumberR = 0 - do kr=1,size(reactiveInTScomb,dim=2) - massNumberR = massNumberR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).massNumber() - nAtomsR = nAtomsR + reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ).nAtoms() - end do - - do ip=1,productInTS.size() - call Math_combinations( productInTS.size(), ip, productInTScomb ) - - do jp=1,size(productInTScomb,dim=1) - - nAtomsP = 0 - massNumberP = 0 - do kp=1,size(productInTScomb,dim=2) - massNumberP = massNumberP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).massNumber() - nAtomsP = nAtomsP + products.clusters( productInTS.at(productInTScomb(jp,kp)) ).nAtoms() - end do - - if( massNumberR == massNumberP .and. nAtomsR > 1 .and. nAtomsP > 1 ) then - - call lReactives.init( size(reactiveInTScomb,dim=2) ) - call lProducts.init( size(productInTScomb,dim=2) ) - - do kr=1,size(reactiveInTScomb,dim=2) - lReactives.clusters(kr) = reactives.clusters( reactiveInTS.at(reactiveInTScomb(jr,kr)) ) - end do - - do kp=1,size(productInTScomb,dim=2) - lProducts.clusters(kp) = products.clusters( productInTS.at(productInTScomb(jp,kp)) ) - end do - - if( trim(lReactives.label()) /= trim(lProducts.label()) ) then - - labelTS = trim(lReactives.label())//"<-->"//trim(lProducts.label()) - - if( GOptions_debugLevel >= 2 ) then - write(*,*) " reactives = ", trim(reactives.label()) - write(*,*) " products = ", trim(products.label()) - write(*,*) " TS located = ", trim(labelTS.fstr) - end if + if( transitionStateId == -1 ) cycle call productsTS.init( products.nMolecules() - lProducts.nMolecules() + 1 ) - - call productsTS.set( 1, & - FragmentsDB_instance.transitionState( FragmentsDB_instance.str2id_TS.at( labelTS ) ) ) + call productsTS.set( 1, FragmentsDB_instance.transitionState( transitionStateId ) ) ! @TODO Aca el problema aparece cuando todos los productos estan en un TS como C(t1)+C(t1)+C(t1) ! En este caso nunca se entra en el if j=2 do i=1,products.nMolecules() do kp=1,size(productInTScomb,dim=2) - label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label()) - if( label /= trim(products.clusters(i).label()) & + label = trim(products.clusters( productInTS.at(productInTScomb(jp,kp)) ).label( details=useDetailsInLabel )) + if( label /= trim(products.clusters(i).label( details=useDetailsInLabel )) & .and. j<=productsTS.nMolecules() ) then call productsTS.set( j, products.clusters(i) ) j = j+1 @@ -740,7 +616,8 @@ subroutine reduceToTransitionStates( reactives, products, productsTS ) end if if( GOptions_debugLevel >= 2 ) then - write(*,*) " Eff channel = ", trim(reactives.label())//"-->"//trim(productsTS.label()) + write(*,*) " products = ", trim(products.label( details=useDetailsInLabel )) + write(*,*) " Eff channel = ", trim(reactives.label( details=useDetailsInLabel ))//"-->"//trim(productsTS.label( details=useDetailsInLabel )) end if locatedTS = .true. @@ -1221,7 +1098,7 @@ subroutine run( this ) if( GOptions_printLevel >= 2 ) then write(*,"(A)") "#--------------------------------------------------------------------------------------------------------------" - write(*,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "formula" + write(*,"(A1,3X,6A15,5X,A)") "#", "LnWe", "LnWv", "LnWn", "LnWr", "LnWt", "LnW", "label" write(*,"(A1,3X,6A15,5X,A)") "#", "arb.", "arb.", "arb.", "arb.", "arb.", "arb.", "" write(*,"(A)") "#--------------------------------------------------------------------------------------------------------------" @@ -1236,7 +1113,7 @@ subroutine run( this ) write(*,"(A)") "" write(*,"(A)") "#--------------------------------------------------------------------------------------------------------------" - write(*,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "formula" + write(*,"(A1,3X,5A15,5X,A)") "#", "trans", "intermol", "vib", "rot", "tot", "label" write(*,"(A1,3X,5A15,5X,A)") "#", "eV", "eV", "eV", "eV", "" write(*,"(A)") "#--------------------------------------------------------------------------------------------------------------" @@ -1311,7 +1188,7 @@ subroutine execute( this, iParser ) call reactives.init( size(reactiveTokens) ) do i=1,size(reactiveTokens) - iBuffer = FragmentsDB_instance.getIdFromName( reactiveTokens(i) ) + iBuffer = FragmentsDB_instance.getIdClusterFromLabel( reactiveTokens(i) ) call reactives.set( i, FragmentsDB_instance.clusters(iBuffer) ) end do @@ -1529,7 +1406,7 @@ subroutine executeReactionsAnalysis( this, iParser ) sBuffer = iParser.getString( "FRAGMENTS_DATABASE:reference", def="@@NONE@@" ) if( sBuffer /= "@@NONE@@" ) then - id = FragmentsDB_instance.getIdFromName( trim(sBuffer.fstr) ) + id = FragmentsDB_instance.getIdClusterFromLabel( trim(sBuffer.fstr) ) else id = size(FragmentsDB_instance.clusters) end if From 2428b856130005d899eeb2617e7d95f199f12010 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Tue, 10 Mar 2020 01:14:59 +0100 Subject: [PATCH 53/57] 1) Bug fixed in TS detection 2) Improved example --- examples/TS/C2.m3c | 13 ++++++++----- src/FragmentsDB.f90 | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/TS/C2.m3c b/examples/TS/C2.m3c index 576b381..7c4d3a8 100644 --- a/examples/TS/C2.m3c +++ b/examples/TS/C2.m3c @@ -1,5 +1,5 @@ BEGIN EXCITATION_ENERGY_SCAN - excitationEnergy = 0:12:13 # dE = 1.0 eV + excitationEnergy = 0:12:25 # dE = 0.5 eV END EXCITATION_ENERGY_SCAN BEGIN GOPTIONS @@ -13,7 +13,7 @@ BEGIN GOPTIONS useSpinConservationRules = FALSE angularMomentumCouplingScheme = JJL -# debugLevel = 3 + debugLevel = 3 END GOPTIONS BEGIN MARKOV_CHAIN @@ -21,7 +21,7 @@ BEGIN MARKOV_CHAIN burnInFraction = 0.0 reactives = C2(s1) - excitationEnergy = 10.0 + excitationEnergy = 7.0 tracking = weight @@ -29,7 +29,7 @@ BEGIN MARKOV_CHAIN # numberOfEvents = 100000 numberOfExperiments = 3 # numberOfEvents = 50000 - numberOfEvents = 2000 + numberOfEvents = 5000 # historyFileFrequency = 100 historyFileFrequency = 1 @@ -49,6 +49,7 @@ BEGIN FRAGMENTS_DATABASE #-------------------------------------------------------------------------------------- # Label Z M WL SYM geomFile Eelec maxVib #-------------------------------------------------------------------------------------- + C(s1) 0 1 3 1 C.q0.m3-1.rxyz 2.5 # ³P (2s²2p²) C(t1) 0 3 3 1 C.q0.m3-1.rxyz 3.0 # ³P (2s²2p²) C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz 0.0 C(t1)+C(t1) # 6.0 ^1\Sigma_g^+ #-------------------------------------------------------------------------------------- @@ -61,6 +62,8 @@ BEGIN TRANSITION_STATES_DATABASE #-------------------------------------------------------------------------------------- # Label Z M WL SYM geomFile Eelec maxVib TS #-------------------------------------------------------------------------------------- - C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz 8.0 4.0 C2(s1)<-->C(t1)+C(t1) + C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz 7.0 4.0 C2(s1)<-->C(s1)+C(s1) + C2(ts2) 0 1 1 2 C2ts.q0.m1-1.rxyz 20.0 4.0 C2(s1)<-->C(s1)+C(t1) + C2(ts3) 0 1 1 2 C2ts.q0.m1-1.rxyz 20.0 4.0 C2(s1)<-->C(t1)+C(t1) #-------------------------------------------------------------------------------------- END TRANSITION_STATES_DATABASE diff --git a/src/FragmentsDB.f90 b/src/FragmentsDB.f90 index 2e8af74..210c4c7 100644 --- a/src/FragmentsDB.f90 +++ b/src/FragmentsDB.f90 @@ -455,6 +455,9 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) call this.str2id_TS.insert( FString_toString(trim(productsdLabel)//"<-->"//trim(reactivesdLabel)), i ) write(*,"(4X,A22,A)") "Interpreted Path = ", trim(reactivesdLabel)//"<-->"//trim(productsdLabel) + deallocate(reactives) + deallocate(products) + else call GOptions_error( & "Bad number of atoms in transition state (N=0)", & @@ -470,9 +473,6 @@ subroutine setTransitionStatesTable( this, transitionStatesTable, store ) call GOptions_section( "END TRANSITION_STATES DATABASE INITIALIZATION", indent=1 ) -! deallocate(reactives) -! deallocate(products) - end subroutine setTransitionStatesTable !> From 77037da9c05927efc182ee9ac0131483de62ebc4 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 14 Mar 2020 21:15:37 +0100 Subject: [PATCH 54/57] Improved example C2 with transition state --- examples/{TS => testTS-C2}/C.q0.m1-1.rxyz | 0 examples/{TS => testTS-C2}/C.q0.m3-1.rxyz | 0 examples/{TS => testTS-C2}/C2.m3c | 43 ++-- examples/{TS => testTS-C2}/C2.q0.m1-1.rxyz | 0 examples/{TS => testTS-C2}/C2.q0.m3-1.rxyz | 0 examples/{TS => testTS-C2}/C2ts.q0.m1-1.rxyz | 2 +- examples/{TS => testTS-C2}/C3.m3c | 0 examples/{TS => testTS-C2}/C3.q0.m1-1.rxyz | 0 examples/testTS-C2/breakDownCurves.png | Bin 0 -> 30496 bytes examples/testTS-C2/energyLandscape.png | Bin 0 -> 52618 bytes examples/testTS-C2/energyLandscape.svg | 247 +++++++++++++++++++ 11 files changed, 265 insertions(+), 27 deletions(-) rename examples/{TS => testTS-C2}/C.q0.m1-1.rxyz (100%) rename examples/{TS => testTS-C2}/C.q0.m3-1.rxyz (100%) rename examples/{TS => testTS-C2}/C2.m3c (50%) rename examples/{TS => testTS-C2}/C2.q0.m1-1.rxyz (100%) rename examples/{TS => testTS-C2}/C2.q0.m3-1.rxyz (100%) rename examples/{TS => testTS-C2}/C2ts.q0.m1-1.rxyz (83%) rename examples/{TS => testTS-C2}/C3.m3c (100%) rename examples/{TS => testTS-C2}/C3.q0.m1-1.rxyz (100%) create mode 100644 examples/testTS-C2/breakDownCurves.png create mode 100644 examples/testTS-C2/energyLandscape.png create mode 100644 examples/testTS-C2/energyLandscape.svg diff --git a/examples/TS/C.q0.m1-1.rxyz b/examples/testTS-C2/C.q0.m1-1.rxyz similarity index 100% rename from examples/TS/C.q0.m1-1.rxyz rename to examples/testTS-C2/C.q0.m1-1.rxyz diff --git a/examples/TS/C.q0.m3-1.rxyz b/examples/testTS-C2/C.q0.m3-1.rxyz similarity index 100% rename from examples/TS/C.q0.m3-1.rxyz rename to examples/testTS-C2/C.q0.m3-1.rxyz diff --git a/examples/TS/C2.m3c b/examples/testTS-C2/C2.m3c similarity index 50% rename from examples/TS/C2.m3c rename to examples/testTS-C2/C2.m3c index 7c4d3a8..abe90a2 100644 --- a/examples/TS/C2.m3c +++ b/examples/testTS-C2/C2.m3c @@ -13,31 +13,22 @@ BEGIN GOPTIONS useSpinConservationRules = FALSE angularMomentumCouplingScheme = JJL - debugLevel = 3 END GOPTIONS BEGIN MARKOV_CHAIN task = 5*V,T,R,S:0,5*V,T,R,S:-1:1 - burnInFraction = 0.0 + burnInFraction = 0.1 reactives = C2(s1) excitationEnergy = 7.0 - tracking = weight - -# numberOfExperiments = 6 -# numberOfEvents = 100000 + tracking = energy numberOfExperiments = 3 -# numberOfEvents = 50000 - numberOfEvents = 5000 -# historyFileFrequency = 100 + numberOfEvents = 10000 historyFileFrequency = 1 -# geometryHistoryFilePrefix = geom energyHistoryFile = energy.dat weightHistoryFile = weight.dat -# JHistoryFile = J.dat -# LHistoryFile = L.dat histogramFile = histogram.dat END MARKOV_CHAIN @@ -46,24 +37,24 @@ BEGIN FRAGMENTS_DATABASE store = . reference = C2(s1) - #-------------------------------------------------------------------------------------- - # Label Z M WL SYM geomFile Eelec maxVib - #-------------------------------------------------------------------------------------- - C(s1) 0 1 3 1 C.q0.m3-1.rxyz 2.5 # ³P (2s²2p²) - C(t1) 0 3 3 1 C.q0.m3-1.rxyz 3.0 # ³P (2s²2p²) - C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz 0.0 C(t1)+C(t1) # 6.0 ^1\Sigma_g^+ - #-------------------------------------------------------------------------------------- + #--------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib + #--------------------------------------------------------------------------- + C(s1) 0 1 5 0 C.q0.m1-1.rxyz -1026.574168 # R3(1-D) + C(t1) 0 3 3 0 C.q0.m3-1.rxyz -1028.024016 # R3(3-P) + C2(s1) 0 1 1 2 C2.q0.m1-1.rxyz -2062.151541 C(t1)+C(t1) # 6.10 D*H(1-SGG) + C2(t1) 0 3 2 2 C2.q0.m3-1.rxyz -2062.058719 C(t1)+C(t1) # 6.01 D*H(3-PIU) + #--------------------------------------------------------------------------- END FRAGMENTS_DATABASE BEGIN TRANSITION_STATES_DATABASE store = . - #-------------------------------------------------------------------------------------- - # Label Z M WL SYM geomFile Eelec maxVib TS - #-------------------------------------------------------------------------------------- - C2(ts1) 0 1 1 2 C2ts.q0.m1-1.rxyz 7.0 4.0 C2(s1)<-->C(s1)+C(s1) - C2(ts2) 0 1 1 2 C2ts.q0.m1-1.rxyz 20.0 4.0 C2(s1)<-->C(s1)+C(t1) - C2(ts3) 0 1 1 2 C2ts.q0.m1-1.rxyz 20.0 4.0 C2(s1)<-->C(t1)+C(t1) - #-------------------------------------------------------------------------------------- + #--------------------------------------------------------------------------------------------- + # Label Z M WL SYM geomFile Eelec maxVib TS + #--------------------------------------------------------------------------------------------- + C2ts(s1) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.151541 C(s1)+C(s1) C2(s1)<-->C(t1)+C(t1) # 8.10 D*H(1-SGG) + C2ts(s2) 0 1 1 2 C2ts.q0.m1-1.rxyz -2054.151541 C(s1)+C(s1) C2(t1)<-->C(t1)+C(t1) # 8.10 D*H(1-SGG) + #--------------------------------------------------------------------------------------------- END TRANSITION_STATES_DATABASE diff --git a/examples/TS/C2.q0.m1-1.rxyz b/examples/testTS-C2/C2.q0.m1-1.rxyz similarity index 100% rename from examples/TS/C2.q0.m1-1.rxyz rename to examples/testTS-C2/C2.q0.m1-1.rxyz diff --git a/examples/TS/C2.q0.m3-1.rxyz b/examples/testTS-C2/C2.q0.m3-1.rxyz similarity index 100% rename from examples/TS/C2.q0.m3-1.rxyz rename to examples/testTS-C2/C2.q0.m3-1.rxyz diff --git a/examples/TS/C2ts.q0.m1-1.rxyz b/examples/testTS-C2/C2ts.q0.m1-1.rxyz similarity index 83% rename from examples/TS/C2ts.q0.m1-1.rxyz rename to examples/testTS-C2/C2ts.q0.m1-1.rxyz index 1668844..d6b0257 100644 --- a/examples/TS/C2ts.q0.m1-1.rxyz +++ b/examples/testTS-C2/C2ts.q0.m1-1.rxyz @@ -1,5 +1,5 @@ 2 -Energy = -75.8561424407255 +Energy = -75.4886493524808 C 0.823543 0.000000 0.000000 C -0.823543 0.000000 0.000000 diff --git a/examples/TS/C3.m3c b/examples/testTS-C2/C3.m3c similarity index 100% rename from examples/TS/C3.m3c rename to examples/testTS-C2/C3.m3c diff --git a/examples/TS/C3.q0.m1-1.rxyz b/examples/testTS-C2/C3.q0.m1-1.rxyz similarity index 100% rename from examples/TS/C3.q0.m1-1.rxyz rename to examples/testTS-C2/C3.q0.m1-1.rxyz diff --git a/examples/testTS-C2/breakDownCurves.png b/examples/testTS-C2/breakDownCurves.png new file mode 100644 index 0000000000000000000000000000000000000000..d718fac11b6e559d7ea9ba8e2d426bdb73d5429c GIT binary patch literal 30496 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�X&oSS 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 + + + + + + + + + image/svg+xml + + + + + + + + C2(s1) + C2(t1) + C2(ts) + C(t1)+C(t1) + C(s1)+C(t1) + C(s1)+C(s1) + 0.0 + 0.1 + 8.0 + 6.1 + 7.6 + 9.0 + + + + + + + + + + From 62404d1680b2e4b4fa6a0759c42e203b8f3f5a73 Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Fri, 20 Mar 2020 01:12:41 +0100 Subject: [PATCH 55/57] Bug fixed in the determination of the spin forbidden reactions --- src/Fragment.f90 | 4 +- src/FragmentsListBase.f90 | 119 +++++++++++++++++++++++++++++--------- src/Reactor.f90 | 43 +++++--------- 3 files changed, 107 insertions(+), 59 deletions(-) diff --git a/src/Fragment.f90 b/src/Fragment.f90 index d868191..dca0eda 100644 --- a/src/Fragment.f90 +++ b/src/Fragment.f90 @@ -61,7 +61,7 @@ module Fragment_ use RandomUtils_ use Molecule_ use StringList_ - use RealList_ + use RealVector_ use GOptionsM3C_ @@ -929,7 +929,7 @@ end subroutine showLnWComponents !! function spinAvailable( this ) result( output ) class(Fragment), intent(in) :: this - type(RealList) :: output + type(RealVector) :: output real(8) :: S, Si, Sj integer :: i, j diff --git a/src/FragmentsListBase.f90 b/src/FragmentsListBase.f90 index 0e3c551..ad28241 100644 --- a/src/FragmentsListBase.f90 +++ b/src/FragmentsListBase.f90 @@ -1,6 +1,12 @@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! This file is part of M3C project !! +!! !! +!! Copyright (c) 2019-2020 by authors !! +!! Authors: !! +!! * Néstor F. Aguirre (2019-2020) !! +!! nfaguirrec@gmail.com !! +!! !! !! Copyright (c) 2013-2016 Departamento de Química !! !! Universidad Autónoma de Madrid !! !! All rights reserved. !! @@ -66,7 +72,7 @@ module FragmentsListBase_ use Atom_ use Molecule_ use BlocksIFileParser_ - use RealList_ + use RealVector_ use GOptionsM3C_ use Fragment_ @@ -75,6 +81,9 @@ module FragmentsListBase_ implicit none private + public :: & + spinListCoupling + type, abstract, public :: FragmentsListBase type(Fragment), allocatable :: clusters(:) !< Fragment list integer, allocatable :: idSorted(:) !< Position of the molecule sorted by mass. It is calculated in updateLabel procedure @@ -2257,43 +2266,97 @@ function spinRange( this ) result( output ) end function spinRange !> - !! @brief + !! @brief Internal. Used only by spinAvailable function !! - function spinAvailable( this ) result( output ) - class(FragmentsListBase), intent(in) :: this - type(RealList) :: output + function spinSpinCoupling( s1, s2 ) result( st ) + real(8), intent(in) :: s1, s2 + type(RealVector) :: st - real(8) :: S, Si, Sj - integer :: i, j + real(8) :: s0 + integer :: i + integer :: n - call output.init() + n = s1+s2-abs(s1-s2)+1 + s0 = abs(s1-s2) - if( this.nMolecules() == 1 ) then - S = (this.clusters(1).multiplicity-1.0_8)/2.0_8 - call output.append( S ) - else - do i=1,this.nMolecules()-1 - Si = (this.clusters(i).multiplicity-1.0_8)/2.0_8 + call st.init( n ) + do i=1,n + call st.set( i, s0+i-1 ) + end do - if( Si < 0.0_8 ) Si=0.0_8 + end function spinSpinCoupling + + !> + !! @brief Internal. Used only by spinAvailable function + !! + function spinListSpinCoupling( sl1, s2 ) result( st ) + type(RealVector), intent(in) :: sl1 + real(8), intent(in) :: s2 + type(RealVector) :: st + + real(8) :: s0 + integer :: i + integer :: n + + n = maxval(sl1.data(1:sl1.size())+s2)-minval(abs(sl1.data(1:sl1.size())-s2))+1 + s0 = minval(abs(sl1.data(1:sl1.size())-s2)) + + call st.init( n, 0.0_8 ) + do i=1,n + call st.set( i, s0+i-1 ) + end do - do j=i+1,this.nMolecules() - Sj = (this.clusters(j).multiplicity-1.0_8)/2.0_8 - - if( Sj < 0.0_8 ) Sj=0.0_8 - - S = abs(Si-Sj) - do while( int(2.0*S) <= int(2.0*(Si+Sj)) ) - call output.append( S ) - - S = S + 1.0_8 - end do - end do + end function spinListSpinCoupling + + !> + !! @brief Internal. Used only by spinAvailable function + !! + function spinListCoupling( sl ) result( st ) + type(RealVector), intent(in) :: sl + type(RealVector) :: st + + integer :: i + type(RealVector) :: sij + + call st.init() + + if( sl.size() == 1 ) then + st = sl + else + sij = spinSpinCoupling( sl.at(1), sl.at(2) ) + st = sij + + do i=3,sl.size() + sij = spinListSpinCoupling( sij, sl.at(i) ) + st = sij end do end if + + end function spinListCoupling + + !> + !! @brief + !! + function spinAvailable( this ) result( output ) + class(FragmentsListBase), intent(in) :: this + type(RealVector) :: output + + integer :: i + real(8) :: S + type(RealVector) :: sl + + call sl.init( this.nMolecules(), 0.0_8 ) + do i=1,this.nMolecules() + S = (this.clusters(i).multiplicity-1.0_8)/2.0_8 + if( S < 0.0_8 ) S=0.0_8 + + call sl.append( S ) + end do + + output = spinListCoupling( sl ) if( output.size() == 0 ) then - write(*,*) "### ERROR ### FragmentsListBase.spinAvailable.size() == 0", this.nMolecules(), S, Si, Sj + write(*,*) "### ERROR ### FragmentsListBase.spinAvailable.size() == 0", this.nMolecules(), S end if end function spinAvailable diff --git a/src/Reactor.f90 b/src/Reactor.f90 index 3ea3f41..fd221f0 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -63,6 +63,7 @@ module Reactor_ use BlocksIFileParser_ use RealHistogram_ use RealList_ + use RealVector_ use IntegerVector_ use StringIntegerMap_ use StringRealMap_ @@ -71,6 +72,7 @@ module Reactor_ use GOptionsM3C_ use Fragment_ + use FragmentsListBase_ use FragmentsList_ use FragmentsDB_ @@ -127,7 +129,7 @@ module Reactor_ integer, private :: internalCharge = 0 integer, private :: internalNTrials = 0 ! real(8), private :: internalReactivesSpinRange(2) = 0.0_8 - type(RealList), private :: internalReactivesSpinAvail + type(RealVector), private :: internalReactivesSpinAvail contains @@ -348,33 +350,25 @@ function isSpinForbidden( multisetPositions, current ) result( output ) logical :: output real(8) :: S, Si, Sj - type(RealList) :: spinAvail + type(RealVector) :: spinAvail integer :: i, j class(RealListIterator), pointer :: it1, it2 - call spinAvail.init() + call spinAvail.init( current, 0.0_8 ) if( current == 1 ) then S = (FragmentsDB_instance.clusters( multisetPositions(1) ).multiplicity-1.0_8)/2.0_8 - call spinAvail.append( S ) + call spinAvail.set( 1, S ) else - do i=1,current-1 + do i=1,current Si = (FragmentsDB_instance.clusters( multisetPositions(i) ).multiplicity-1.0_8)/2.0_8 - if( Si < 0.0_8 ) Si=0.0_8 - do j=i+1,current - Sj = (FragmentsDB_instance.clusters( multisetPositions(j) ).multiplicity-1.0_8)/2.0_8 - - if( Sj < 0.0_8 ) Sj=0.0_8 - - S = abs(Si-Sj) - do while( int(2.0*S) <= int(2.0*(Si+Sj)) ) - call spinAvail.append( S ) - S = S + 1.0_8 - end do - end do + call spinAvail.set( i, Si ) end do + + spinAvail = spinListCoupling( spinAvail ) + end if if( spinAvail.size() == 0 ) then @@ -382,22 +376,13 @@ function isSpinForbidden( multisetPositions, current ) result( output ) end if output = .true. - - it1 => spinAvail.begin - do while( associated(it1) ) - - it2 => internalReactivesSpinAvail.begin - do while( associated(it2) ) - - if( abs( it1.data - it2.data ) < 0.1 ) then + do i=1,spinAvail.size() + do j=1,internalReactivesSpinAvail.size() + if( abs( spinAvail.at(i) - internalReactivesSpinAvail.at(j) ) < 0.1 ) then output = .false. return end if - - it2 => it2.next end do - - it1 => it1.next end do call spinAvail.clear() From 8859cb51e7e8da376d421ee3d99b31d2403b0e5a Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Sat, 21 Mar 2020 10:36:23 +0100 Subject: [PATCH 56/57] Simple bug fixed --- src/Reactor.f90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Reactor.f90 b/src/Reactor.f90 index fd221f0..f25d55f 100644 --- a/src/Reactor.f90 +++ b/src/Reactor.f90 @@ -358,6 +358,8 @@ function isSpinForbidden( multisetPositions, current ) result( output ) if( current == 1 ) then S = (FragmentsDB_instance.clusters( multisetPositions(1) ).multiplicity-1.0_8)/2.0_8 + if( Si < 0.0_8 ) Si=0.0_8 + call spinAvail.set( 1, S ) else do i=1,current From 39f60a000b920b41be97aaf831ef163de170bbca Mon Sep 17 00:00:00 2001 From: nfaguirrec Date: Mon, 23 Mar 2020 22:16:41 +0100 Subject: [PATCH 57/57] Now new properties of the deposited energy function are printed in M3CBR M3CfitBR programs --- src/M3CBR.f90 | 43 +++++++++++++++++++++++++++++++++++++++++- src/M3CfitBR.f90 | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/M3CBR.f90 b/src/M3CBR.f90 index 00d358d..dc5bf7d 100644 --- a/src/M3CBR.f90 +++ b/src/M3CBR.f90 @@ -1,6 +1,12 @@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! This file is part of M3C project !! +!! !! +!! Copyright (c) 2019-2020 by authors !! +!! Authors: !! +!! * Néstor F. Aguirre (2020-2020) !! +!! nfaguirrec@gmail.com !! +!! !! !! Copyright (c) 2013-2016 Departamento de Química !! !! Universidad Autónoma de Madrid !! !! All rights reserved. !! @@ -72,6 +78,7 @@ program M3CBR logical :: lBuffer real(8) :: BR, rms, error + real(8) :: averE, stdevE, skewE type(CommandLineParser) :: programOptions type(BlocksIFileParser) :: iParser @@ -371,13 +378,47 @@ program M3CBR rms = sqrt(rms/nChannels) close(11) - + + ! Maxima: + ! B(E):=E**l*exp(-E/n)/(n**(l+1)*gamma(l+1)); + ! integrate(E*B(E),E,0,inf); #---> (l+1)*n + ! integrate((E-mu)**2*B(E),E,0,inf); #---> (l+1)*(l+2)*n**2-2*(l+1)*n*mu+mu**2 + ! integrate(((E-mu)/sigma)**3*B(E),E,0,inf); #--> ( (l+1)*(l+2)*(l+3)*n**3-3*(l+1)*(l+2)*n**2*mu+3*(l+1)*n*mu**2-mu**3 )/sigma**3 + + averE = 0.0_8 + do k=1,basisSize + n = NL(k,1) + l = NL(k,2) + + averE = averE + (C.get(k,1)/100.0_8)*real((l+1)*n,8) + end do + + stdevE = 0.0_8 + do k=1,basisSize + n = NL(k,1) + l = NL(k,2) + + stdevE = stdevE + (C.get(k,1)/100.0_8)*( real((l+1)*(l+2)*n**2,8) - 2.0_8*real((l+1)*n,8)*averE + averE**2 ) + end do + stdevE = sqrt(stdevE) + + skewE = 0.0_8 + do k=1,basisSize + n = NL(k,1) + l = NL(k,2) + + skewE = skewE + (C.get(k,1)/100.0_8)*( real((l+1)*(l+2)*(l+3)*n**3,8) - 3.0_8*real((l+1)*(l+2)*n**2,8)*averE + 3.0_8*real((l+1)*n,8)*averE**2-averE**3 )/stdevE**3 + end do + call f.fromFunction( energyGrid, energyFunction ) call f.save( energyDistFileName.fstr ) call integrator.init( f, NIntegrator_BOOLE ) write(*,*) "" write(*,"(A15,F10.5)") "rms = ", rms write(*,"(A15,F10.5)") "Integral = ", integrator.evaluate() + write(*,"(A15,F10.5)") " = ", averE + write(*,"(A15,F10.5)") "stdev(E) = ", stdevE + write(*,"(A15,F10.5)") "skew(E) = ", skewE if( integrator.evaluate() < 98.0_8 ) then write(*,*) "" diff --git a/src/M3CfitBR.f90 b/src/M3CfitBR.f90 index 6fe8b39..3c93b9d 100644 --- a/src/M3CfitBR.f90 +++ b/src/M3CfitBR.f90 @@ -1,6 +1,12 @@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! This file is part of M3C project !! +!! !! +!! Copyright (c) 2019-2020 by authors !! +!! Authors: !! +!! * Néstor F. Aguirre (2020-2020) !! +!! nfaguirrec@gmail.com !! +!! !! !! Copyright (c) 2013-2016 Departamento de Química !! !! Universidad Autónoma de Madrid !! !! All rights reserved. !! @@ -71,6 +77,8 @@ program M3CfitBR type(Grid) :: bufferGrid logical :: lBuffer + real(8) :: averE, stdevE, skewE + type(CommandLineParser) :: programOptions type(BlocksIFileParser) :: iParser @@ -486,10 +494,51 @@ program M3CfitBR write(*,"(A15,F10.5)") "rms = ", sqrt(ssum/nChannels) close(11) + ! Maxima: + ! B(E):=E**l*exp(-E/n)/(n**(l+1)*gamma(l+1)); + ! solve(diff(B(E),E)=0,E); #--> E=n*l + ! integrate(E*B(E),E,0,inf); #---> (l+1)*n + ! integrate((E-mu)**2*B(E),E,0,inf); #---> (l+1)*(l+2)*n**2-2*(l+1)*n*mu+mu**2 + ! integrate(((E-mu)/sigma)**3*B(E),E,0,inf); #--> ( (l+1)*(l+2)*(l+3)*n**3-3*(l+1)*(l+2)*n**2*mu+3*(l+1)*n*mu**2-mu**3 )/sigma**3 + + averE = 0.0_8 + k=1 + do n=1,Nmax + do l=1,Lmax + averE = averE + (C.get(k,1)/100.0_8)*real((l+1)*n,8) + + k = k+1 + end do + end do + + stdevE = 0.0_8 + k=1 + do n=1,Nmax + do l=1,Lmax + stdevE = stdevE + (C.get(k,1)/100.0_8)*( real((l+1)*(l+2)*n**2,8) - 2.0_8*real((l+1)*n,8)*averE + averE**2 ) + + k = k+1 + end do + end do + stdevE = sqrt(stdevE) + + skewE = 0.0_8 + k=1 + do n=1,Nmax + do l=1,Lmax + skewE = skewE + (C.get(k,1)/100.0_8)*( real((l+1)*(l+2)*(l+3)*n**3,8) - 3.0_8*real((l+1)*(l+2)*n**2,8)*averE + 3.0_8*real((l+1)*n,8)*averE**2-averE**3 )/stdevE**3 + + k = k+1 + end do + end do + call f.fromFunction( energyGrid, energyFunction ) call f.save( energyDistFileName.fstr ) call integrator.init( f, NIntegrator_BOOLE ) write(*,"(A15,F10.5)") "Integral = ", integrator.evaluate() + write(*,"(A15,F10.5)") " = ", averE + write(*,"(A15,F10.5)") "stdev(E) = ", stdevE + write(*,"(A15,F10.5)") "skew(E) = ", skewE if( abs(integrator.evaluate()-100.0_8) > 2.0_8 ) then write(*,*) ""