Skip to content

Commit

Permalink
Symu.SysDyn intergation in Symu
Browse files Browse the repository at this point in the history
  • Loading branch information
lmorisse committed Oct 12, 2020
1 parent 4a165d4 commit 51b6e97
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 12 deletions.
30 changes: 30 additions & 0 deletions SourceCode/Symu/Classes/Agents/IAgent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#region Licence

// Description: SymuBiz - Symu
// Website: https://symu.org
// Copyright: (c) 2020 laurent morisseau
// License : the program is distributed under the terms of the GNU General Public License

#endregion

namespace Symu.Classes.Agents
{
/// <summary>
/// The Agent interface
/// </summary>
public interface IAgent
{
//todo => c#8 IAgentId AgentId;
/// <summary>
/// Clone an agent
/// </summary>
/// <returns></returns>
IAgent Clone();
/// <summary>
/// Set an agent's property value by its name
/// </summary>
/// <param name="propertyName"></param>
/// <param name="value"></param>
void SetProperty(string propertyName, float value);
}
}
13 changes: 4 additions & 9 deletions SourceCode/Symu/Classes/Agents/ReactiveAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@

namespace Symu.Classes.Agents
{
/// <summary>
/// The Agent interface
/// </summary>
public interface IAgent
{
//todo => c#8 IAgentId AgentId;
IAgent Clone();
}

/// <summary>
/// The default implementation of IAgent
/// You can define your own class agent by inheritance or implementing directly IAgent
Expand Down Expand Up @@ -334,5 +325,9 @@ public void Unsubscribe(IAgentId agentId, byte subject)
}

#endregion

public virtual void SetProperty(string propertyName, float value)
{
}
}
}
31 changes: 31 additions & 0 deletions SourceCode/Symu/Environment/NodeAgent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#region Licence

// Description: SymuBiz - Symu
// Website: https://symu.org
// Copyright: (c) 2020 laurent morisseau
// License : the program is distributed under the terms of the GNU General Public License

#endregion

using Symu.Common.Interfaces;
using Symu.SysDyn.Model;

namespace Symu.Environment
{
/// <summary>
/// NodeAgent is used with SysDynModel
/// It make the link between a Symu.SysDyn.Node and a Symu.Agent and its property used in SysDyn
/// </summary>
public readonly struct NodeAgent
{
public NodeAgent(string nodeId, IAgentId agentId, string property)
{
NodeId = nodeId;
AgentId = agentId;
Property = property;
}
public string NodeId { get; }
public IAgentId AgentId { get; }
public string Property { get; }
}
}
14 changes: 13 additions & 1 deletion SourceCode/Symu/Environment/SymuEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Symu.OrgMod.Entities;
using Symu.Repository;
using Symu.Results;
using Symu.SysDyn;
using EventEntity = Symu.Repository.Entities.EventEntity;

