GSF - Physical Systems Generator
Available in Español .
Back in 1994 I was studying physics at the University of Valencia and stumbled onto a chapter by Richard Feynman that described how to predict a particle’s path numerically. I wanted to see those equations breathe, so I wrote a tiny C program that evolved into GSF – the Physical Systems Generator.
The idea was intentionally simple: describe the particles, forces, and initial conditions in text files, let the program iterate the equations, and output new files with the resulting trajectories. Today I would use JSON for everything and pipe the results into a visualisation, but in the mid‑90s a terminal full of numbers already felt like science fiction.
I recently recovered the original source code and uploaded it to GitHub. Reading those files is like meeting my younger self—dense comments, handcrafted parsers, and a lot of love for numerical experiments.
Original program documentation
The easiest way to see what all this does is to try the DEMOs that accompany the programs. So, if you haven’t already, run one first (for example, type demo001
).
The GSF environment consists of two programs: GSFMS and GSFVM. The GSFMS program is the physics systems engine. It is the program responsible for generating all the movements of a physical system, which is provided as input, as time progresses. To see the results, the GSFVM viewer is used. This program is a direct command processor and can perform various functions of displaying movements on the screen, both in 2D and 3D.
The programs have been developed in C using QuickC, and are included along with the executables. GSFMS might be portable to other compilers like Turbo C, but I don’t think it’s possible (without many modifications) to do the same with GSFVM.
The included demos call GSFVM and pass it the data previously calculated by GSFMS, in addition to the commands it must execute.
The idea for this program came after reading a book by Feynman where he proposed a numerical method to calculate the trajectory of a particle subjected to forces. With the fundamental knowledge of a first-year physics course at the University of Valencia and a good numerical method, I began to write the program. This is what came out. I would greatly appreciate, from anyone who wishes, advice, improvements, etc.
GSFMS - Systems Engine
GSFMS accepts as input a file describing the system to be moved. The description gives the number of particles or bodies involved, the duration of the animation, the dimension of the space in which they move, etc., as well as the initial conditions of the movement and the fields involved. We will call the input file a ‘physical system file’, or fsf.
An fsf file consists of two blocks. The first is the environment definition block and is of the form:
DefEntorno={var=const;var=const;car=const;....}
The assignments allow setting the values of the main environment variables. The variables are:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
NumBodys - Number of bodies involved.
Tiempo - Time the animation of the movement lasts.
IncTemporal - Time increment in each step. We cannot
forget that we work with numerical methods to
solve differential equations. A small time
increment ensures greater precision. In
each case we must reach a compromise between
precision and calculation time (the smaller the
increment, the more calculations are performed).
SpaceDimension - This variable contains the dimension of the space in
which the particles move.
NumCampos - Number of force fields involved.
SinInteraccion - This variable allows the possibility of making
particles insensitive to each other, even if they generate similar fields.
It is a two-state variable, set to Yes or No.
An example of an environment definition would be:
1
2
3
4
5
6
7
DefEntorno = {
NumBodys = 22;
Tiempo = 60;
IncTemporal = 0.2;
SpaceDimension = 2;
NumCampos = 2;
}
The second block in an fsf file is the system definition. This block is of the form:
DefSistema={ {defpart},{defpart},...}
where defpart is the definition of a particle. The definition of a particle consists of 4 parts and is of the form:
{initial.pos}, {initial.vel}, {field1,field2,...}, {mgs1,mgs2,...}
An example: {-5,0,0}, {0, 0.2,0} , {Null,UnitA}, {15, 5}
This example defines a particle that is at position (-5,0,0) in space at the initial instant, and starts with a velocity of (0,0.2,0). It also has a null field (we’ll see what that is later) and generates a Unitary Attractive field. The field magnitudes are 15 for Null and 5 for UnitA.
All particles are defined in the same way and are numbered by their position starting from zero: the first particle is particle 0, the second defined particle is 1, and so on.
The initial position is of the form {x,y} if we are in 2D and of the form {x,y,z} if we are in 3D. The velocity follows the same criterion.
The part reserved for fields allows us to put as many fields as we want, but there must be as many as indicated by NumCampos. It is also essential that the first field be gravitational or null. This is because, in any case, mgs1 is ALWAYS the mass of the particle. The rest of the fields must be defined the same for all particles. Thus, if we define the second field as electric, all particles must have the electric field or null as their second field (if not, the effects can be very strange). This is because while the ‘field’ only says that the particle generates said field, the corresponding mgs indicates the value with which it generates it and the value with which it is sensitive to it. We will see this in more detail later.
You can choose from the following fields:
- Gravit - Gravitational field
- Elect - Electric field
- UnitA - Newtonian attractive field with constant 1
- UnitR - Newtonian repulsive field with constant 1
- Elast - Elastic field
- Null - Does not generate that field
The gravitational and electric fields are the usual ones. The unitary fields are the ones that require more attention. The UnitA field is the same as the gravitational one but with G=1. The UnitR field is like UnitA but repulsive.
The Null field is used so that the particle does not generate that field. In the previous example
{-5,0,0}, {0, 0.2,0} , {Null,UnitA}, {15, 5}
the particle, with mass 15, does not generate a gravitational field.
In this other example,
1
2
{ { 8,7,0}, {0,0,0.3}, {null,null}, {1,5} },
{ { 9,7,0}, {0,0,0.7}, {null,unita}, {5,5} }
the first particle does not generate the UnitA field, but since it has an mgs of 5 associated with that field, it DOES experience the force due to the other particle that DOES generate the field. The other particle, on the contrary, will not experience any force since the first one does not generate a UnitA field.
If we wanted to completely detach the first one, we would just have to do:
1
2
{ { 8,7,0}, {0,0,0}, {null,null}, {1,0} },
{ { 9,7,0}, {0,0,0.7}, {null,unita}, {5,5} }
Let’s see the following example:
1
2
3
{ {-5,0}, {0, 0.2}, {Null,Null}, {15, 5} },
{ { 0,0}, {0, 0.3}, {Null,UnitA}, {1, 0.7} },
{ { 5,0}, {0, 0.2}, {Null,Null}, {15, 5} }
We have 3 particles moving in the positive y-axis direction. The one in the middle, faster, generates a UnitA field. The others generate nothing, but are sensitive to the attractive unitary field. This is why they approach the central one, without the latter suffering any disturbance in its movement. If we had done,
1
2
3
{ {-5,0}, {0, 0.2}, {Null,Null}, {15, 0} },
{ { 0,0}, {0, 0.3}, {Null,UnitA}, {1, 0.7} },
{ { 5,0}, {0, 0.2}, {Null,Null}, {15, 5} }
the particle on the left would not experience any force, since we have set its sensitive/generating magnitude to zero. As it was not generating anything, what we have done is to make it insensitive to that field.
Another very interesting field is the elastic one: Elast. This field defines its mgs differently:
{part1,k1,d1,part2,k2,d2,...}
It is a succession of: particle with which it is linked, elastic constant, rest distance. Thus, the definition:
1
{ {-10,0}, {0,0}, {null,elast}, {10,{1,3,1}} } (particle n)
tells us that this particle, with mass 10, experiences elastic forces with an elastic constant of 3, when particle number 1 moves away from the equilibrium distance (1 unit of length). It is important to note that this does not imply that particle 1 will experience the reaction force. If we want this to happen, we will have to ‘tie’ it to the previous particle in the same way ( {n,3,1} ).
This is all you need to know. For more details (or more technical things), just -heh, heh,…- look at the source code. Anyway, I think the possibilities are endless with what is there. Have fun.
GSFVM - Movement Viewer
GSFVM is a command processor oriented to the visualization of movements generated by GSFMS.
When called from DOS, it accepts the movement file and the video mode in which you want to work. Once the movements are loaded into memory, a prompt appears waiting for you to enter commands.
The commands are a word, followed by one or two parameters separated by commas.
Let’s see what they are (1P=one parameter, 2P=two parameters):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Quit - To exit GSFVM
MovSis - Moves the system
Escala 1P - Scale factor. Initially it is 10
Centrox 1P - X coordinate in pixels of the center
Centroy 1P - Y coordinate in pixels of the center
Retardo 1P - Time in milliseconds of delay per animation
cycle. If you want to see the animation
more slowly use this command.
Steep - Increment per cycle in the movement number. This
command is very important if your computer is
slow, as it speeds up (at the cost of smoothness in the
movement) the animation.
Cls - Clear screen (did anyone doubt it)
Marca 1P - It has two effects:
- On MovSis, it indicates how often a
trace is left. This allows you to see the trajectories.
- On Ejes, it determines the density of points
that are drawn of the axes.
Print 1P - The parameter is the text (less than 1 line)
that is displayed at the last position given by
locate.
Locate 2P - Positions the cursor for Print
Wait 1P - Pause: time in milliseconds.
Color 1P - Color for: Print, Ejes.
OjoX 1P - X position of the point of view
OjoY 1P - Y position of the point of view
OjoZ 1P - Z position of the point of view
Ejes 1P - Draws 3D axes, with a length given by
its parameter.
When you are in 3D you can change the point of view. There is something to be said about this. The coordinates of the ‘eye’ do not place anything more than the direction from which you look at the center. The distance is determined by the scale factor. The Print command has no limitations within the viewing window: if the text is too large, it will go out of it. As there are not too many commands, just grab a system from one of the demos and try them all.