Simple Open Dynamics Engine (ODE)

I created the following code to solve a simple ODE. It is clear enough? Is it efficient code? I really want to read opinions because I want to make all my exercise solutions the same way (same structure of the program), so I need to make sure that this code is really clear and efficient.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

class step
{
public:
step()
: time(0.), velocity(0.) {}
step(const double& t, const double& v)
: time(t), velocity(v) {}

double time;
double velocity;
};

void calculate(
std::vector<step>& steps,
double g,
double t_max,
double dt)
{
int iterations(t_max / dt + 1);

steps.resize(iterations);

for(int i(0); i <= iterations; i++)
{
steps[i+1].time = steps[i].time + dt;
steps[i+1].velocity = steps[i].velocity - g * dt;
}
}

void save(
const std::vector<step>& steps,
const std::string& filename)
{
std::ofstream out(filename);

for(int i(0); i < steps.size(); i++)
{
out << steps[i].time << ' ' << steps[i].velocity << std::endl;
}
}

int main()
{
double g(9.81);
double t_max(10.);
double dt(0.01);

step initial_conditions(0.,0.);
std::vector< step > steps({initial_conditions});

calculate(steps, g, t_max, dt);
save(steps, "ex_1.1.dat");

return 0;
}


Although I'm not a C++ programmer I once held a course in computations with Matlab for physicists. So I can only give hints and thoughts on your code but I won't answer your question on efficiency.

As you mentioned that this code will be the basic of following exercises, I'm missing all sorts of documentation. If you are planning to teach someone (solving) ODEs with this code, you should at least refer to a physical or mathematical problem, which will be solved by your code and you should comment every function and what it does. However, if you want to teach writing clean code, you should separate your definitions from the implementation. I'm the opinion that variables should have meaningful names even if you are referring to the standard variable names in physics (like g for gravity). This will ease the burden of understanding the code if you are not familiar with standard variable names.

Lastly, there is the call to the resize method of the vector. As I am no C++ programmer, so I can't say for sure, but I feel uncomfortable with this function. I searched in a C++ reference and found out about the method reserve which might be more appropriate in a safer way.