{"id":15018270,"url":"https://github.com/tinaccil/fortranthermostats","last_synced_at":"2026-02-02T19:31:05.403Z","repository":{"id":213885937,"uuid":"735174415","full_name":"TinacciL/FortranThermoStats","owner":"TinacciL","description":"Molecule thermostatistics properties code in Fortran90","archived":false,"fork":false,"pushed_at":"2023-12-25T09:59:50.000Z","size":6964,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T13:33:30.731Z","etag":null,"topics":["chemoinformatics","molecule","thermodynamics"],"latest_commit_sha":null,"homepage":"","language":"Fortran","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TinacciL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-12-23T23:40:56.000Z","updated_at":"2024-01-20T22:54:18.000Z","dependencies_parsed_at":"2023-12-24T01:21:16.129Z","dependency_job_id":"fe5cb741-15c0-42b3-9d94-9746441bc497","html_url":"https://github.com/TinacciL/FortranThermoStats","commit_stats":{"total_commits":6,"total_committers":1,"mean_commits":6.0,"dds":0.0,"last_synced_commit":"4bb049a138a46a579227a3ab1360cacb7872d2a4"},"previous_names":["tinaccil/fortranthermostats"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TinacciL/FortranThermoStats","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TinacciL%2FFortranThermoStats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TinacciL%2FFortranThermoStats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TinacciL%2FFortranThermoStats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TinacciL%2FFortranThermoStats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TinacciL","download_url":"https://codeload.github.com/TinacciL/FortranThermoStats/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TinacciL%2FFortranThermoStats/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260477921,"owners_count":23015064,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chemoinformatics","molecule","thermodynamics"],"created_at":"2024-09-24T19:51:46.146Z","updated_at":"2026-02-02T19:31:00.356Z","avatar_url":"https://github.com/TinacciL.png","language":"Fortran","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FortranThermoStats\nThis is a Fortran 90 program that allows one to read a molecule file (```input.f90```, in this case, is the water molecule) and calculate and print all the thermodynamic information of the molecule. In the ```parameters.f90``` there are the parameters of the main.\n\n\u003cp align=\"center\"\u003e\n \u003cimg src=\"variae/H2O_Vibration.gif\" alt=\"Water Vibrations\"\u003e\n\u003c/p\u003e\n\nThis script is part of my duty to accomplish the Theoretical Chemistry Exams at University of Florence in 2017.\n\nTo see the theory behind it, in the ```variae``` folder there is the pdf ```thermo.pdf``` written by Joseph W. Ochterski which explains the Thermochemistry in Gaussian program, from which my program is inspired. In the above mentioned folder there are also the files of the water optimization and frequency calcolation in Gaussian09 (```water_opt_freq.gau``` is the input, ```water_opt_freq.log``` is the output).\n\n### To run the script:\nIn my case, since I used an Apple M1 chip, I download ```gfortran``` compiler from the python ```anaconda``` package management in a dedicated environment.\n\nTo install the ```gfortran```:\n\n1) ```conda create --name Fortran python=3.10.13```\n1) ```conda activate Fortran```\n1) ```conda install -c conda-forge gfortran```\n\nTo run the code you can use the MakeFile:\n\n1) ```make compile``` to compile the module and main script\n1) ```make run``` to run the code\n1) ```make clean``` to clean all the executable and compile file\n\n    Here below the comands run by the ```MakeFile```:\n\n    1) Compile the module file\n\n        ```gfortran -c parameters.f90```\n    1) Compile the script \n\n        ```gfortran FortranThermoStats.f90 parameters.f90 -o FortranThermoStats.o```\n    1) If needed, you have to allow the exectution of the script\n\n        ```chmod +x FortranThermoStats.o```\n    1) Run the code:\n\n        ```./FortranThermoStats.o```\n\n\nThe code:\n\n```f90\nprogram FortranThermoStats\n  use parameters\n\n  implicit none\n\n  real(8) :: x(n), y(n), z(n), freq(n), theta(n), fvib(n), theta_tot, fp_vib, Ain, Bin, Cin, Iin, \u0026\n             fp_rot, mass(n), fp_tot, fp_el, fp_nuc, fp_trl,                                   \u0026\n             ix, iy, iz, ixz, ixy, iyz, Inerzia(3,3), Inerzia1(3,3), M, bx, by, bz, pi, ht, A, \u0026\n             S_tot, S_vib, S_trl, S_rot, G, V, P, E_tot, E_vib, E_trl, E_rot, Cv, Cp, T, mol,  \u0026\n             E_totj, E_vibj, E_trlj, E_rotj, S_totj, S_vibj, S_trlj, S_rotj, E_vibs, E_vibsj,  \u0026\n             Cvr\n  character(2) :: nome(n)\n  integer :: k, i, nato, j, sig, sim, nmv\n  \n  !---case where reading and printing to file is desired-------------------------------------------\n  open (unit = 1, file = 'risultati.dat', status = 'replace', action = 'write')\n  open (unit = 2, file = 'input.txt', status = 'old', action = 'read')  \n  !-------------------------------------------------------------------------------------------\n\n  pi = acos(-1.d0)\n  ht =  h/(2.d0*pi) \n\n  !---reading input data-------------------------------------------------------------------\n  \n  read (2,*) !comment input\n  read (2,*) T\n  read (2,*) P\n  read (2,*) V\n  read (2,*) mol\n  read (2,*) nato\n  read (2,*) sim\n  read (2,*) sig\n  \n  do i=1, nato \n     read (2,*) nome(i), x(i), y(i), z(i)\n  enddo\n\n   k=0\n\n   do \n      k= k+1\n      read(2,*,end=10) freq(k)\n   enddo\n\n  !---end of input-----------------------------------------------------------------------------\n   \n  !----associating atom names with mass vector and calculating molecular mass M------------------\n10 do i=1, nato\n      do j=1, 118\n         if (nome(i) == element(j)) then\n            mass(i)  = weights(j) \n         endif\n      enddo\n   enddo   \n\n   do i=1, nato\n      M= M + mass(i)\n   enddo   \n  !-------------------------------------------------------------------------------------------  \n   \n  !Parameters for ideal gas law\n  if (P == 0) then\n     P = (mol * Av *kb * T) / (V * 101325)\n  endif\n  if (V == 0) then \n     V = (mol * Av *kb * T) / (P * 101325)\n  endif\n  if (mol == 0) then\n     mol = (P * V * 101325) / (Av *kb * T)\n  endif\n \n  !assigning normal vibrational modes\n  if (sim == 0) then\n     nmv = 3 * nato - 5 \n  else if (sim == 1) then\n     nmv = 3 * nato - 6\n  endif    \n  \n  !---------------Inertia-------------------------------------------------------------- \n  !calculating center of mass and changing reference frame \n   do i=1, nato\n      bx = bx + mass(i)*x(i)/M\n      by = by + mass(i)*y(i)/M\n      bz = bz + mass(i)*z(i)/M\n   enddo\n          \n     x(i) = x(i) - bx\n     y(i) = y(i) - bx\n     z(i) = z(i) - bx\n         \n  !constructing inertia tensor elements and diagonalizing\n    do i=1, nato\n       ix = ix + mass(i) * ((y(i)**2) + (z(i)**2))\n       iy = iy + mass(i) * ((z(i)**2) + (x(i)**2))\n       iz = iz + mass(i) * ((y(i)**2) + (x(i)**2))\n       ixz = ixz + mass(i) * x(i) * z(i)\n       ixy = ixy + mass(i) * x(i) * y(i)\n       iyz = iyz +  mass(i) * y(i) * z(i)\n    enddo   \n    \n     Inerzia(1,1) = ix\n     Inerzia(1,2) = ixy\n     Inerzia(1,3) = ixz\n     Inerzia(2,1) = ixy\n     Inerzia(2,2) = iy\n     Inerzia(2,3) = iyz\n     Inerzia(3,1) = ixz\n     Inerzia(3,2) = iyz\n     Inerzia(3,3) = iz\n\n    call jacobi (Inerzia, Inerzia1, abserr, 3)\n     \n   ! principal axes of inertia in kg and meters from uma and angstrom \n     Ain = Inerzia(1,1) * 1.660539d-47 \n     Bin = Inerzia(2,2) * 1.660539d-47 \n     Cin = Inerzia(3,3) * 1.660539d-47  \n   !---------------------------------------------------------------------------------------------------  \n     \n   !---Partition Function-----------------------------------------------------------------------------     \n   !NOTE: vib= vibrational, trl=translational, el=electronic, nuc=nuclear, rot= rotational  tot=total\n\n   !vibrational and vibrational temperatures\n   fp_vib = 1.d0\n\n   do k=1, nmv \n      theta(k)  =  freq(k) * c * 100* h / Kb\n      fvib(k)   =  1 / (1 - exp(-theta(k) / T))\n      fp_vib    =  fp_vib * fvib(k)\n      theta_tot = theta_tot + theta(k)\n   enddo\n  \n   !linear or non-linear rotational\n   if (sim == 0) then                                     \n      I = Ain + Bin + Cin\n      fp_rot = 2 * T * I *kb / (sig * h**2)                                   \n   else if (sim == 1) then\n     fp_rot = ( ( ( (2*kb*T) / ( (ht)**2) ) )**(1.5d0)) *  ( (pi*Ain*Bin*Cin)**(0.5d0) ) /sig\n   endif     \n\n \n     fp_trl = V /  h**3  *  (2 * pi * kb * T * M * 1.660539e-27)**(1.5d0) / Av\n\n     fp_el = 1\n\n     fp_nuc = 1\n          \n\n     fp_tot = fp_vib + fp_rot + fp_el + fp_nuc + fp_trl\n   !----end Partition Function-----------------------------------------------------------------------  \n     \n   !----energy in classical thermodynamics--------------------------------------------------------------\n   !NOTE: suffix -j indicates  joule/mol, without kcal/mol\n\n   !rotational energy for linear or non-linear molecule in joule/mol    \n   if (sim == 0) then     \n      E_rotj  = (R * T) / mol                                   \n   else if (sim == 1) then\n      E_rotj  = (1.5d0 * R * T) / mol                     \n   endif\n\n   E_rot   = E_rotj * 0.2388459 *0.001                    \n   E_trlj  = (1.5d0 * R * T) /mol                          \n   E_trl   = E_trlj * 0.2388459 *0.001                    \n   E_vibj  = (R * T) / mol                               \n   E_vib   = E_vibj * 0.2388459 * 0.001                   \n\n   E_totj  = (E_vibj + E_rotj + E_trlj)                    \n   E_tot   = (E_vib + E_rot + E_trl)               \n   !---------------------------------------------------------------------------------------------------   \n     \n   !thermodynamic quantities\n   \n    S_vibj = Av * kb * log(fp_vib) + E_vibj / T\n    S_vib  = S_vibj * 0.2388459\n    S_rotj = Av * kb * log(fp_rot) + E_rotj / T\n    S_rot  = S_rotj * 0.2388459\n    S_trlj = Av * kb * log(fp_trl) + E_trlj / T\n    S_trl  = S_trlj * 0.2388459\n    S_tot  = S_vib + S_rot + S_trl\n    S_totj = S_vibj + S_rotj + S_trlj     \n\n   !calculating Cv \n    do i=1, nmv\n       Cv = Cv + R * (theta(i) / T)**2.d0 * exp(theta(i) / T ) / ( exp(theta(i) / T) - 1)**2.d0\n    enddo\n\n    Cvr = 1.5d0 * R\n    Cv  = ( Cv + 1.5d0 * R + Cvr) * 0.2388459\n\n\n    !----Output Data---------------------------------------------------------------------------------\n    write (1,*) 'Temperature (K):              ', T\n    write (1,*) 'System Volume (m^3):          ', V\n    write (1,*) 'System Pressure (atm):        ', P\n    write (1,*) 'System Moles:                 ', mol\n    write (1,*) 'Number of Atoms:              ', nato\n    write (1,*) 'Number of Normal Modes:       ', k-1\n    write (1,*) 'Molecule Symmetry Axes:       ', sig\n    \n    if (sim == 0) then\n       write (1,*) 'Molecule Symmetry:            ', 'Linear'\n    else if (sim == 1) then\n       write (1,*) 'Molecule Symmetry:            ', 'Nonlinear'\n    endif\n    \n    if (k-1 /= nmv) then\n       write (*,*) 'ERROR: Number of normal vibrational modes different from read frequencies'\n       stop\n    endif\n    \n    write (1,*) '                        Energy (kcal*mol^-1)      Energy (J*mol^-1) '\n    write (1,*) 'Vibrational Energy:    ', E_vib,               E_vibj\n    write (1,*) 'Rotational Energy:     ', E_rot,               E_rotj\n    write (1,*) 'Translational Energy:  ', E_trl,               E_trlj\n    write (1,*) 'Total System Energy:   ', E_tot,               E_totj\n\n   do i=1, nmv\n      write (1,*) 'Frequency (cm^-1):', freq(i), 'Vibrational Temperature (K):', theta(i)\n   enddo\n  \n   do i=1, nato\n      write (1,*) 'Atom, Mass (u), and Coordinates (A):', nome(i), mass(i),  x(i), y(i), z(i)\n   enddo\n  \n    write (1,*) 'Molecule Mass (u):', M     \n    write (1,*) 'Center of Mass (A):'\n    write (1,*)  bx, by, bz    \n    write (1,*) 'Inertia Tensor (u*A^2):'\n    write (1,*)  Inerzia(1,1), Inerzia(1,2), Inerzia(1,3)\n    write (1,*)  Inerzia(2,1), Inerzia(2,2), Inerzia(2,3)\n    write (1,*)  Inerzia(3,1), Inerzia(3,2), Inerzia(3,3)    \n    write (1,*) 'Principal Axes of Inertia (Kg*m^2)'\n    Write (1,*)  Ain\n    Write (1,*)  Bin\n    Write (1,*)  Cin\n    write (1,*) 'Rotational Partition Function:  ', fp_rot\n    write (1,*) 'Vibrational Partition Function: ', fp_vib\n    write (1,*) 'Translational Partition Function:', fp_trl\n    write (1,*) 'Electronic Partition Function:  ', fp_el\n    write (1,*) 'Nuclear Partition Function:     ', fp_nuc\n    write (1,*) 'Total Partition Function:       ', fp_tot     \n    write (1,*) '                        Entropy (cal*mol^-1*K^-1) Entropy (J*mol^-1*K^-1)'    \n    write (1,*) 'Vibrational Entropy:  ', S_vib,               S_vibj\n    write (1,*) 'Rotational Entropy:   ', S_rot,               S_rotj\n    write (1,*) 'Translational Entropy: ', S_trl,               S_trlj\n    write (1,*) 'Total System Entropy: ', S_tot,               S_totj\n    write (1,*) 'Cv:',  Cv\n    \nend program FortranThermoStats\n\nsubroutine Jacobi(a,x,abserr,n)\n!===========================================================\n! Evaluate eigenvalues and eigenvectors\n! of a real symmetric matrix a(n,n): a*x = lambda*x \n! method: Jacoby method for symmetric matrices \n! Alex G. (December 2009)\n!-----------------------------------------------------------\n! input ...\n! a(n,n) - array of coefficients for matrix A\n! n      - number of equations\n! abserr - abs tolerance [sum of (off-diagonal elements)^2]\n! output ...\n! a(i,i) - eigenvalues\n! x(i,j) - eigenvectors\n! comments ...\n!===========================================================\nimplicit none\ninteger i, j, k\ndouble precision  b2, bar\ndouble precision beta, coeff, c, s, cs, sc\nreal(8), intent(inout) :: a(n,n), x(n,n)\nreal(8), intent(in) :: abserr\ninteger, intent(in) :: n\n\nx = 0.0\ndo i=1,n\n  x(i,i) = 1.0\nend do\n\n! find the sum of all off-diagonal elements (squared)\nb2 = 0.0\ndo i=1,n\n  do j=1,n\n    if (i.ne.j) b2 = b2 + a(i,j)**2\n  end do\nend do\n\nif (b2 \u003c= abserr) return\n\n! average for off-diagonal elements /2\nbar = 0.5*b2/float(n*n)\n\ndo while (b2.gt.abserr)\n  do i=1,n-1\n    do j=i+1,n\n      if (a(j,i)**2 \u003c= bar) cycle  ! do not touch small elements\n      b2 = b2 - 2.0*a(j,i)**2\n      bar = 0.5*b2/float(n*n)\n! calculate coefficient c and s for Givens matrix\n      beta = (a(j,j)-a(i,i))/(2.0*a(j,i))\n      coeff = 0.5*beta/sqrt(1.0+beta**2)\n      s = sqrt(max(0.5+coeff,0.0))\n      c = sqrt(max(0.5-coeff,0.0))\n! recalculate rows i and j\n      do k=1,n\n        cs =  c*a(i,k)+s*a(j,k)\n        sc = -s*a(i,k)+c*a(j,k)\n        a(i,k) = cs\n        a(j,k) = sc\n      end do\n! new matrix a_{k+1} from a_{k}, and eigenvectors \n      do k=1,n\n        cs =  c*a(k,i)+s*a(k,j)\n        sc = -s*a(k,i)+c*a(k,j)\n        a(k,i) = cs\n        a(k,j) = sc\n        cs =  c*x(k,i)+s*x(k,j)\n        sc = -s*x(k,i)+c*x(k,j)\n        x(k,i) = cs\n        x(k,j) = sc\n      end do\n    end do\n  end do\nend do\nreturn\nend subroutine Jacobi\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinaccil%2Ffortranthermostats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinaccil%2Ffortranthermostats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinaccil%2Ffortranthermostats/lists"}