跳到内容

膨胀球壳延缓引力势中的运动物体/Java程序

来自维基教科书,开放的书籍,开放的世界

带计算结果的表格


Java程序

[编辑 | 编辑源代码]

以下 Java 程序可用于数值计算不同线性质量密度下的史瓦西距离。它实现了有效质量的数值积分以及史瓦西距离的数值求解。

/*
  Source file: SchwarzschildDistance.java
  Program: Computation of the Schwarzschild Distance within the Hubble sphere
  Autor: Markus Bautsch
  Location: Berlin, Germany
  Licence: public domain
  Date: 18th July 2024
  Version: 1.3
  Programming language: Java
 */

/*
  This Java-Programm computes Schwarzschild distances for any black shell masses.
  The black shell is at the outer rim of the Hubble space.
 */

public class SchwarzschildDistance
{
	// Class constants
	final static double G = 6.67430e-11; // Gravitational constant in cube metres per kilogram and square second
	final static double c = 2.99792458e8; // Speed of light in metres per second
	final static double TropicalYear = 365.24219052 * 24 * 3600; // Tropical year in seconds
	final static double LightYear = c * TropicalYear; // Light-year in metres
	final static double R = 1.36e26; // Hubble length in metres
	final static double MUniverse = 2.97e53; // Mass of the visible universe in kilograms

	final static double lambdaMfirst = 3.36663e26; // start value for linear mass density of black shell
	final static double lambdaMlast  = 3.36670e26; // startop value for linear mass density of black shell
	final static double deltaLambda  = 0.00001e26; // step size for linear mass density of black shell

	// This method computes and returns the distance s of a mass m to a mass point dM in the black shell
	// distance is the closest distance of the mass m to to the mass point dM in the black shell in m
	// alpha is the angle beweteen the mass m and the mass point dM in the black shell as seen from the centre of the universe in rad
	private static double distanceToMassElementShell (double distance, double alpha)
	{
		double cosAlpha = java.lang.Math.cos (alpha);	
		double squareDistance = distance * distance;
		double argument = 2*R*R - 2*R*distance + squareDistance - 2*R*(R-distance)*cosAlpha;
		double s;			
		if (argument <= squareDistance) // because of possible rounding errors
		{
			s = distance;
		}
		else
		{
			s = java.lang.Math.sqrt (argument);
		}
		return s;
	}

	// This method computes and returns the angle of a half chord x in m as seen from the centre of the universe in rad
	private static double alpha (double x)
	{
		double alpha = java.lang.Math.asin (x / R);
		return alpha;
	}

	// This method computes and returns the integrand of the integral
	// distance is the closest distance of the mass m to to the mass point dM in the black shell in m
	// alpha is the angle beweteen the mass m and the mass point dM in the black shell as seen from the centre of the universe in rad
	private static double integrand (double distance, double alpha)
	{
		double s = distanceToMassElementShell (distance, alpha);
		double e = R * (1 - java.lang.Math.cos (alpha)); // the auxiliary sagitta e
		double cosBeta = (distance - e) / s;
		double integrand = cosBeta / s / s;
		return integrand;
	}

	// This method computes and returns the effective mass from 0 to alphaR for a given lambdaM and a given distance
	// lambdaM is the linear mass density of the black shell in kg/m
	// distance is the closest distance of the mass m to to the mass point dM in the black shell in m
	private static double integrateEffectiveMass (double lambdaM, double distance)
	{
		final long steps = 1000000; // number of steps for numerical integration
		double squareDistance = distance * distance;
		double xMax = java.lang.Math.sqrt (2*R*distance - squareDistance); // maximum half chord for a given maximum angle alphaR
		double x = xMax; // x runs from xMax to 0 in steps of deltaX
		double alpha = alpha (x); // alpha runs from alphaR to 0
		double integrand = integrand (distance, alpha);
		double integral = 0;
		long step = 0;
		while (step <= steps)
		{
			x = xMax * (1 - (double) step / steps);
			double alphaNext = alpha (x);
			double integrandNext = integrand (distance, alphaNext);
			double deltaAlpha = alpha - alphaNext;
			double averageIntegrand = (integrandNext + integrand) / 2;
			double area = averageIntegrand * deltaAlpha; // numerical integration
			integral = integral + area;
			alpha = alphaNext;
			integrand = integrandNext;
			step++;
		}
		double effectiveMass = R * lambdaM * squareDistance * (2*integral);
		return effectiveMass;
	}

