The first step to using a projection is creating it. In this case, we will be using a 'SharedNetwork' projection- that is, a network that 'knows' that it can have connections that are shared across process boundaries.

The modifications to the Model.h file are simple: add the required include-

/* Demo_02_Model.h */

#ifndef DEMO_02_MODEL
#define DEMO_02_MODEL

#include 
#include "repast_hpc/Schedule.h"
#include "repast_hpc/Properties.h"
#include "repast_hpc/SharedContext.h"
#include "repast_hpc/AgentRequest.h"
#include "repast_hpc/TDataSource.h"
#include "repast_hpc/SVDataSet.h"
#include "repast_hpc/SharedNetwork.h"

#include "Demo_02_Agent.h"

And create two things: an instance of an 'edge content manager' (that is responsible for packaging edge content and sharing between processes) and a pointer to the network as a private instance variable of the model class:

class RepastHPCDemoModel{
	int stopAt;
	int countOfAgents;
	repast::Properties* props;
	repast::SharedContext<RepastHPCDemoAgent> context;
	
	RepastHPCDemoAgentPackageProvider* provider;
	RepastHPCDemoAgentPackageReceiver* receiver;

        repast::RepastEdgeContentManager<RepastHPCDemoAgent> edgeContentManager;

	repast::SVDataSet* agentValues;
	repast::SharedNetwork<RepastHPCDemoAgent, repast::RepastEdge<RepastHPCDemoAgent>, repast::RepastEdgeContent<RepastHPCDemoAgent>, 
              repast::RepastEdgeContentManager<RepastHPCDemoAgent> >* agentNetwork;
	
public:
	RepastHPCDemoModel(std::string propsFile, int argc, char** argv, boost::mpi::communicator* comm);
	~RepastHPCDemoModel();
	void init();
	void requestAgents();
	void cancelAgentRequests();
	void removeLocalAgents();
	void moveAgents();
	void doSomething();
	void initSchedule(repast::ScheduleRunner& runner);
	void recordResults();
};

Note that in order to create the network we must specify in the template parameters:

In this case the nodes will be our agents; the edges will be a default edge (provided by repast), which also must be informed that it will be connecting elements of a specific type (hence it is, itself, templated). 'Edge Content' refers to the data that is contained in an edge- generally, the source and target vertices plus whatever additional data the edge might contain (e.g. a 'weight' or other value or set of values). In this case the edge content will be the default, built-in Repast Edge Content (which contains the two vertices and a 'weight' value), and it will be managed by the default, built-in Repast Edge Content Manager.

To create the network now requires only two lines in the model constructor, one to create the network instance and one to add it to the context:

RepastHPCDemoModel::RepastHPCDemoModel(std::string propsFile, int argc, char** argv, boost::mpi::communicator* comm){
	props = new repast::Properties(propsFile, argc, argv, comm);
	stopAt = repast::strToInt(props->getProperty("stop.at"));
	countOfAgents = repast::strToInt(props->getProperty("count.of.agents"));
	initializeRandom(*props, comm);
	if(repast::RepastProcess::instance()->rank() == 0) props->writeToSVFile("./output/record.csv");
	provider = new RepastHPCDemoAgentPackageProvider(&context);
	receiver = new RepastHPCDemoAgentPackageReceiver(&context);
	
        agentNetwork = new repast::SharedNetwork<RepastHPCDemoAgent, repast::RepastEdge<RepastHPCDemoAgent>,
              repast::RepastEdgeContent<RepastHPCDemoAgent>, repast::RepastEdgeContentManager<RepastHPCDemoAgent> >("agentNetwork", false, &edgeContentManager);
	context.addProjection(agentNetwork);
	
	// Data collection
	// Create the data set builder
	std::string fileOutputName("./output/agent_total_data.csv");
	repast::SVDataSetBuilder builder(fileOutputName.c_str(), ",", repast::RepastProcess::instance()->getScheduleRunner().schedule());
	
	// Create the individual data sets to be added to the builder
	DataSource_AgentTotals* agentTotals_DataSource = new DataSource_AgentTotals(&context);
	builder.addDataSource(createSVDataSource("Total", agentTotals_DataSource, std::plus<int>()));

	DataSource_AgentCTotals* agentCTotals_DataSource = new DataSource_AgentCTotals(&context);
	builder.addDataSource(createSVDataSource("C", agentCTotals_DataSource, std::plus<int>()));

	// Use the builder to create the data set
	agentValues = builder.createDataSet();
	
}

The arguments that are used in the constructor for the network are, first, the name that can be used to refer to the network (remember, a context can have several projections in it, so each one is assigned a name), and second a variable that indicates whether the network will be directed (true) or undirected (false). 'Undirected' networks mean that a connection between two agents is reciprocal: if A is connected to B, then B is connected to A; directed networks allow connections that go only in one direction, such as from A to B but not B to A. The third argument is the content manager instance.

There is one final but very important step. You must add the following line to the of the DemoModel.cpp file, after the includes but before the rest of the code:

#include "repast_hpc/initialize_random.h"
#include "repast_hpc/SVDataSetBuilder.h"

#include "Demo_02_Model.h"

BOOST_CLASS_EXPORT_GUID(repast::SpecializedProjectionInfoPacket<repast::RepastEdgeContent<RepastHPCDemoAgent> >, "SpecializedProjectionInfoPacket_EDGE");

RepastHPCDemoAgentPackageProvider::RepastHPCDemoAgentPackageProvider(repast::SharedContext* agentPtr): agents(agentPtr){ }

The reason for this is somewhat technical: Repast HPC uses the Boost library, and the Boost library provides some very convenient functions relating to sending information back and forth across processes. This line tells Boost that there will be a class being sent back and forth that carries a specific kind of edge content, in this case the default RepastEdge with RepastHPCDemoAgents as nodes. With this, Boost performs some behind-the-scenes work to make sure that it knows how to package and send this content without too much other preparation needed. However, if you omit this line, the result will be Boost trying to send information for which it does not recognize the structure, and a segmentation fault will occur.