QHG Tutorial 03 - Moving¶
In this chapter we describe a class which, in addition to aging and dying also lets agents move randomly between cells.
To get the agents moving we use the action class RandomMove.
Population code:
Action code:
The Header File¶
This class must additionaly include the header files for the RandomMove
action.
#ifndef __TUT_MOVEPOP_H__
#define __TUT_MOVEPOP_H__
#include "OldAgeDeath.h"
#include "GetOld.h"
#include "RandomMove.h"
#include "SPopulation.h"
// our agents need to have an age
struct tut_MoveAgent : Agent {
float m_fAge;
};
class tut_MovePop : public SPopulation<tut_MoveAgent> {
public:
tut_MovePop(SCellGrid *pCG, PopFinder *pPopFinder, int iLayerSize, IDGen **apIDG, uint32_t *aulState, uint *aiSeeds);
virtual ~tut_MovePop();
int addPopSpecificAgentData(int iAgentIndex, char **ppData);
void addPopSpecificAgentDataTypeQDF(hid_t *hAgentDataType);
protected:
GetOld<tut_MoveAgent> *m_pGO;
OldAgeDeath<tut_MoveAgent> *m_pOAD;
RandomMove<tut_MoveAgent> *m_pRM;
};
#endif
For random moving we don’t need to add members to the agent structure - the agents` positions are already part of the basic agent structure. So we use the same agent structure as in the previous chapter.
The public methods addPopSpecificAgentData
and addPopSpecificAgentDataTypeQDF
remain unchanged since they only deal with the addition agent member m_fAge
.
Finally, we need a pointer to an instance of the RandomMove
-action.
Code: tut_MovePop.h
The Implementation¶
The include files reflect the addition of the move action:
The constructor must create instances of all the actions and add them to the priority list.
//----------------------------------------------------------------------------
// constructor
//
tut_MovePop::tut_MovePop(SCellGrid *pCG, PopFinder *pPopFinder, int iLayerSize, IDGen **apIDG, uint32_t *aulState, uint *aiSeeds)
: SPopulation<tut_MoveAgent>(pCG, pPopFinder, iLayerSize, apIDG, aulState, aiSeeds) {
m_pGO = new GetOld<tut_MoveAgent>(this, m_pCG, "");
m_pOAD = new OldAgeDeath<tut_MoveAgent>(this, m_pCG, "", m_apWELL);
m_pRM = new RandomMove<tut_MoveAgent>(this, m_pCG, "", m_apWELL);
m_prio.addAction(m_pGO);
m_prio.addAction(m_pOAD);
m_prio.addAction(m_pRM);
}
In the destructor the instances created by the constructor are deletetd.
//----------------------------------------------------------------------------
// destructor
//
tut_MovePop::~tut_MovePop() {
if (m_pGO != NULL) {
delete m_pGO;
}
if (m_pOAD != NULL) {
delete m_pOAD;
}
if (m_pRM != NULL) {
delete m_pRM;
}
}
Finally, there are the input auxiliary methods dealing with the age member. They are the same as the ones in the previous chapter.
//----------------------------------------------------------------------------
// addPopSpecificAgentData
// read additional data from pop file (the mat index is volatile, so we don't try to read it)
//
int tut_MovePop::addPopSpecificAgentData(int iAgentIndex, char **ppData) {
int iResult = 0;
if (iResult == 0) {
iResult = addAgentDataSingle(ppData, &m_aAgents[iAgentIndex].m_fAge);
}
return iResult;
}
//----------------------------------------------------------------------------
// addPopSpecificAgentDataTypeQDF
// extend the agent data type to include additional data in the output
//
void tut_MovePop::addPopSpecificAgentDataTypeQDF(hid_t *hAgentDataType) {
tut_MoveAgent ma;
H5Tinsert(*hAgentDataType, "Age", qoffsetof(ma, m_fAge), H5T_NATIVE_FLOAT);
}
Code: tut_MovePop.cpp
XML and DAT¶
Apart from the entries for OldAgeDeath
there is also an entry for RandomMove
in the xml file.
The action GetOld
requires no parameters.
<class name="tut_MovePop" species_name="sapiens" species_id="104">
<module name="OldAgeDeath">
<param name="OAD_max_age" value="60.0"/>
<param name="OAD_uncertainty" value="0.1"/>
</module>
<module name="RandomMove">
<param name="RandomMove_prob" value="0.1"/>
</module>
<priorities>
<prio name="GetOld" value="1"/>
<prio name="OldAgeDeath" value="20"/>
<prio name="RandomMove" value="3"/>
</priorities>
</class>
The action RandomMove
needs a parameter for its move probability. For details, see the description of RandomMove.
The priority values are chosen such that the age is changed fist, then agents may die of old age, and the survivors may move.The dat file tut_Move.dat
defines postions and attributes for 20 agents, the last attribute pertainng to the new member m_fAge
.
The dat file tut_Move.dat
is identical to the dat file of the previous chapter.
Apart from the postion and the basic parameters we have to add a parameter for the age.
#Longitude;Latitude;LifeState;AgentID;BirthTime;Gender;Age
8;47;1; 1;-10.0;0;10.0
8;47;1; 2;-10.0;0;10.0
8;47;1; 3;-10.0;0;10.0
...
8;47;1;20;-10.0;0;10.0
In this case, too, all 20 agents are placed at the same location, and all agents are female (Gender: 0=female, 1=male).
Feel free to modify the values in the xml file and see how this changes the outcome.
Grid¶
For this example we use a subdivided icosahedron
Compiling and Running¶
We assume that you have created the tutorial directories with the script build_tut_dirs.py. This copies all relevant files to the tutorial subdirectories.
First lets create alternative population and action directories with the script build_alt_modpop.py:
${QHG4_DIR}/useful_stuff/build_alt_modpop.py tut_03 tut_MovePop
This builds alternative population directories tut_03_pop
and tut_03_mod
.
To compile, cd to the QHG4 root directory and type:
SHORT=tut_03 make clean QHGMain
This is the simplest way to compile QHG (for more information see Compiling QHG)
Now cd to the tutorial subdirectory “tutorial_03’ and start QHGMain
${QHG4_DIR}/app/QHGMain --read-config=tutorial_03.cfg > tutorial_03.out
This tells QHGMain to read the parameters from the file tutorial_03.cfg
and write all output to the file tutorial_03.out
(this output contains more information than the logfile)
The config file tutorial_03.cfg
was created when the tutorial directories were created with build_tut_dirs.py
.
--data-dirs=${QHG4_DIR}/tutorial_data/grids/
--events='write|grid+geo+pop:sapiens@20000'
--grid=ico32s.qdf
--log-file=tutorial_03.log
--num-iters=200
--output-dir=output/tutorial_03
--output-prefix=tut
--pops='tut_Move.xml:tut_Move.dat'
--shuffle=92244
--start-time=0
data-dirs
A list of directories to search for data
events
A list of events (see Events). Here a single event is defined: write output at step 20000 (or at the end of the simulation run).
grid
Path to the grid on which to run the simulation.
log-file
Log file for ‘high level’ messages.
num-iters
Number of iterations for the simulation.
output-dir
Output directory for qdf files.
output-prefix
A prefix prepended to the names of all output files
pops
The files for population attributes (
tut_Move.xml
) and agent attributes (tut_Move.dat
). These files were created bybuild_tut_dirs.py
.shuffle
A kiind of seed for the random nummber generators. Same
shuffle
values result in idfentical simulations.start-time
The ‘real’ time corresponding to step 0.
Grid¶
For this example we use a subdivided icosahedron
Compiling and Running¶
We assume that you have created the tutorial directories with the script build_tut_dirs.py. This copies all relevant files to the tutorial subdirectories.
First lets create alternative population and action directories with the script build_alt_modpop.py:
${QHG4_DIR}/useful_stuff/build_alt_modpop.py tut_03 tut_MovePop
This builds alternative population directories tut_03_pop
and tut_03_mod
.
To compile, cd to the QHG4 root directory and type:
SHORT=tut_03 make clean QHGMain
This is the simplest way to compile QHG (for more information see Compiling QHG)
Now cd to the tutorial subdirectory “tutorial_03’ and start QHGMain
${QHG4_DIR}/app/QHGMain --read-config=tutorial_03.cfg > tutorial_03.out
This tells QHGMain to read the parameters from the file tutorial_03.cfg
and write all output to the file tutorial_03.out
(this output contains more information than the logfile)
The config file tutorial_03.cfg
was created when the tutorial directories were created with build_tut_dirs.py
.
--data-dirs=/home/jody/progs/multi_spc_QHG3_std/useful_stuff/gridpreparation/
--events='write|grid+geo+pop:sapiens@20000'
--grid=ico32s.qdf
--log-file=tutorial_03.log
--num-iters=200
--output-dir=output/tutorial_03
--output-prefix=nnn
--pops='tut_Move.xml:tut_Move.dat'
--shuffle=92244
--start-time=-200
data-dirs
A list of directories to search for data.
events
A list of events (see Events). Here a single event is defined: write output at step 20000 (or at the end of the simulation run).
grid
Path to the grid on which to run the simulation.
log-file
Log file for ‘high level’ messages.
num-iters
Number of iterations for the simulation.
output-dir
Output directory for qdf files.
output-prefix
A prefix prepended to the names of all output files
pops
The files for population attributes (
tut_Move.xml
) and agent attributes (tut_Move.dat
). These files were created bybuild_tut_dirs.py
.shuffle
A kind of seed for the random number generators. Same
shuffle
values result in idfentical simulations.start-time
The ‘real’ time corresponding to step 0.
The Output File¶
The output files, in this case tutorial_03.out
, always have the same structure.
First there are messages concerning the start of the program and intialisation.
If the simulation does not run, there’s a chance that you find th readoon why here.
The second part is a list of every step describing the numbers of births, deaths and moves, as well as the time the step took to execute.
At the end there is a short summary of the state at the end of the program: number of iterations, total time of execution, nuber of surviving agents. This is follwed by the contents of the log file.
If you look at the output for the steps, you see that there are still no births, but there are moves an deaths:
After step 45 (0.000115 s): total 20 agents
sapiens 0 births r
sapiens 0 deaths r
sapiens 3 moves
After step 46 (0.000116 s): total 20 agents
sapiens 0 births r
sapiens 5 deaths r
sapiens 4 moves
After step 47 (0.000118 s): total 15 agents
sapiens 0 births r
sapiens 2 deaths r
sapiens 5 deaths p
sapiens 1 moves
And at the beginning of the last part:
-----
Stopped Simulation
Number of threads: 8
Number of iterations: 54
Used time: 0.009391 (00:00:00)
Number of agents after last step
sapiens: 0
total: 0
+++success+++
The summary at the end:
*** total number of births 0
*** total number of deaths 20
*** total number of moves 82