	// This method computes and returns the Schwarzschild distance d_S for a given effective mass mEff
	private static double schwarzschildDistance (double effectiveMass)
	{
		double schwarzschildDistance = 2 * G * effectiveMass / c / c;
		return schwarzschildDistance;
	}

	// This method computes and returns the effective mass mEff for a given Schwarzschild distance d_S
	private static double effectiveMass (double schwarzschildDistance)
	{
		double effectiveMass = schwarzschildDistance * c * c / 2 / G;
		return effectiveMass;
	}

	// This method solves and returns the Schwarzschild distance d_S for a given lambdaM
	// lambdaM is the linear mass density of the black shell in kg/m
	private static double solve (double lambdaM)
	{
		final double limit = 5e-16; // for relative precision of determination of Schwarzschild distance
		double lowerDistance = 1e20; // first low guess for Schwarzschild distance
		double upperDistance = 1e25; // first high guess for Schwarzschild distance
		double delta; // delta shall become smaller than limit
		double distance;
		double schwarzschildDistance;
		double deltaDistance;
		do
		{
			distance = (lowerDistance + upperDistance) / 2;
			double effectiveMass = integrateEffectiveMass (lambdaM, distance);
			schwarzschildDistance = schwarzschildDistance (effectiveMass);
			deltaDistance = (distance - schwarzschildDistance) / schwarzschildDistance;
			if (deltaDistance < 0) // Schwarzschild distance too large
			{
				lowerDistance = (upperDistance + lowerDistance) / 2;
			}
			else // Schwarzschild distance too small
			{
				upperDistance = (upperDistance + lowerDistance) / 2;
			}
			delta = (upperDistance - lowerDistance) / lowerDistance;
		} while (delta > limit);
		if (java.lang.Math.abs (deltaDistance) > 1e-6)
		{
			java.lang.System.out.println ("unstable numerical result:");
			java.lang.System.out.println ("Computed      distance = " + distance);
			java.lang.System.out.println ("Schwarzschild distance = " + schwarzschildDistance);
		}
		return schwarzschildDistance;
	}

	// This method outputs the table header
	private static void printHeader ()
	{
		java.lang.System.out.print ("lambda_M in kg/m;");
		java.lang.System.out.print ("   M_S  in kg   ;");
		java.lang.System.out.print ("   M_S/M        ;");
		java.lang.System.out.print ("   M_eff in kg  ;");
		java.lang.System.out.print ("   d_S im m     ;");
		java.lang.System.out.print ("   d_S/R        ;");
		java.lang.System.out.print ("   d_S in ly    ;");
		java.lang.System.out.print ("   (R-d)/R      ");
		java.lang.System.out.println ();
	}

	// This method outputs a table result line
	// lambdaM is the linear mass density of the black shell in kg/m
	// distance is the closest distance of the mass m to to the mass point dM in the black shell in m
	// mEff is the effective mass of a sphere in the black shell
	private static void printResults (double lambdaM, double distance, double effectiveMass)
	{
		double mShell = lambdaM * R * 2 * java.lang.Math.PI; // mass of black shell
		double mRatio = mShell / MUniverse;
		double dRatio = distance / R;
		double dLightYears = distance / LightYear;
		double deltaRatio = (R - distance) / R;
		java.lang.System.out.printf ("%15.7e", lambdaM);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.6e", mShell);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.6f", mRatio);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.2e", effectiveMass);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.2e", distance);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.2e", dRatio);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.0f", dLightYears);
		java.lang.System.out.print (" ;");
		java.lang.System.out.printf ("%15.9f", + deltaRatio);
		java.lang.System.out.println ();
	}

	// This method has a loop for computing a sequence of effective masses and Schwarzschild distances for different lambdaM values
	// lambdaM is iterated from lambdaMfirst to lambdaMlast in steps of deltaLambda
	private static void computeScharzschildRadii (double lambdaMfirst, double lambdaMlast, double deltaLambda)
	{
		double lambdaM = lambdaMfirst; // linear mass density of black shell at Hubble radius in kg/m
		lambdaMlast = lambdaMlast * 1.00000001; // for the reason of numerical rounding errors
		printHeader ();
		do
		{
			double schwarzschildDistance = solve (lambdaM);
			double effectiveMass = effectiveMass (schwarzschildDistance);
			printResults (lambdaM, schwarzschildDistance, effectiveMass);
			lambdaM = lambdaM + deltaLambda;
		} while (lambdaM <= lambdaMlast);
	}

	// Main program
	public static void main (java.lang.String [] arguments)
	{
		computeScharzschildRadii (lambdaMfirst, lambdaMlast, deltaLambda);
	}
}
华夏公益教科书