jabble
Class Evolver

java.lang.Object
  extended by jabble.Evolver
Direct Known Subclasses:
IteratedCrankNicholson, LaxWendroff, Multigrid, Multigrid.VCycle, SingleLoopEvolver

public abstract class Evolver
extends java.lang.Object

An Evolver solves a partial differential equation by calculating a set of Fields at a given time step by using the data from Fields at previous time steps. The flow is as follow:

While one can create an Evolver for a particular equation by extending this class and implementing calculatesNewFields, that is (hopefully) rarely needed. One can typically extend the template corresponding to the method used, such as Jacobi, SingleLoopEvolver, IteratedCrankNicholson, FullMultigrid... See the list of the classes extending Evolver on the top of this page for a complete and up-to-date list. In the case one needs to implement a new method, instead, one would extend directly from this class. In that case, please consider contributing the new method to Jabble: we are willing to do the generalization provided we have a working example for a specific case.

Field initialization

All Evolvers (including subclasses such as Jacobi, IteratedCrankNicholson, ...) will have their fields automatically initialized. This means that you simply need to declare a Field in your class, and Jabble will "inject" the correct value for you. For all evolvers, the following conventions apply:

By looking at how many Field at a given time step are declared, Jabble is going to understand how many previous Slices the Evolver needs. This information is used by Jabble for efficient memory management.

Consider the following example:

 public class DiffusionCartesianJacobi extends Jacobi {
  
      private Field previousPhi;
      private Field phi;
      private Field rho;
      private Field dt;
   
      protected void calculateNewFields(Point point) {
          double dtValue = dt.at(point);
          double previousPhiValue = previousPhi.at(point);
          double phiValue = previousPhiValue;
      
          phiValue += dtValue * laplacianBulk(previousPhi);
          phiValue -= dtValue * rho.at(point);
          phi.setAt(point, phiValue);
      }
   
 }

Here phi, rho and dt are initialized to the correct Field object representing phi, rho and dt at the current time step; previousPhi is initialized to phi at t - dt. Jabble will also deduce that the DiffusionCartesianJacobi Evolver will need 2 Slices (current and previous). This means that at any time there must be 2 Slices allocated, and that 1 Slice will need to be initialized with initial conditions

Implementing an Evolver

In case you need to create an Evolver that doesn't fit any method already bundled with Jabble, you need to extend directly the Evolver class. The entry point for the new Evolver is calculateNewFields(): the framework will call that method any time it will need for the evolver to go through the calculation. The Evolver essentially needs these pieces from the framework:

What an Evolver will typically do is perform a few loops over the Grid, and calculate the value of some Field in each of them. Once the calculation is finished, the new Evolver should simply return from calculateNewFields(): the framework will automatically retrieve the affected Fields, and reset the Evolver for another iteration by switch the Fields around.


Field Summary
protected  java.util.Map<java.lang.String,java.lang.reflect.Field> constantsMap
           
protected  Field[] dDirs
          The differentials fields in coordinate order.
protected  java.util.Map<java.lang.String,java.lang.reflect.Field> fieldArrayMap
          A map to all the Field[] java variables defined in the Evolver, generated through introspection.
protected  java.util.Map<java.lang.String,java.lang.reflect.Field> fieldMap
          A map to all the Field java variables defined in the Evolver, generated through introspection.
protected  Grid grid
          The grid on which the evolver will need to compute, as extracted from the slices.
protected  Trigger stopTrigger
          The trigger used by the evolver to stop the evolution.
 
Constructor Summary
Evolver()
          Creates a new evolver and initializes the field and fieldArray map.
 
Method Summary
protected abstract  void calculateNewFields()
          Calculates the fields for the current iteration.
 void evolve(java.util.List<Slice> slices)
          Evolves the data in the list of slices of one time step.
 int evolve(java.util.List<Slice> slices, int nIterations)
          Evolves the data in the list of slices for nIterations time steps.
 int evolve(java.util.List<Slice> slices, int maxIterations, Trigger stopTrigger)
          Evolves the data in the list of slices for maxIterations time steps, or until the stopTrigger is verified.
 int getNPreviousSlicesNeeded()
          Returns the number of slices needed for the previous time steps.
