Experimental Verification of the NKTg Variable-Inertia Law — Interpolating the Masses of 8 Planets (Mercury → Neptune) — Fortran

Post body (copy & paste):

Hi everyone,

I converted my experiment (originally in a Word document) into a single Fortran program so readers on this forum can run the verification locally. The experiment tests a proposed NKTg Law of Variable Inertia against NASA real-time data (30–31 Dec 2024) for all 8 planets (Mercury → Neptune).

Theory (simplified):

  • p = m * v

  • NKTg1 = x * p

  • interpolation formula used here: m = NKTg1 / (x * v)

This program:

  1. Stores the 8-planet dataset (x in km, v in km/s, NKTg1 and NASA masses in kg).

  2. Computes interpolated masses using m = NKTg1/(x*v).

  3. Computes absolute and relative errors.

  4. Prints a formatted comparison table to stdout and writes nktg_8planets.csv.

How to compile & run (example using gfortran):

gfortran -O2 -std=f2008 -o nktg_8planets nktg_8planets.f90
./nktg_8planets

The program prints a table similar to the original document and saves nktg_8planets.csv for plotting with your preferred tool (gnuplot, Python, Excel, etc).

Below is the full Fortran source. Feel free to suggest additions (time series / GRACE comparisons / CSV format tweaks / gnuplot script).


Fortran program — nktg_8planets.f90

! nktg_8planets.f90
! Fortran 2008 program: NKTg-based interpolation of planetary masses (Mercury -> Neptune)
! Data from: NASA JPL Horizons snapshot (30-31 Dec 2024) and NKTg1 values provided in the user's file.
!
! Compile:
!   gfortran -O2 -std=f2008 -o nktg_8planets nktg_8planets.f90
! Run:
!   ./nktg_8planets
!
program nktg_8planets
  implicit none
  integer, parameter :: dp = selected_real_kind(15, 307)
  integer, parameter :: nplan = 8
  integer :: i, ios
  character(len=16), dimension(nplan) :: name
  real(dp), dimension(nplan) :: x_km, v_km_s, nktg1, nasa_mass, interp_mass, delta_mass, rel_error
  character(len=80) :: csvfile

  ! --- Data: name, x (km), v (km/s), NKTg1 (unit consistent), NASA mass (kg)
  ! Values taken from user's document (30-31/12/2024)
  name = (/ 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune' /)

  x_km = [ 6.9817930e7_dp,   & ! Mercury
           1.0893900e8_dp,   & ! Venus
           1.4710000e8_dp,   & ! Earth
           2.4923000e8_dp,   & ! Mars
           8.1662000e8_dp,   & ! Jupiter
           1.5065300e9_dp,   & ! Saturn
           3.0013900e9_dp,   & ! Uranus
           4.5589000e9_dp ]     ! Neptune

  v_km_s = [ 38.86_dp, 35.02_dp, 29.29_dp, 24.07_dp, 13.06_dp, 9.69_dp, 6.80_dp, 5.43_dp ]

  nktg1 = [ 8.951e32_dp, 1.858e34_dp, 2.571e34_dp, 3.850e33_dp, 2.024e37_dp, 8.303e36_dp, 1.772e36_dp, 2.534e36_dp ]

  nasa_mass = [ 3.301e23_dp, 4.867e24_dp, 5.972e24_dp, 6.417e23_dp, 1.898e27_dp, 5.683e26_dp, 8.681e25_dp, 1.024e26_dp ]

  ! --- Compute interpolated masses and errors
  do i = 1, nplan
    if ( x_km(i) * v_km_s(i) /= 0.0_dp ) then
      interp_mass(i) = nktg1(i) / ( x_km(i) * v_km_s(i) )
    else
      interp_mass(i) = 0.0_dp
    end if
    delta_mass(i) = nasa_mass(i) - interp_mass(i)
    if ( nasa_mass(i) /= 0.0_dp ) then
      rel_error(i) = abs(delta_mass(i)) / abs(nasa_mass(i))
    else
      rel_error(i) = 0.0_dp
    end if
  end do

  ! --- Print header
  write(*, '(A)') 'NKTg Interpolation of Planetary Masses (Mercury -> Neptune)'
  write(*, '(A)') 'Formula used: m = NKTg1 / (x * v)    (x in km, v in km/s)'
  write(*, *)
  write(*, '(A)') '---------------------------------------------------------------------------------------------'
  write(*, '(A)') ' Planet     NASA (kg)       Interp (kg)      Delta (NASA - Interp)    RelError'
  write(*, '(A)') '---------------------------------------------------------------------------------------------'

  do i = 1, nplan
    write(*,'(A10,2X,1PE13.6,2X,1PE13.6,2X,1PE13.6,2X,1PE8.3)') trim(adjustl(name(i))), nasa_mass(i), interp_mass(i), delta_mass(i), rel_error(i)
  end do
  write(*, '(A)') '---------------------------------------------------------------------------------------------'

  ! Summary
  call print_summary(nplan, name, rel_error, nasa_mass, interp_mass)

  ! Write CSV for external plotting
  csvfile = 'nktg_8planets.csv'
  open(unit=10, file=csvfile, status='replace', action='write', iostat=ios)
  if (ios /= 0) then
    write(*,'(A)') 'Warning: cannot open CSV file for writing.'
  else
    write(10, '(A)') 'Planet,x_km,v_km_s,NKTg1,NASA_kg,Interp_kg,Delta_kg,RelError'
    do i = 1, nplan
      write(10,'(A,1X,F0.6,1X,F0.6,1X,1PE0.6,1X,1PE0.6,1X,1PE0.6,1X,1PE0.6)') &
           trim(adjustl(name(i))) // ',', x_km(i), v_km_s(i), nktg1(i), nasa_mass(i), interp_mass(i), delta_mass(i), rel_error(i)
    end do
    close(10)
    write(*,'(A,A)') 'CSV written to: ', trim(csvfile)
  end if

contains

  subroutine print_summary(n, names, relerr, nasa, interp)
    integer, intent(in) :: n
    character(len=*), dimension(n), intent(in) :: names
    real(dp), dimension(n), intent(in) :: relerr, nasa, interp
    real(dp) :: max_rel, mean_rel
    integer :: j

    max_rel = 0.0_dp
    mean_rel = 0.0_dp
    do j = 1, n
      if ( relerr(j) > max_rel ) max_rel = relerr(j)
      mean_rel = mean_rel + relerr(j)
    end do
    mean_rel = mean_rel / real(n, dp)

    write(*, *)
    write(*,'(A)') 'Summary statistics:'
    write(*,'(A,1X,F0.6)') ' Max relative error: ', max_rel
    write(*,'(A,1X,F0.6)') ' Mean relative error: ', mean_rel
    write(*, *)
    write(*,'(A)') 'Notes: Input NKTg1 values were taken from the supplied document. With these inputs the interpolation'
    write(*,'(A)') '       reproduces NASA masses with negligible relative errors (as reported in the original file).'
  end subroutine print_summary

end program nktg_8planets


Notes / caveats

  • The Fortran program uses double precision (selected_real_kind(15,307)) to keep numerical accuracy.

  • CSV formatting uses simple fields; you can adapt the CSV writer to include full precision if needed.

  • The original Word file mentioned Earth mass variations (GRACE/GRACE-FO). If you want, I can extend the program to ingest time-series data (CSV of dates/x/v) and compute time evolution & plots (CSV → gnuplot).

  • If you prefer, I can also produce a gnuplot script to visualize relative errors or export a high-resolution PNG.