Earth's gravitational field

1. Nov 17, 2015

whatisreality

I'm trying to write a class for the gravitational field of any planet (I tested it with values for Earth though), and it gives completely the wrong answer! I suspect this is either a mathematical error, or an issue with my declarations of stuff as public, private, static etc. Compiles, just doesn't actually work! I can also post my main class if helpful.
I have access to a class called PhysicsVector, which can perform pretty much every operation imaginable on vectors.
Here's my code, trying to use Newton's law of Gravity:

Code (Java):

import java.lang.Math;

public class GravField{

public static final double G = 6.674*Math.pow(10,-11);       //Gravitational constant, same for everything
private double planetMass=0;
private double projectileX=0;
private double projectileY=0;
PhysicsVector projectilePosition = new PhysicsVector(a, projectileY);   //Haven't declared a yet, don't know if that's allowed
PhysicsVector gravityAcceleration = new PhysicsVector();

public GravField(double planetMass, double planetRadius, double projectileX, double projectileY){

double distance = Math.sqrt(projectileX*projectileX+projectileY*projectileY);   //Distance of projectile from Earth
double a = planetRadius + projectileX;         //Newton's law assumes origin at planet centre,
//my co-ord system starts at planet surface

double x = (-G*planetMass*projectileX)/(distance*distance*distance);   //Probably some maths mistake here
double y = (-G*planetMass*projectileY)/(distance*distance*distance);

gravityAcceleration.setVector(x, y);         //setVector is in PhysicsVector class and makes vector
gravityAcceleration.print2D();           //xi + yj

}

public static double magnitude(PhysicsVector gravityAcceleration){

double magnitudeOfGravField = gravityAcceleration.magnitude();   //again magnitude is in PhysicsVector class
return magnitudeOfGravField;

}
}

2. Nov 17, 2015

SteamKing

Staff Emeritus
Well, a planet mass of 0 is not going to work very well.

Also, "My program just doesn't work!" contains very little diagnostic information.

When numerically modeling a physical situation, it is a good idea to keep a list of the equations used in your model to help determine if those are the ones actually contained in your code. It's also a good idea to insert some comments in your code which briefly describe what it is you are modeling and how you are doing it.

3. Nov 17, 2015

whatisreality

But all I know is that it doesn't work. It does compile, just gives the wrong answer. And although I initialised the variables to zero, when I created 'GravField earth = new GravField' in my main class, I gave it arguments that were non zero, i.e. filled in the values of planetMass etc.

This is the first multi-class thing that I've written, and I don't even know where to start looking for my mistake. I was trying to create a 'GravField' object, didn't succeed though... Is it right to use a constructor, by the way? To create an object?

4. Nov 17, 2015

whatisreality

Oh yeah, and I'm trying to simulate Earth's gravitational field acting on some small projectile. :) To do that, I want to write a class that calculates the gravitational field of any planet, if I give it the mass, radius etc.

5. Nov 17, 2015

SteamKing

Staff Emeritus
Well, sharing some of the numbers this program puts out would be a big help in figuring out what is going on. That's what I mean by 'diagnostic information'.

The details of your model still aren't clear. Are you trying to simulate the 2-D path of a projectile fired from the surface of the earth? How general is this model supposed to be? Is it supposed to handle artillery fire, rockets, what?

If you're trying to solve simple projectile problems, that's one thing. If you want to solve more than that, things could get complicated.

6. Nov 17, 2015

whatisreality

Oh, I get it! Sorry. So I'm trying to simulate the 2D path of a projectile fired from the surface, yeah. And the GravField class is supposed to be able to represent the field of any planet. For now the projectile has negligible mass.
Numbers: Well, I tried entering the mass of the earth, its radius, and starting the projectile at 0,0. Subsequent values of x and y are calculated using Euler's algorithm, but I set the initial x velocity to zero so the motion is purely vertical. And g, it turns out, is actually 6.35. Not 9.81. ;)

7. Nov 17, 2015

SteamKing

Staff Emeritus
Well, what's the mass of the earth and the radius which you are using?

8. Nov 17, 2015

whatisreality

mass of earth: 5.972 x 10^24 kg, radius of earth 6,371 x 10^3 m. Just from wikipedia.

9. Nov 17, 2015

SteamKing

Staff Emeritus
g = G(Mem) / re2

