|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectjabble.Evolver
public abstract class Evolver
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:
Evolver is instructed by Jabble to evolve a List
of Slices, that represent the value of the fields at the previous steps
in time.Evolver class will perform a series of preparation steps,
among which the initialization of the Field variablesEvolver will call calculateNewFields(), which
perform the actual computationEvolver will iterate until either a stop condition is reached,
or it performs the number of iteration it was instructed to doWhile 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.
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:
Field phi;
if phi is the name of a Field defined in the
equation, then the variable will be populated with the Field at
the current time step (i.e. the one that needs to be calculated).Field temp;
if temp is not the name of a Field defined
in the equation, the variable is populated with a Field defined
on the same Grid. No assumption should be made on the data of the
temperary field: it won't be passed through iterations and it won't be initialized
to 0. The data should be only used withing a single time step calculation.Field previousPhi;
if phi is the name of a Field defined in the
equation, then the variable will be populated with the Field at
the previous time step. You can also request Fields at any previous
time steps: previous2Phi will give you phi at t
- 2dt, previous3Phi at t - 3dt and so
on.Field[] velocity;velocityX,
velocityY, ... Fields are defined in the equation,
the array is initialized with the different component in the order of the coordinates.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
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:
Grid: it will need to know on which grid to make the calculation
to be able to loop over it. This is passed through the grid variable.Fields: it needs to the references to the Field objects
on which it should be performing the calculation. These are passed through the
field initialization mechanism discussed beforeWhat 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 |
|---|
protected Trigger stopTrigger
protected Grid grid
protected Field[] dDirs
protected java.util.Map<java.lang.String,java.lang.reflect.Field> fieldMap
protected java.util.Map<java.lang.String,java.lang.reflect.Field> fieldArrayMap
protected java.util.Map<java.lang.String,java.lang.reflect.Field> constantsMap
| Constructor Detail |
|---|
public Evolver()
| Method Detail |
|---|
protected void initializeFieldArray(java.lang.String arrayVariableName,
int nComponents)
arrayVariableName - The name of the Java variable of this evolver that needs to be initialized.nComponents - number of components to put in the array.protected void initializeFieldArray(java.lang.String arrayVariableName)
arrayVariableName - The name of the Java variable of this evolver that needs to be initialized.public int getNPreviousSlicesNeeded()
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.
protected abstract void calculateNewFields()
public void evolve(java.util.List<Slice> slices)
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.
slices - The slices containing the data to work on; first slice is the most recent in time
of iterations performed by the solver.
public int evolve(java.util.List<Slice> slices,
int nIterations)
slices - The slices containing the data to work on; first slice is the most recent in timenIterations - A positive integer indicating the maximum number of iterations
for the evolution
public int evolve(java.util.List<Slice> slices,
int maxIterations,
Trigger stopTrigger)
slices - The slices containing the data to work on; first slice is the most recent in timemaxIterations - A positive integer indicating the maximum number of iterations
for the evolutionstopTrigger - The exit condition that, if verified, will stop the evolution
protected boolean skipBoundaryPoint(Point point)
point - a point on the grid
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||