protected  void initializeFieldArray(java.lang.String arrayVariableName)
          Initializes a variable with an array of Fields on the current Grid.
protected  void initializeFieldArray(java.lang.String arrayVariableName, int nComponents)
          Initializes a variable with an array of Fields on the current Grid.
protected  boolean skipBoundaryPoint(Point point)
          Determine whether the point is on a boundary that needs to be skipped.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

stopTrigger

protected Trigger stopTrigger
The trigger used by the evolver to stop the evolution.


grid

protected Grid grid
The grid on which the evolver will need to compute, as extracted from the slices.


dDirs

protected Field[] dDirs
The differentials fields in coordinate order.


fieldMap

protected java.util.Map<java.lang.String,java.lang.reflect.Field> fieldMap
A map to all the Field java variables defined in the Evolver, generated through introspection.


fieldArrayMap

protected java.util.Map<java.lang.String,java.lang.reflect.Field> fieldArrayMap
A map to all the Field[] java variables defined in the Evolver, generated through introspection.


constantsMap

protected java.util.Map<java.lang.String,java.lang.reflect.Field> constantsMap
Constructor Detail

Evolver

public Evolver()
Creates a new evolver and initializes the field and fieldArray map.

Method Detail

initializeFieldArray

protected void initializeFieldArray(java.lang.String arrayVariableName,
                                    int nComponents)
Initializes a variable with an array of Fields on the current Grid. This is a temporary method to use until the framework implements VectorFields.

Parameters:
arrayVariableName - The name of the Java variable of this evolver that needs to be initialized.
nComponents - number of components to put in the array.

initializeFieldArray

protected void initializeFieldArray(java.lang.String arrayVariableName)
Initializes a variable with an array of Fields on the current Grid. This is a temporary method to use until the framework implements VectorFields. The number of the components in the array will match the dimension of the Grid.

Parameters:
arrayVariableName - The name of the Java variable of this evolver that needs to be initialized.

getNPreviousSlicesNeeded

public int getNPreviousSlicesNeeded()
Returns the number of slices needed for the previous time steps. For example, if it returns 2 it means that 2 slices in the past are needed by this evolver (say because it needs to calculate a second derivative in time). The evolver will of course need one slice more, that will correspond to the slice that will be used for to store the value of the next iteration.

The value is calculated by looking at the fields declared within the evolver. So if a subclass will declare a previous2Phi, this method will return 2, provided no other older fields where declared.

Returns:
the number of past slices needed

calculateNewFields

protected abstract void calculateNewFields()
Calculates the fields for the current iteration.


evolve

public void evolve(java.util.List<Slice> slices)
Evolves the data in the list of slices of one time step.

An EllipticSolver will work by continuing to refine the solution at each iteration over the Grid. At each iteration, the solver will determine what was the best improvement (that is F[n](P) - F[n-1](P)) and if it's less than the truncation error it will return. The solver will not go past the maxIterations limit.

The solver will return the solution by modifying the data contained in the Slice, or by removing and adding Fields accordingly.

Parameters:
slices - The slices containing the data to work on; first slice is the most recent in time of iterations performed by the solver.

evolve

public int evolve(java.util.List<Slice> slices,
                  int nIterations)
Evolves the data in the list of slices for nIterations time steps.

Parameters:
slices - The slices containing the data to work on; first slice is the most recent in time
nIterations - A positive integer indicating the maximum number of iterations for the evolution
Returns:
The number of iterations performed by the evolver (will be nIterations).

evolve

public int evolve(java.util.List<Slice> slices,
                  int maxIterations,
                  Trigger stopTrigger)
Evolves the data in the list of slices for maxIterations time steps, or until the stopTrigger is verified.

Parameters:
slices - The slices containing the data to work on; first slice is the most recent in time
maxIterations - A positive integer indicating the maximum number of iterations for the evolution
stopTrigger - The exit condition that, if verified, will stop the evolution
Returns:
A positive integer from 0 to maxIterations representing the number of iterations performed by the solver.

skipBoundaryPoint

protected boolean skipBoundaryPoint(Point point)
Determine whether the point is on a boundary that needs to be skipped.

Parameters:
point - a point on the grid
Returns:
true if the point is on a boundary to be skipped.