g = 6.674 Ã— 10-11 â‹… (5.972 Ã— 1024 â‹… 1) / (6,371,000)2

g = 9.82 m/s2

You'll have to check the code which makes this calculation. It doesn't appear to be included in the code listing in the OP.

10. Nov 17, 2015

whatisreality

Oh, hang on. I've not added the radius to the y-component of position. I think I should have used a instead of projectileY in my gravityAcceleration vector.

11. Nov 17, 2015

whatisreality

I've just broken my code! Now I just get NaN for every output!

12. Nov 17, 2015

whatisreality

Here's my main class. Clearly something incredibly wrong with it :(
I seriously appreciate your help, by the way, I'm just posting huge amounts of messy code...
Code (Java):

import java.util.Scanner;
import java.lang.Math;

public class ParticleSim{

public static void main(String[] args){

Scanner scanner = new Scanner(System.in);
System.out.println("Please enter the size of the time step:");
double timeStep = scanner.nextDouble();
System.out.println("Please enter the initial x velocity:");
double initialXVelocity = scanner.nextDouble();
System.out.println("Please enter the initial y velocity:");
double initialYVelocity = scanner.nextDouble();

PhysicsVector projectilePosition = new PhysicsVector();

double earthMass = 5.972*Math.pow(10,24);

GravField earth = new GravField(earthMass, earthRadius, 0, 0);

double y=0.0;
double x=0.0;
double yVelocity=initialYVelocity;
double xVelocity=initialXVelocity;

do{ //either this loop or my GravField class is the problem, I think!
System.out.println("Hi! I'm in the loop!");
y += yVelocity * timeStep; //Euler's algorithm to calculate positions and velocities
x += xVelocity*timeStep;
yVelocity += earth.componentY() * timeStep;
xVelocity += earth.componentX() * timeStep;

PhysicsVector velocity = new PhysicsVector();
PhysicsVector position = new PhysicsVector();
velocity.setVector(xVelocity, yVelocity);
position.setVector(x, y);

velocity.print();
position.print();

timeStep += timeStep;
}while(y>0);

}
}

13. Nov 17, 2015

SteamKing

Staff Emeritus
Getting NaN suggests to me that something got corrupted after your latest modifications, a variable got misspelled or something else got changed inadvertently.

I notice you have this statement at the end of your while loop:

timeStep += timeStep;

I'm not sure, but I think this statement means timeStep = timeStep + timeStep, which, if correct, would increase the value stored in timeStep every time the while loop was executed. You might want to use another variable to accumulate the time elapsed during the simulation.

The Euler method is notoriously slow and sensitive to the size of the steps used.

14. Nov 17, 2015

whatisreality

Oh, yes it would! Thanks, that would have caused huge problems. If I instead wrote double t = timestep, outside the loop, and then t += timestep, would that be better? I think that solves that problem.
And the Euler method is bad, there are loads better. Only this code gets marked by a robot, so we all have to use the same method, which in this case we've been told is the Euler method. Unfortunate!

15. Nov 17, 2015

SteamKing

Staff Emeritus
Yes, I think your changes make a difference.

16. Nov 17, 2015

whatisreality

Oh, whoops. This code is riddled with mistakes. Am I asking it to divide by zero? If I set projectileX to zero, then my distance will be zero, and dividing by zero is bad...

Even if that's what I'm doing, I don't see an easy way to change it! How does Newton's law deal with things at the origin? Well, it doesn't in this case...

17. Nov 17, 2015

SteamKing

Staff Emeritus
I thought the origin for your simulation was the center of the earth, or whatever planet you intend to use.

Newton's law of gravity breaks down when r = 0 because it is physically impossible for two separate objects to occupy the same location, which is what r = 0 means.

18. Nov 17, 2015

whatisreality

Oh. Yes, my origin is the centre of the earth - but I thought to move between those frames, all I had to do was add the radius onto the y value. Shouldn't the x values be the same??

19. Nov 17, 2015

SteamKing

Staff Emeritus
I think you need to start drawing some sketches here.

The earth is actually a 3-D spheroid. We locate ourselves on its surface by the intersection of imaginary lines of longitude and latitude, which are constructed starting a some convenient reference location. Over small areas, we can draw 2-D maps and pretend that the earth's surface at that location can be treated like an x-y plane, but the underlying 3-D nature of the earth can't always be neglected, such as when figuring out the path that projectiles take.