Build a Model

Last updated on 16th July 2024

Phase 1

The Model interface wraps everything you define to build a simulation. Get started by learning how to build the credit card model.

1. Create a Model

First, create a new Java class in the same directory as Main.java in which you will implement the Model interface. In order to do so, right click on the directory and select new then Java File.

What is an interface?

A Java interface is a set of methods declared but generally not defined. To implement an interface, an object must first define its methods.

Insert implements Model after the class name and hit enter to automatically add the interface declaration at the top of the code.

CreditCard.java

import simudyne.core.Model;

public class CreditCard implements Model {
}
The Model is the core abstraction around which the Simudyne engine is designed. For more detailed information, you can consult the javadoc.
You will find an error near your model declaration. This is because you need to define the `step()` method.

2. Define step()

The step() method is called at each tick of the model. The calculations for every tick are specified inside the step() method.

Start by creating a variable called balance set to 400 and incremented by 20% at every tick.

Overriding step CreditCard.java

 import simudyne.core.Model;
 import simudyne.core.annotations.Variable;

 public class CreditCard implements Model {
 @Variable(name = "Balance")
    public float balance = 400;

    @Override
    public void step() {
    balance \*= 1.2;
    }
 }

What is an annotation ?

Annotations are used to mark fields in the model as inputs, outputs or constants. Learn more about annotations in the reference section.

3. Setup the Server

Before running the model, add it to the Main.java class to register on the Server.

Registering a model Main.java

 import simudyne.nexus.Server;
 import org.example.models.CreditCard.CreditCard;

 public class Main {
    public static void main(String[] args) {
      Server.register("My Credit Card", CreditCard.class);
      Server.run();
    }
 }

or run using the command:

$ Run Main
$ simudyne-maven-java> mvn clean compile exec:java -Dexec.mainClass="Main" -s settings.xml

By default, the console can be found at localhost:8080.

4. Launch Console

After launching the console, you will be brought to a list of models registered with the server. We have only registered "My Credit Card" so we only have one. Click on the model to be brought to the console for that model. Then, click the initialise button to initialise an interactive run.

model list v2 1

This will then display a number of buttons.

  • The cross allows you to cancel the run at any point.
  • Step allows you to run your model for a single time step.
  • Run, runs the model for the number of macro time steps we specify (to be discussed).

run tabs

5. Run Simulation

Once you've opened your model you will see a tile for the balance variable which you annotated earlier.

blank credit card

Use the arrows at the top of the console to control your simulation and watch your balance grow.

Phase 2

In order to improve the complexity of the model you will add:

  • Spending
  • Repayment
  • Interest

1. Declare Parameters

Add the new parameters required for the extended model.

Input Annotations

To add inputs to the console, use the @Input(name = "inputName").

Annotating inputs

@Input(name = "Spending")
public boolean isSpending = true;

@Input(name = "Spending Amount")
public float spending = 250f;

@Input(name = "Repayment Amount")
public float repayment = 200f;

@Input(name = "Interest Rate")
public float interest = 0.03f;

2. Define Calculations

Add new variables and update the calculations in the step() method.

Annotating Variables

@Variable(name = "Interest Charge")
public float interest_charge() { return interest * balance; }

@Variable(name = "Balance Additions")
public float balance_additions() {
  return interest_charge() + (isSpending ? spending : 0);
}

public void step() {
  balance += balance_additions() - repayment;

  if (balance < 0) {
    balance = 0;
  }
}

3. Initialize Balance

To specify an initial value for balance, add the initializable parameter to its variable annotation.

Initialize Variables

@Variable(name = "Balance", initializable = true)
public long balance = 400;

4. Model Settings

Now we set up the annotations on the model, this will set the model time unit, and define the 'macro step' which is what you'll see on the console when you want to advance time by more than a tick, in this case, a year.

Specify the macroStep

@ModelSettings(timeUnit = "MONTHS", macroStep = 12)
public class CreditCard implements Model {}

5. Final Model

In the console you will find inputs that you can control during the simulation. Your model class should look like this:

CreditCard.java

import simudyne.core.Model;
import simudyne.core.annotations.Input;
import simudyne.core.annotations.Variable;

@ModelSettings(timeUnit = "MONTHS", macroStep = 12)
public class CreditCard implements Model {

  @Input(name = "Spending")
  public boolean isSpending = true;

  @Input(name = "Spending Amount")
  public float spending = 250f;

  @Input(name = "Repayment Amount")
  public float repayment = 200f;

  @Input(name = "Interest Rate")
  public float interest = 0.03f;

  @Variable(name = "Balance", initializable = true)
  public long balance = 400;

  @Variable(name = "Interest Charge")
  public float interest_charge() { return interest * balance; }

  @Variable(name = "Balance Additions")
  public float balance_additions() {
    return interest_charge() + (isSpending ? spending : 0);
  }

  // Model Interface Methods
  @Override
  public void step() {
    balance += balance_additions() - repayment;

    if (balance < 0) {
      balance = 0;
    }
  }
}

If you have followed our guidelines, your model output should closely resemble the following.

console simple credit card visual