Adding a speed function

Introduction

Multivac is designed to handle a wide range of front propagation problems. One may want to provide his own initial front and his own speed function. Many initial fronts may be defined thanks to the class CSetOfPoints. Defining a new velocity is easy (at least with the explanations of this section) but it requires to code a new class.

Class design

All speed functions have to be implemented according to a given interface. This interface is defined by a base class, see includes/speedfunctions/baseclass.hxx. This base class, called CSpeedFunction is then derived in a speed-function class. To define your speed function, you have to create such a derived class.

Here is a description of members of the class CSpeedFunction (open includes/speedfunctions/baseclass.hxx):

Defining a new speed function

The point is to define a few methods among those previously described. The best way is to duplicate another speed function and to modify it. Let's try to implement the following speed function:

F_example(x, y, time, nx, ny, curvature) = x^2 + y^2

where 'x' and 'y' are the coordinates in space, 'time' is the current date (the initial time is so that 'time'=0), 'nx' and 'ny' are the two components of the normal to the front and 'curvature' is the curvature of the front.

Files

In includes/speedfunctions/, copy firemodel.hxx into newvelocity.hxx and firemodel.cxx into newvelocity.cxx. Open newvelocity.hxx and newvelocity.cxx.

Put relevant include guards: rename FILE_SPEEDFUNCTIONS_FIREMODEL_CXX into FILE_SPEEDFUNCTIONS_NEWVELOCITY_CXX and FILE_SPEEDFUNCTIONS_FIREMODEL_HXX into FILE_SPEEDFUNCTIONS_NEWVELOCITY_HXX. Replace #include "firemodel.hxx" with #include "newvelocity.hxx". Finally replace CFireModel with CNewVelocity in both files. So, you have a new valid class, but it is still the fire model...

Initialization

First, modify the constructors. You can keep only one constructor. If the default copy-constructor is not enough, you must provide a copy constructor because Multivac needs it. But you should put heavy initializations (in terms of memory or computational requirements) in the method Init. Since Multivac uses the copy constructor (and therefore duplicates the object), the method Init may be a good replacement for the constructor. Modify the destructor too. For our speed function F_example, keep only the default constructor (no argument) where dependence_position should be set to true and other dependencies to false (refer to the expression of F_example, above). Don't forget to update newvelocity.hxx.

Method Init is called by Multivac once, at the very beginning of the simulation (after the initialization of the mesh and of the initial front). Keep at least the reallocation of Values. As for our new velocity F_example, keep Init as it is. No initialization is needed there. That would be different if we had to read data (e.g. topography for fire propagation, an image, ...).

Speed rate

operator() (T x, T y, T time) is needed by the fast marching method and operator() (T x, T y, T time, T nx, T ny, T curvature) is called by the narrow band method. Define the one you need. You should define it carefully because the main computational costs could come from this part of the code.

As for F_example, we could use the fast marching method. However this method cannot be applied to lots of problems. Assuming that you want to use the narrow band method, define operator() (T x, T y, T time, T nx, T ny, T curvature). Just replace "return Model(nx, ny, time);" with "return x*x + y*y;". By the way, you can remove the method Model.

If you want to use the Lax-Friedrichs scheme, you must define GetMaxF1 and GetMaxF2. F_example doesn't depend on the normal to the front, so replace c_1 * m * sqrt(U) with 0.

Update newvelocity.hxx according to your changes and your speed function is ready.

Test with F_example

You can now edit track.cpp (main example provided with Multivac). Add #include "newvelocity.cxx" after #include "multivac.hxx". Replace "typedef CSimplifiedFireModel SpeedType;" with "typedef CNewVelocity SpeedType;". Replace "SpeedType F(U, m, c1, epsilon0, alpha);" with "SpeedType F;" (call to the default constructor).

Compile and run track. The result should be:

Remarks

Of course, it is perfectly possible to call another code from Multivac. For instance, you could call a Fortran code that computes the velocity (in operator() (T x, T y, T time, T nx, T ny, T curvature)).

Multivac uses the C++ library Seldon which provides vectors and matrices. Seldon is provided with Multivac in the directory includes/seldon/. A user's guide for Seldon is available at http://spacetown.free.fr/lib/seldon/. While implementing your speed function, you could need vectors and matrices and using Seldon would make sense.

If your speed function is intricate, you can compile it with strict options: -Wall -ansi -pedantic. This way, g++ issues warnings that may be useful. Multivac doesn't generate any warning with those options.