![]() |
![]() |
![]() |
We introduce, in this lesson, new aspects of OFELI programmation:
The Finite Element Code
#include "OFELI.h" #include "Therm.h" using namespace OFELI; |
int main(int argc, char *argv[]) { |
if (argc <= 1) { cout << " Usage: lesson4 <parameter_file>" << endl; exit(1) } IPF data(argv[1]); |
theFinalTime = data.getMaxTime(); theTimeStep = data.getTimeStep(); |
Mesh ms(data.getMeshFile()); |
User ud(ms); |
Implementation of class User will be given later.
SkSMatrix<double> A(ms); Vect<double> b(ms.getNbDOF()), u(ms.getNbDOF()), bc(ms.getNbDOF()); |
ud.setInitialData(u); |
TimeLoop { |
b = 0; |
ud.setTime(theTime); |
ud.setDBC(bc); |
MeshElements(ms) { |
DC2DT3 eq(theElement,u,theTime); |
eq.LCapacity(1./theTimeStep); eq.Diffusion(); |
Note that capacity matrix is multiplied by the inverse of time step. This is necessary to implement the backward Euler scheme.
if (theStep==1) eq.ElementAssembly(A); eq.ElementAssembly(b); } |
The loop on elements is closed.
MeshSides(ms) { |
DC2DT3 eq(theSide,u,theTime); |
eq.BoundaryRHS(ud); |
eq.SideAssembly(b); } |
A.Prescribe(b,bc,theStep-1); |
A.solve(b); |
u = b; |
cout << "\nSolution for time: " << time << endl << u; } return 0; } |
and then close the time stepping loop and the program.
#include "OFELI.h" using namespace OFELI; |
class User : public UserData<double> { |
public : |
User(Mesh &mesh) : UserData<double>(mesh) { } |
double BoundaryCondition(const Point<double> &x, int code, double time=0., size_t dof=1) { double ret = 0.0; if (code == 2) ret = 1.0; return ret; } |
double SurfaceForce(const Point<double> &x, int code, double time, size_t dof) { if (code) return 1.0; else return 0.0; } |
}; |
A test
We use here exactly the same mesh file as in the previous lesson. Of course, we obtain the same solution. The convergence is obtained after 3 iterations.
![]() |
![]() |
![]() |