#endregion
Expand All @@ -35,13 +36,17 @@ namespace Symu.Environment
/// </summary>
public class SymuEnvironment
{
//TODO refactor MainOrganizationReference, StateMachineReference, ... in a readonly struct
protected MainOrganization MainOrganizationReference {get; set; }

public SymuEnvironment()
{
IterationResult = new IterationResult(this);
}

/// <summary>
/// The MainOrganization that encapsulates the metaNetwork, the organizational models and so on.
/// </summary>
public MainOrganization MainOrganization { get; protected set; }

/// <summary>
Expand All @@ -50,8 +55,13 @@ public SymuEnvironment()
/// </summary>
public WhitePages WhitePages { get; } = new WhitePages();

/// <summary>
/// The iteration result manage and store all results of an iteration
/// </summary>
public IterationResult IterationResult { get; set; }

public SysDynModel SysDynModel { get; set; }

/// <summary>
/// Use to slow down or speed up the simulation
/// Delay is in milliseconds
Expand Down Expand Up @@ -388,7 +398,9 @@ private void SetInteractionSphere(bool initialization)
/// </summary>
public void PreStep()
{
WhitePages.AllAgents().ToList().ForEach(a => a.PreStep());
var agents = WhitePages.AllAgents().ToList();
SysDynModel.Process(agents);
agents.ForEach(a => a.PreStep());
}

/// <summary>
Expand Down
65 changes: 65 additions & 0 deletions SourceCode/Symu/Environment/SysDynModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#region Licence

// Description: SymuBiz - Symu
// Website: https://symu.org
// Copyright: (c) 2020 laurent morisseau
// License : the program is distributed under the terms of the GNU General Public License

#endregion

#region using directives

using System;
using System.Collections.Generic;
using System.Xml.XPath;
using NCalc2.Grammar;
using Symu.Classes.Agents;
using Symu.Common.Classes;
using Symu.Common.Interfaces;
using Symu.SysDyn;
using Symu.SysDyn.Model;

#endregion

namespace Symu.Environment
{
/// <summary>
/// SysDynModel encapsulate Symu.SysDyn and make the link between Symu.SysDyn.Nodes and Symu.Agents and properties
/// </summary>
public class SysDynModel
{
private readonly StateMachine _stateMachine;
private readonly List<NodeAgent> _nodeAgentList = new List<NodeAgent>();

public SysDynModel(string xmlFile)
{
_stateMachine = new StateMachine(xmlFile);
}

public void Process(List<ReactiveAgent> agents)
{
if (agents == null)
{
throw new ArgumentNullException(nameof(agents));
}

_stateMachine.Process();

foreach (var nodeAgent in _nodeAgentList)
{
var agent = agents.Find(x => x.AgentId.Equals(nodeAgent.AgentId));
agent.SetProperty(nodeAgent.Property, _stateMachine.GetVariable(nodeAgent.NodeId));
}
}

public void AddNodeAgent(string nodeId, IAgentId agentId, string property)
{
_nodeAgentList.Add(new NodeAgent(nodeId, agentId, property));
}

public float GetVariable(string nodeId)
{
return _stateMachine.GetVariable(nodeId);
}
}
}
3 changes: 3 additions & 0 deletions SourceCode/Symu/Results/IterationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@

namespace Symu.Results
{
/// <summary>
/// The iteration result manage and store all results of an iteration
/// </summary>
public class IterationResult
{
public IterationResult(SymuEnvironment environment)
Expand Down
1 change: 1 addition & 0 deletions SourceCode/Symu/Symu.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<ProjectReference Include="..\..\..\..\Symu.Common\Github\SourceCode\SymuCommon\SymuCommon.csproj" />
<ProjectReference Include="..\..\..\..\Symu.DNA\Github\SourceCode\SymuDNA\SymuDNA.csproj" />
<ProjectReference Include="..\..\..\..\Symu.OrgMod\Github\SourceCode\SymuOrgMod\SymuOrgMod.csproj" />
<ProjectReference Include="..\..\..\..\Symu.SysDyn\Github\SourceCode\SymuSysDyn\SymuSysDyn.csproj" />
</ItemGroup>

</Project>
36 changes: 36 additions & 0 deletions SourceCode/SymuTests/Environment/SysDynModelTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Symu.Environment;
using SymuTests.Helpers;

namespace SymuTests.Environment
{
[TestClass()]
public class SysDynModelTests : BaseTestClass
{
private const string XmlFile = "../../../Resources/sysdyn.xmile";
private const string NodeId = "Employees";
private TestSysDynAgent _agent;

[TestInitialize]
public void Initialize()
{
_agent = new TestSysDynAgent(Environment.WhitePages.NextAgentId(TestReactiveAgent.ClassId), Environment);
Environment.SysDynModel = new SysDynModel(XmlFile);
Environment.SysDynModel.AddNodeAgent(NodeId, _agent.AgentId, "Property1");
}

[TestMethod()]
public void SysDynModelTest()
{
Assert.AreEqual(10, Environment.SysDynModel.GetVariable(NodeId));
}

[TestMethod()]
public void ProcessTest()
{
Environment.SysDynModel.Process(Environment.WhitePages.AllAgents().ToList());
Assert.AreEqual(Environment.SysDynModel.GetVariable(NodeId), _agent.Property1);
}
}
}
4 changes: 2 additions & 2 deletions SourceCode/SymuTests/Helpers/TestReactiveAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@

namespace SymuTests.Helpers
{
internal sealed class TestReactiveAgent : ReactiveAgent
internal class TestReactiveAgent : ReactiveAgent
{
public static byte Class = SymuYellowPages.Actor;

/// <summary>
/// Constructor of the agent
/// </summary>
/// <remarks>Call the Initialize method after the constructor, or call the factory method</remarks>
private TestReactiveAgent(IAgentId id, SymuEnvironment environment) : base(id, environment)
protected TestReactiveAgent(IAgentId id, SymuEnvironment environment) : base(id, environment)
{
}

Expand Down
41 changes: 41 additions & 0 deletions SourceCode/SymuTests/Helpers/TestSysDynAgent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#region Licence

// Description: SymuBiz - SymuTests
// Website: https://symu.org
// Copyright: (c) 2020 laurent morisseau
// License : the program is distributed under the terms of the GNU General Public License

#endregion

#region using directives

using System;
using Symu.Classes.Agents;
using Symu.Common.Interfaces;
using Symu.Environment;
using Symu.Repository;

#endregion

namespace SymuTests.Helpers
{
internal sealed class TestSysDynAgent : TestReactiveAgent
{
public float Property1 { get; set; }
public float Property2 { get; set; }
public TestSysDynAgent(IAgentId id, SymuEnvironment environment) : base(id, environment){}

public override void SetProperty(string propertyName, float value)
{
switch (propertyName)
{
case "Property1":
Property1 = value;
break;
case "Property2":
Property2 = value;
break;
}
}
}
}
31 changes: 31 additions & 0 deletions SourceCode/SymuTests/Resources/sysdyn.xmile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>

<xmile version="1.0" xmlns="http://docs.oasis-open.org/xmile/ns/XMILE/v1.0">
<header>
<name>SysDyn</name>
<vendor>Symu</vendor>
</header>
<sim_specs method="Euler" time_units="Time">
<start>0</start>
<stop>12</stop>
<dt>0.25</dt>
</sim_specs>
<model>
<variables>
<stock name="Employees">
<eqn>10</eqn>
<inflow>Attrition</inflow>
<outflow>Recruitment</outflow>
<non_negative />
</stock>
<flow name="Attrition">
<eqn>Employees*0.1</eqn>
<non_negative />
</flow>
<flow name="Recruitment">
<eqn>Employees*0.1</eqn>
<non_negative />
</flow>
</variables>
</model>
</xmile>

0 comments on commit 51b6e97

Please sign in to comment.