sim.app.hexabugs.HexaDiffuser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.hexabugs;
import sim.engine.*;
import sim.field.grid.*;
/**
Hexa Non-toroidal Diffuser
*/
public /*strictfp*/ class HexaDiffuser implements Steppable
{
private static final long serialVersionUID = 1;
DoubleGrid2D updateGrid;
DoubleGrid2D tempGrid;
double evaporationRate;
double diffusionRate;
public HexaDiffuser( final DoubleGrid2D updateGrid,
final DoubleGrid2D tempGrid,
final double evaporationRate,
final double diffusionRate )
{
this.updateGrid = updateGrid;
this.tempGrid = tempGrid;
this.evaporationRate = evaporationRate;
this.diffusionRate = diffusionRate;
}
public void step(SimState state)
{
// Let's start with the easy stuff. We'll include some local variables because it's faster.
// See heatbugs.Diffuser for more examples.
// // locals are faster than instance variables
// final DoubleGrid2D _valgrid = updateGrid;
// final DoubleGrid2D v = valgrid; // shorter
// final double[][] _valgrid_field = updateGrid.field;
// final double[][] _valgrid2_field = tempGrid.field;
// final int _gridWidth = _valgrid.getWidth();
// final int _gridHeight = _valgrid.getHeight();
// final double _evaporationRate = evaporationRate;
// final double _diffusionRate = diffusionRate;
//
// double average;
// DoubleBag temp = new DoubleBag();
// // for each x and y position
// for(int x=0;x< _gridWidth;x++)
// for(int y=0;y< _gridHeight;y++)
// {
// // Get neighbors
// _valgrid.getMooreNeighbors(x,y,1,Grid2D.TOROIDAL,true,temp,null,null);
//
// //Go through neighbors and compute average
// for( int i = 0 ; i < temp.numObjs ; i++ ) average += temp.objs[i];
// average /= (1+temp.numObjs);
//
// // load the new value into HexaBugs.this.valgrid2
// _valgrid2_field[x][y] = _evaporationRate *
// (_valgrid_field[x][y] + _diffusionRate *
// (average - _valgrid_field[x][y]));
// }
// The problem with this approach is that getMooreNeighbors is simple
// and elegant but expensive. Instead we can simply hard-code it as so:
// // locals are faster than instance variables
// final DoubleGrid2D _valgrid = updateGrid;
// final DoubleGrid2D v = valgrid; // shorter
// final double[][] _valgrid_field = updateGrid.field;
// final double[][] _valgrid2_field = tempGrid.field;
// final int _gridWidth = _valgrid.getWidth();
// final int _gridHeight = _valgrid.getHeight();
// final double _evaporationRate = evaporationRate;
// final double _diffusionRate = diffusionRate;
//
// double average;
// // for each x and y position
// for(int x=0;x< _gridWidth;x++)
// for(int y=0;y< _gridHeight;y++)
// {
// average =
// (_valgrid_field[x][y] +
// _valgrid_field[v.stx(v.ulx(x,y))][v.sty(v.uly(x,y))] +
// _valgrid_field[v.stx(v.urx(x,y))][v.sty(v.ury(x,y))] +
// _valgrid_field[v.stx(v.dlx(x,y))][v.sty(v.dly(x,y))] +
// _valgrid_field[v.stx(v.drx(x,y))][v.sty(v.dry(x,y))] +
// _valgrid_field[v.stx(v.upx(x,y))][v.sty(v.upy(x,y))] +
// _valgrid_field[v.stx(v.downx(x,y))][v.sty(v.downy(x,y))]) / 7.0;
//
// // load the new value into HexaBugs.this.valgrid2
// _valgrid2_field[x][y] = _evaporationRate *
// (_valgrid_field[x][y] + _diffusionRate *
// (average - _valgrid_field[x][y]));
// }
// Now we're getting somewhere speed-wise. But we can also eliminate the toroidal and hexagonal
// cover functions with some work. Boy, it's a chore though. We include it here for fun, but
// don't blame us if it's totally unreadable!
// stolen from HeatBugs and modified for our own purposes
// locals are faster than instance variables
// locals are faster than instance variables
final DoubleGrid2D _valgrid = updateGrid;
final double[][] _valgrid_field = updateGrid.field;
final double[][] _valgrid2_field = tempGrid.field;
final int _gridWidth = _valgrid.getWidth();
final int _gridHeight = _valgrid.getHeight();
final double _evaporationRate = evaporationRate;
final double _diffusionRate = diffusionRate;
double average;
double[] _past = _valgrid_field[_valgrid.stx(-1)];
double[] _current = _valgrid_field[0];
double[] _next;
double[] _put;
int yminus1;
int yplus1;
// for each x and y position
for(int x=0;x< _gridWidth;x++)
{
int xplus1 = x+1;
if( xplus1 == _gridWidth )
xplus1 = 0;
_next = _valgrid_field[xplus1];
_put = _valgrid2_field[x];
boolean xmodulo2equals0 = x%2==0;
yminus1 = _gridHeight-1; // initialized
for(int y=0;y< _gridHeight;y++)
{
// for each neighbor of that position
// go across top
yplus1 = y+1;
if( yplus1 == _gridHeight )
yplus1 = 0;
if( xmodulo2equals0 )
{
average = (
_current[y] + // CURRENT
_past[yminus1] + //UL
_next[yminus1] + // UR
_past[y] + //DL
_next[y] + // DR
_current[yminus1] + // UP
_current[yplus1] // DOWN
) / 7.0;
}
else
{
average = (
_current[y] + // CURRENT
_past[y] + //UL
_next[y] + // UR
_past[yplus1] + //DL
_next[yplus1] + // DR
_current[yminus1] + // UP
_current[yplus1] // DOWN
) / 7.0;
}
// load the new value into HeatBugs.this.valgrid2
_put[y] = _evaporationRate *
(_current[y] + _diffusionRate *
(average - _current[y]));
// set y-1 to what y was "last time around"
yminus1 = y;
}
// swap elements
_past = _current;
_current = _next;
}
updateGrid.setTo(tempGrid);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy