I have coded some classes for some computational exercises. But I cannot declare and assign an object of a derived class despite it being included in header files. Not really sure where I have made an error here.
//main.cpp
#include "ForwardEulerSolver.h" //provide the class definition of the objects you want to instantiate
#include "RungeKutta.h"
//no need to forward declare other classes, or the classes already defined
int main(){
//...
}
1 2 3 4 5 6 7 8 9 10 11 12
//AbstractOdeSolver.h
//#pragma once //this have the same effect than the ifndef define combo, if your compiler support it
#ifndef ABSTRACTODESOLVER_H //this is a unique identifier
#define ABSTRACTODESOLVER_H
//no need to forward declare other classes, or the class we are about to define
//using namespece std; //this pollutes any source that includes this file
class AbstractOdeSolver{
//...
};
//your member function implementation should be in another .cpp
#endif
1 2 3 4 5 6 7 8 9 10 11 12
//AbstractOdeSolver.cpp
#include "AbstractOdeSolver.h"
#include <iostream>
usingnamespace std; //this is a source file, the pollution is contained here
//member function implementation
void AbstractOdeSolver::SetStepSize(double h)
{
stepSize = h;
cout << "The step size has been set to " << stepSize << endl;
}
1 2 3 4 5 6 7 8 9 10 11
//ForwardEulerSolver.h
#ifndef FORWARDEULERSOLVER_H //again, unique identifier
#define FORWARDEULERSOLVER_H
#include "AbstractOdeSolver.h" //we need the class definition to derive from it
class ForwardEulerSolver : publicvirtual AbstractOdeSolver{ //¿do you actually want virtual inheritance?
//...
};
//again, may separate member function implementation (ForwardEulerSolver.cpp)
#endif
1 2 3 4 5 6 7 8 9 10 11 12 13
//RungeKutta.h
#ifndef RUNGEKUTTA_H //again, unique identifier
#define RUNGEKUTTA_H
#include "AbstractOdeSolver.h" //we need the class definition to derive from it
//no need to even mention ForwardEulerSolver
//don't include .cpp, that may give you multiple definition errors
//http://www.cplusplus.com/forum/general/140198/class RungeKutta : public AbstractOdeSolver{ //¿no virtual here?
//...
};
//and yet again, may separate member function implementation (RungeKutta.cpp)
#endif
You have effectively coded up Simpson's rule for numerical integration, not a general Runge-Kutta solver. If you want to make it a general solver then dy_dt() needs to be a function of both t AND y.
Yes, I think the point of the exercise was to have an analytical solution to check against. In the forward euler solver class I had also compared the values against the analytical one just to see it's degree of accuracy.