/*
* JaamSim Discrete Event Simulation
* Copyright (C) 2002-2011 Ausenco Engineering Canada Inc.
* Copyright (C) 2016 JaamSim Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jaamsim.basicsim;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import javax.swing.JFrame;
import com.jaamsim.Samples.SampleConstant;
import com.jaamsim.Samples.SampleInput;
import com.jaamsim.StringProviders.StringProvListInput;
import com.jaamsim.datatypes.IntegerVector;
import com.jaamsim.events.Conditional;
import com.jaamsim.events.EventManager;
import com.jaamsim.input.BooleanInput;
import com.jaamsim.input.DirInput;
import com.jaamsim.input.EntityListInput;
import com.jaamsim.input.Input;
import com.jaamsim.input.InputAgent;
import com.jaamsim.input.IntegerListInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.input.RunNumberInput;
import com.jaamsim.input.UnitTypeListInput;
import com.jaamsim.input.ValueInput;
import com.jaamsim.math.Vec3d;
import com.jaamsim.ui.AboutBox;
import com.jaamsim.ui.EditBox;
import com.jaamsim.ui.EntityPallet;
import com.jaamsim.ui.FrameBox;
import com.jaamsim.ui.GUIFrame;
import com.jaamsim.ui.LogBox;
import com.jaamsim.ui.ObjectSelector;
import com.jaamsim.ui.OutputBox;
import com.jaamsim.ui.PropertyBox;
import com.jaamsim.units.DimensionlessUnit;
import com.jaamsim.units.DistanceUnit;
import com.jaamsim.units.TimeUnit;
import com.jaamsim.units.Unit;
import com.jaamsim.units.UserSpecifiedUnit;
/**
* Simulation provides the basic structure for the Entity model lifetime of earlyInit,
* startUp and doEndAt. The initial processtargets required to start the model are
* added to the eventmanager here. This class also acts as a bridge to the UI by
* providing controls for the various windows.
*/
public class Simulation extends Entity {
// Key Inputs tab
@Keyword(description = "The duration of the simulation run in which all statistics will be recorded.",
example = "Simulation RunDuration { 8760 h }")
private static final ValueInput runDuration;
@Keyword(description = "The initialization interval for the simulation run. The model will "
+ "run for the InitializationDuration interval and then clear the "
+ "statistics and execute for the specified RunDuration interval. "
+ "The total length of the simulation run will be the sum of the "
+ "InitializationDuration and RunDuration inputs.",
example = "Simulation InitializationDuration { 720 h }")
private static final ValueInput initializationTime;
@Keyword(description = "An optional expression that pauses the run when TRUE is returned.",
example = "Simulation PauseCondition { '[Queue1].QueueLength > 20'}")
private static final SampleInput pauseConditionInput;
@Keyword(description = "If TRUE, the simulation run will be terminated when the "
+ "PauseCondition expression returns TRUE. If multiple runs have been "
+ "specified, then the next run will be started. If no more runs have "
+ "been specified, the simulation will be paused or terminated "
+ "depending on the input to the ExitAtStop keyword.",
example = "Simulation ExitAtPauseCondition { TRUE }")
private static final BooleanInput exitAtPauseCondition;
@Keyword(description = "If TRUE, the program will be closed on completion of the last "
+ "simulation run. Otherwise, the last run will be paused.",
example = "Simulation ExitAtStop { TRUE }")
private static final BooleanInput exitAtStop;
@Keyword(description = "Global seed that sets the substream for each probability "
+ "distribution. Must be an integer >= 0. GlobalSubstreamSeed works "
+ "together with each probability distribution's RandomSeed keyword to "
+ "determine its random sequence. It allows the user to change all the "
+ "random sequences in a model with a single input. To run multiple "
+ "replications, set the appropriate inputs under the Multiple Runs tab "
+ "and then set the GlobalSubstreamSeed input to the run number or to "
+ "one of the run indices.",
example = "Simulation GlobalSubstreamSeed { 5 }\n"
+ "Simulation GlobalSubstreamSeed { [Simulation].RunNumber }\n"
+ "Simulation GlobalSubstreamSeed { [Simulation].RunIndex(3) }")
private static final SampleInput globalSeedInput;
@Keyword(description = "If TRUE, a full output report is printed to the file "
+ "<configuration file name>.rep at the end of the simulation run.",
example = "Simulation PrintReport { TRUE }")
private static final BooleanInput printReport;
@Keyword(description = "The directory in which to place the output report. Defaults to the "
+ "directory containing the configuration file for the run.",
example = "Simulation ReportDirectory { 'c:\reports\' }")
private static final DirInput reportDirectory;
@Keyword(description = "The unit types for the selected outputs for the simulation run. "
+ "Use DimensionlessUnit for a text output.",
example = "Simulation UnitTypeList { DistanceUnit SpeedUnit }")
private static final UnitTypeListInput unitTypeList;
@Keyword(description = "One or more selected outputs to be printed at the end of each "
+ "simulation run. Each output is specified by an expression. In script "
+ "mode (-s tag), the selected outputs are printed to the command line "
+ "(standard out). Otherwise, they are printed to the file "
+ "<configuration file name>.dat.",
example = "Simulation RunOutputList { { [Entity1].Out1 } { [Entity2].Out2 } }")
protected static final StringProvListInput runOutputList;
@Keyword(description = "The length of time represented by one simulation tick.",
example = "Simulation TickLength { 1e-6 s }")
private static final ValueInput tickLengthInput;
// Multiple Runs tab
@Keyword(description = "Defines the number of run indices and the maximum value N for each "
+ "index. When making multiple runs, each index will be iterated from "
+ "1 to N starting with the last index. One run will be executed for "
+ "every combination of the run index values. For example, if three run "
+ "indices are defined with ranges of 3, 5, and 10, then at total of "
+ "3*5*10 = 150 runs will be executed.",
example = "Simulation RunIndexDefinitionList { 3 5 10 }")
private static final IntegerListInput runIndexDefinitionList;
@Keyword(description = "The first run number to be executed. The value can be entered as "
+ "either an integer or as the equivalent combination of run indices. "
+ "For example, if there are three run indices with ranges of "
+ "3, 5, and 10, then run number 22 can be expressed as 1-3-2 because "
+ "22 = (1-1)*5*10 + (3-1)*10 + 2.",
example = "Simulation StartingRunNumber { 22 }\n"
+ "Simulation StartingRunNumber { 1-3-2 }")
private static final RunNumberInput startingRunNumber;
@Keyword(description = "The last run number to be executed. The value can be entered as "
+ "either an integer or as the equivalent combination of run indices. "
+ "For example, if there are three run indices with ranges of "
+ "3, 5, and 10, then run number 78 can be expressed as 2-3-8 because "
+ "78 = (2-1)*5*10 + (3-1)*10 + 8.",
example = "Simulation EndingRunNumber { 78 }\n"
+ "Simulation EndingRunNumber { 2-3-8 }")
private static final RunNumberInput endingRunNumber;
// GUI tab
@Keyword(description = "An optional list of units to be used for displaying model outputs.",
example = "Simulation DisplayedUnits { h kt }")
private static final EntityListInput<? extends Unit> displayedUnits;
@Keyword(description = "If TRUE, a dragged object will be positioned to the nearest grid "
+ "point.",
example = "Simulation SnapToGrid { TRUE }")
private static final BooleanInput snapToGrid;
@Keyword(description = "The distance between snap grid points.",
example = "Simulation SnapGridSpacing { 1 m }")
private static final ValueInput snapGridSpacing;
@Keyword(description = "The distance moved by the selected entity when the an arrow key is "
+ "pressed.",
example = "Simulation IncrementSize { 1 cm }")
private static final ValueInput incrementSize;
@Keyword(description = "If TRUE, the simulation is executed a constant multiple of real time. "
+ "Otherwise, the run is executed as fast as possible, limited only by "
+ "processor speed.",
example = "Simulation RealTime { TRUE }")
private static final BooleanInput realTime;
@Keyword(description = "The target ratio of elapsed simulation time to elapsed real time.",
example = "Simulation RealTimeFactor { 1200 }")
private static final ValueInput realTimeFactor;
public static final double DEFAULT_REAL_TIME_FACTOR = 1;
public static final double MIN_REAL_TIME_FACTOR = 1e-6;
public static final double MAX_REAL_TIME_FACTOR = 1e6;
@Keyword(description = "The time at which the simulation will be paused.",
example = "Simulation PauseTime { 200 h }")
private static final ValueInput pauseTime;
@Keyword(description = "If TRUE, the Model Builder tool is shown on startup.",
example = "Simulation ShowModelBuilder { TRUE }")
private static final BooleanInput showModelBuilder;
@Keyword(description = "If TRUE, the Object Selector tool is shown on startup.",
example = "Simulation ShowObjectSelector { TRUE }")
private static final BooleanInput showObjectSelector;
@Keyword(description = "If TRUE, the Input Editor tool is shown on startup.",
example = "Simulation ShowInputEditor { TRUE }")
private static final BooleanInput showInputEditor;
@Keyword(description = "If TRUE, the Output Viewer tool is shown on startup.",
example = "Simulation ShowOutputViewer { TRUE }")
private static final BooleanInput showOutputViewer;
@Keyword(description = "If TRUE, the Property Viewer tool is shown on startup.",
example = "Simulation ShowPropertyViewer { TRUE }")
private static final BooleanInput showPropertyViewer;
@Keyword(description = "If TRUE, the Log Viewer tool is shown on startup.",
example = "Simulation ShowLogViewer { TRUE }")
private static final BooleanInput showLogViewer;
@Keyword(description = "Time at which the simulation run is started (hh:mm).",
example = "Simulation StartTime { 2160 h }")
private static final ValueInput startTimeInput;
// Hidden keywords
@Keyword(description = "If TRUE, then the input report file will be printed after loading "
+ "the configuration file. The input report can always be generated "
+ "when needed by selecting \"Print Input Report\" under the File menu.",
example = "Simulation PrintInputReport { TRUE }")
private static final BooleanInput printInputReport;
@Keyword(description = "This is placeholder description text",
example = "This is placeholder example text")
private static final BooleanInput traceEventsInput;
@Keyword(description = "This is placeholder description text",
example = "This is placeholder example text")
private static final BooleanInput verifyEventsInput;
private static double startTime; // simulation time (seconds) for the start of the run (not necessarily zero)
private static double endTime; // simulation time (seconds) for the end of the run
private static int runNumber; // labels each run when multiple runs are being made
private static IntegerVector runIndexList;
private static Simulation myInstance;
private static String modelName = "JaamSim";
static {
// Key Inputs tab
runDuration = new ValueInput("RunDuration", "Key Inputs", 31536000.0d);
runDuration.setUnitType(TimeUnit.class);
runDuration.setValidRange(1e-15d, Double.POSITIVE_INFINITY);
initializationTime = new ValueInput("InitializationDuration", "Key Inputs", 0.0);
initializationTime.setUnitType(TimeUnit.class);
initializationTime.setValidRange(0.0d, Double.POSITIVE_INFINITY);
pauseConditionInput = new SampleInput("PauseCondition", "Key Inputs", null);
pauseConditionInput.setUnitType(DimensionlessUnit.class);
exitAtPauseCondition = new BooleanInput("ExitAtPauseCondition", "Key Inputs", false);
exitAtStop = new BooleanInput("ExitAtStop", "Key Inputs", false);
globalSeedInput = new SampleInput("GlobalSubstreamSeed", "Key Inputs", new SampleConstant(0));
globalSeedInput.setUnitType(DimensionlessUnit.class);
globalSeedInput.setValidRange(0, Integer.MAX_VALUE);
printReport = new BooleanInput("PrintReport", "Key Inputs", false);
reportDirectory = new DirInput("ReportDirectory", "Key Inputs", null);
reportDirectory.setDefaultText("Configuration File Directory");
ArrayList<Class<? extends Unit>> defList = new ArrayList<>();
unitTypeList = new UnitTypeListInput("UnitTypeList", "Key Inputs", defList);
unitTypeList.setDefaultText("None");
runOutputList = new StringProvListInput("RunOutputList", "Key Inputs", null);
runOutputList.setUnitType(UserSpecifiedUnit.class);
runOutputList.setDefaultText("None");
tickLengthInput = new ValueInput("TickLength", "Key Inputs", 1e-6d);
tickLengthInput.setUnitType(TimeUnit.class);
tickLengthInput.setValidRange(1e-9d, 5.0d);
// Multiple Runs tab
IntegerVector defRangeList = new IntegerVector();
defRangeList.add(1);
runIndexDefinitionList = new IntegerListInput("RunIndexDefinitionList", "Multiple Runs", defRangeList);
startingRunNumber = new RunNumberInput("StartingRunNumber", "Multiple Runs", 1);
endingRunNumber = new RunNumberInput("EndingRunNumber", "Multiple Runs", 1);
// GUI tab
displayedUnits = new EntityListInput<>(Unit.class, "DisplayedUnits", "GUI", null);
displayedUnits.setDefaultText("SI Units");
displayedUnits.setPromptReqd(false);
realTime = new BooleanInput("RealTime", "GUI", false);
realTime.setPromptReqd(false);
snapToGrid = new BooleanInput("SnapToGrid", "GUI", false);
snapToGrid.setPromptReqd(false);
snapGridSpacing = new ValueInput("SnapGridSpacing", "GUI", 0.1d);
snapGridSpacing.setUnitType(DistanceUnit.class);
snapGridSpacing.setValidRange(1.0e-6, Double.POSITIVE_INFINITY);
snapGridSpacing.setPromptReqd(false);
incrementSize = new ValueInput("IncrementSize", "GUI", 0.1d);
incrementSize.setUnitType(DistanceUnit.class);
incrementSize.setValidRange(1.0e-6, Double.POSITIVE_INFINITY);
incrementSize.setPromptReqd(false);
realTimeFactor = new ValueInput("RealTimeFactor", "GUI", DEFAULT_REAL_TIME_FACTOR);
realTimeFactor.setValidRange(MIN_REAL_TIME_FACTOR, MAX_REAL_TIME_FACTOR);
realTimeFactor.setPromptReqd(false);
pauseTime = new ValueInput("PauseTime", "GUI", Double.POSITIVE_INFINITY);
pauseTime.setUnitType(TimeUnit.class);
pauseTime.setValidRange(0.0d, Double.POSITIVE_INFINITY);
pauseTime.setPromptReqd(false);
showModelBuilder = new BooleanInput("ShowModelBuilder", "GUI", false);
showModelBuilder.setPromptReqd(false);
showObjectSelector = new BooleanInput("ShowObjectSelector", "GUI", false);
showObjectSelector.setPromptReqd(false);
showInputEditor = new BooleanInput("ShowInputEditor", "GUI", false);
showInputEditor.setPromptReqd(false);
showOutputViewer = new BooleanInput("ShowOutputViewer", "GUI", false);
showOutputViewer.setPromptReqd(false);
showPropertyViewer = new BooleanInput("ShowPropertyViewer", "GUI", false);
showPropertyViewer.setPromptReqd(false);
showLogViewer = new BooleanInput("ShowLogViewer", "GUI", false);
showLogViewer.setPromptReqd(false);
// Hidden keywords
startTimeInput = new ValueInput("StartTime", "Key Inputs", 0.0d);
startTimeInput.setUnitType(TimeUnit.class);
startTimeInput.setValidRange(0.0d, Double.POSITIVE_INFINITY);
traceEventsInput = new BooleanInput("TraceEvents", "Key Inputs", false);
verifyEventsInput = new BooleanInput("VerifyEvents", "Key Inputs", false);
printInputReport = new BooleanInput("PrintInputReport", "Key Inputs", false);
// Initialize basic model information
startTime = 0.0;
endTime = 8760.0*3600.0;
runNumber = 1;
runIndexList = new IntegerVector();
runIndexList.add(1);
}
{
// Key Inputs tab
this.addInput(runDuration);
this.addInput(initializationTime);
this.addInput(pauseConditionInput);
this.addInput(exitAtPauseCondition);
this.addInput(exitAtStop);
this.addInput(globalSeedInput);
this.addInput(printReport);
this.addInput(reportDirectory);
this.addInput(unitTypeList);
this.addInput(runOutputList);
this.addInput(tickLengthInput);
// Multiple Runs tab
this.addInput(runIndexDefinitionList);
this.addInput(startingRunNumber);
this.addInput(endingRunNumber);
// GUI tab
this.addInput(displayedUnits);
this.addInput(snapToGrid);
this.addInput(snapGridSpacing);
this.addInput(incrementSize);
this.addInput(realTime);
this.addInput(realTimeFactor);
this.addInput(pauseTime);
this.addInput(showModelBuilder);
this.addInput(showObjectSelector);
this.addInput(showInputEditor);
this.addInput(showOutputViewer);
this.addInput(showPropertyViewer);
this.addInput(showLogViewer);
// Hidden keywords
this.addInput(startTimeInput);
this.addInput(traceEventsInput);
this.addInput(verifyEventsInput);
this.addInput(printInputReport);
// Hide various keywords
startTimeInput.setHidden(true);
traceEventsInput.setHidden(true);
verifyEventsInput.setHidden(true);
printInputReport.setHidden(true);
// Set the entity corresponding to "this" for keywords that can accept an expression
pauseConditionInput.setEntity(Simulation.getInstance());
globalSeedInput.setEntity(Simulation.getInstance());
runOutputList.setEntity(Simulation.getInstance());
}
public Simulation() {}
public static Simulation getInstance() {
if (myInstance == null) {
for (Entity ent : Entity.getClonesOfIterator(Entity.class)) {
if (ent instanceof Simulation) {
myInstance = (Simulation)ent;
break;
}
}
}
return myInstance;
}
@Override
public void updateForInput( Input<?> in ) {
super.updateForInput( in );
if(in == realTimeFactor || in == realTime) {
updateRealTime();
return;
}
if (in == pauseTime) {
updatePauseTime();
return;
}
if (in == reportDirectory) {
InputAgent.setReportDirectory(reportDirectory.getDir());
return;
}
if (in == unitTypeList) {
runOutputList.setUnitTypeList(unitTypeList.getUnitTypeList());
return;
}
if (in == runIndexDefinitionList) {
Simulation.setRunNumber(runNumber);
startingRunNumber.setRunIndexRangeList(runIndexDefinitionList.getValue());
endingRunNumber.setRunIndexRangeList(runIndexDefinitionList.getValue());
return;
}
if (in == startingRunNumber) {
Simulation.setRunNumber(startingRunNumber.getValue());
return;
}
if (in == displayedUnits) {
if (displayedUnits.getValue() == null)
return;
for (Unit u : displayedUnits.getValue()) {
Unit.setPreferredUnit(u.getClass(), u);
}
return;
}
if (in == showModelBuilder) {
if (GUIFrame.getInstance() != null)
setWindowVisible(EntityPallet.getInstance(), showModelBuilder.getValue());
return;
}
if (in == showObjectSelector) {
if (GUIFrame.getInstance() != null)
setWindowVisible(ObjectSelector.getInstance(), showObjectSelector.getValue());
return;
}
if (in == showInputEditor) {
if (GUIFrame.getInstance() != null)
setWindowVisible(EditBox.getInstance(), showInputEditor.getValue());
FrameBox.reSelectEntity();
return;
}
if (in == showOutputViewer) {
if (GUIFrame.getInstance() != null)
setWindowVisible(OutputBox.getInstance(), showOutputViewer.getValue());
FrameBox.reSelectEntity();
return;
}
if (in == showPropertyViewer) {
if (GUIFrame.getInstance() != null)
setWindowVisible(PropertyBox.getInstance(), showPropertyViewer.getValue());
FrameBox.reSelectEntity();
return;
}
if (in == showLogViewer) {
if (GUIFrame.getInstance() != null)
setWindowVisible(LogBox.getInstance(), showLogViewer.getValue());
FrameBox.reSelectEntity();
return;
}
}
/**
* Clears the Simulation prior to loading a new model
*/
public static void clear() {
// Reset all Simulation inputs to their default values
for (Input<?> inp : Simulation.getInstance().getEditableInputs()) {
inp.reset();
}
updateRealTime();
// Initialize basic model information
startTime = 0.0;
endTime = 8760.0*3600.0;
myInstance = null;
// close warning/error trace file
InputAgent.closeLogFile();
// Kill all entities except simulation
while(Entity.getAll().size() > 0) {
Entity ent = Entity.getAll().get(Entity.getAll().size()-1);
ent.kill();
}
// Reset the run number and run indices
Simulation.setRunNumber(1);
}
/**
* Initializes and starts the model
* 1) Initializes EventManager to accept events.
* 2) calls startModel() to allow the model to add its starting events to EventManager
* 3) start EventManager processing events
*/
public static void start(EventManager evt) {
// Validate each entity based on inputs only
for (Entity each : Entity.getClonesOfIterator(Entity.class)) {
try {
each.validate();
}
catch (Throwable e) {
InputAgent.logMessage("Validation Error - %s: %s", each.getName(), e.getMessage());
GUIFrame.showErrorDialog("Input Error",
"JaamSim has detected the following input error during validation:",
String.format("%s: %-70s", each.getName(), e.getMessage()),
"The error must be corrected before the simulation can be started.");
GUIFrame.updateForSimState(GUIFrame.SIM_STATE_CONFIGURED);
return;
}
}
InputAgent.prepareReportDirectory();
evt.clear();
evt.setTraceListener(null);
if( Simulation.traceEvents() ) {
String evtName = InputAgent.getConfigFile().getParentFile() + File.separator + InputAgent.getRunName() + ".evt";
EventRecorder rec = new EventRecorder(evtName);
evt.setTraceListener(rec);
}
else if( Simulation.verifyEvents() ) {
String evtName = InputAgent.getConfigFile().getParentFile() + File.separator + InputAgent.getRunName() + ".evt";
EventTracer trc = new EventTracer(evtName);
evt.setTraceListener(trc);
}
evt.setTickLength(tickLengthInput.getValue());
startTime = startTimeInput.getValue();
endTime = startTime + Simulation.getInitializationTime() + Simulation.getRunDuration();
Simulation.setRunNumber(startingRunNumber.getValue());
Simulation.startRun(evt);
}
/**
* Starts a single simulation run.
* @param evt - EventManager for the run.
*/
private static void startRun(EventManager evt) {
evt.scheduleProcessExternal(0, 0, false, new InitModelTarget(), null);
evt.resume(evt.secondsToNearestTick(Simulation.getPauseTime()));
}
/**
* Ends a single simulation run and if appropriate restarts the model for the next run.
*/
public static void endRun() {
// Execute the end of run method for each entity
for (Entity each : Entity.getClonesOfIterator(Entity.class)) {
each.doEnd();
}
// Print the output report
if (printReport.getValue())
InputAgent.printReport(EventManager.simSeconds());
// Print the selected outputs
if (runOutputList.getValue() != null) {
InputAgent.printRunOutputs(EventManager.simSeconds());
}
// Increment the run number and check for last run
if (Simulation.isLastRun()) {
Simulation.end();
return;
}
// Start the next run
final EventManager currentEvt = EventManager.current();
Simulation.setRunNumber(runNumber + 1);
Simulation.stopRun(currentEvt);
new Thread(new Runnable() {
@Override
public void run() {
Simulation.startRun(currentEvt);
}
}).start();
}
/**
* Ends a set of simulation runs.
*/
private static void end() {
// Close warning/error trace file
LogBox.logLine("Made it to do end at");
InputAgent.closeLogFile();
// Always terminate the run when in batch mode
if (InputAgent.getBatch() || exitAtStop.getValue())
GUIFrame.shutdown(0);
EventManager.current().pause();
}
/**
* Stops and resets the simulation model to zero simulation time.
* @param evt - EventManager for the run.
*/
public static void stop(EventManager evt) {
// Stop the present simulation run
Simulation.stopRun(evt);
// Reset the run number and run indices
Simulation.setRunNumber(startingRunNumber.getValue());
// Close the output reports
InputAgent.stop();
}
/**
* Stops the present simulation run when multiple runs are to be executed.
* @param evt - EventManager for the run.
*/
private static void stopRun(EventManager evt) {
// Stop the simulation and clear the event list
evt.pause();
evt.clear();
// Destroy the entities that were generated during the run
for (int i = 0; i < Entity.getAll().size();) {
Entity ent = Entity.getAll().get(i);
if (ent.testFlag(Entity.FLAG_GENERATED))
ent.kill();
else
i++;
}
// Re-initialise the model
for (Entity each : Entity.getClonesOfIterator(Entity.class)) {
// Try/catch is required because some earlyInit methods use simTime which is only
// available from a process thread
try {
each.earlyInit();
} catch (Exception e) {}
}
// Initialise each entity a second time
for (Entity each : Entity.getClonesOfIterator(Entity.class)) {
try {
each.lateInit();
} catch (Exception e) {}
}
}
public static int getSubstreamNumber() {
return (int)globalSeedInput.getValue().getNextSample(0.0);
}
public static boolean getPrintReport() {
return printReport.getValue();
}
public static boolean traceEvents() {
return traceEventsInput.getValue();
}
public static boolean verifyEvents() {
return verifyEventsInput.getValue();
}
public static double getTickLength() {
return tickLengthInput.getValue();
}
public static double getPauseTime() {
return pauseTime.getValue();
}
/**
* Returns the start time of the run.
* @return - simulation time in seconds for the start of the run.
*/
public static double getStartTime() {
return startTime;
}
/**
* Returns the end time of the run.
* @return - simulation time in seconds when the current run will stop.
*/
public static double getEndTime() {
return endTime;
}
/**
* Returns the duration of the run (not including intialization)
*/
public static double getRunDuration() {
return runDuration.getValue();
}
/**
* Returns the duration of the initialization period
*/
public static double getInitializationTime() {
return initializationTime.getValue();
}
public static StringProvListInput getRunOutputList() {
return runOutputList;
}
public static double getIncrementSize() {
return incrementSize.getValue();
}
public static boolean isSnapToGrid() {
return snapToGrid.getValue();
}
public static double getSnapGridSpacing() {
return snapGridSpacing.getValue();
}
public static boolean getExitAtPauseCondition() {
return exitAtPauseCondition.getValue();
}
public void doPauseCondition() {
if (pauseConditionInput.getValue() != null)
EventManager.scheduleUntil(pauseModel, pauseCondition, null);
}
private final PauseModelTarget pauseModel = new PauseModelTarget();
static class PauseConditional extends Conditional {
@Override
public boolean evaluate() {
if (pauseConditionInput.getValue() == null)
return false;
double simTime = EventManager.simSeconds();
return pauseConditionInput.getValue().getNextSample(simTime) != 0.0d;
}
}
private final Conditional pauseCondition = new PauseConditional();
/**
* Returns the nearest point on the snap grid to the given coordinate.
* To avoid dithering, the new position must be at least one grid space
* from the old position.
* @param newPos - new coordinate for the object
* @param oldPos - present coordinate for the object
* @return newest snap grid point.
*/
public static Vec3d getSnapGridPosition(Vec3d newPos, Vec3d oldPos) {
double spacing = snapGridSpacing.getValue();
Vec3d ret = new Vec3d(newPos);
if (Math.abs(newPos.x - oldPos.x) < spacing)
ret.x = oldPos.x;
if (Math.abs(newPos.y - oldPos.y) < spacing)
ret.y = oldPos.y;
if (Math.abs(newPos.z - oldPos.z) < spacing)
ret.z = oldPos.z;
return Simulation.getSnapGridPosition(ret);
}
/**
* Returns the nearest point on the snap grid to the given coordinate.
* @param pos - position to be adjusted
* @return nearest snap grid point.
*/
public static Vec3d getSnapGridPosition(Vec3d pos) {
double spacing = snapGridSpacing.getValue();
Vec3d ret = new Vec3d(pos);
ret.x = spacing*Math.rint(ret.x/spacing);
ret.y = spacing*Math.rint(ret.y/spacing);
ret.z = spacing*Math.rint(ret.z/spacing);
return ret;
}
static void updateRealTime() {
GUIFrame.updateForRealTime(realTime.getValue(), realTimeFactor.getValue());
}
static void updatePauseTime() {
GUIFrame.updateForPauseTime(pauseTime.getValueString());
}
public static void setModelName(String newModelName) {
modelName = newModelName;
}
public static String getModelName() {
return modelName;
}
public static boolean getExitAtStop() {
return exitAtStop.getValue();
}
public static boolean getPrintInputReport() {
return printInputReport.getValue();
}
public static boolean isRealTime() {
return realTime.getValue();
}
public static void setWindowVisible(JFrame f, boolean visible) {
f.setVisible(visible);
if (visible)
f.toFront();
}
/**
* Re-open any Tools windows that have been closed temporarily.
*/
public static void showActiveTools() {
setWindowVisible(EntityPallet.getInstance(), showModelBuilder.getValue());
setWindowVisible(ObjectSelector.getInstance(), showObjectSelector.getValue());
setWindowVisible(EditBox.getInstance(), showInputEditor.getValue());
setWindowVisible(OutputBox.getInstance(), showOutputViewer.getValue());
setWindowVisible(PropertyBox.getInstance(), showPropertyViewer.getValue());
setWindowVisible(LogBox.getInstance(), showLogViewer.getValue());
}
/**
* Closes all the Tools windows temporarily.
*/
public static void closeAllTools() {
if (GUIFrame.getInstance() == null)
return;
setWindowVisible(EntityPallet.getInstance(), false);
setWindowVisible(ObjectSelector.getInstance(), false);
setWindowVisible(EditBox.getInstance(), false);
setWindowVisible(OutputBox.getInstance(), false);
setWindowVisible(PropertyBox.getInstance(), false);
setWindowVisible(LogBox.getInstance(), false);
}
private static void setRunNumber(int n) {
runNumber = n;
runIndexList = Simulation.getRunIndexList(n, runIndexDefinitionList.getValue());
}
/**
* Returns the run indices that correspond to a given run number.
* @param n - run number.
* @param rangeList - maximum value for each index.
* @return run indices.
*/
public static IntegerVector getRunIndexList(int n, IntegerVector rangeList) {
IntegerVector indexList = new IntegerVector(rangeList.size());
indexList.fillWithEntriesOf(rangeList.size(), 0);
int denom = 1;
for (int i=rangeList.size()-1; i>=0; i--) {
indexList.set(i, (n-1)/denom % rangeList.get(i) + 1);
denom *= rangeList.get(i);
}
return indexList;
}
/**
* Returns the run number that corresponds to a given set of run indices.
* @param indexList - run indices.
* @param rangeList - maximum value for each index.
* @return run number.
*/
public static int getRunNumber(IntegerVector indexList, IntegerVector rangeList) {
int n = 1;
int factor = 1;
for (int i=indexList.size()-1; i>=0; i--) {
n += (indexList.get(i)-1)*factor;
factor *= rangeList.get(i);
}
return n;
}
/**
* Returns the input format used to specify a set of run indices.
* @param indexList - run indices.
* @return run code.
*/
public static String getRunCode(IntegerVector indexList) {
StringBuilder sb = new StringBuilder();
sb.append(indexList.get(0));
for (int i=1; i<indexList.size(); i++) {
sb.append("-").append(indexList.get(i));
}
return sb.toString();
}
public static String getRunCode() {
return Simulation.getRunCode(runIndexList);
}
public static String getRunHeader() {
return String.format("##### RUN %s #####", Simulation.getRunCode());
}
public static boolean isMultipleRuns() {
return endingRunNumber.getValue() > startingRunNumber.getValue();
}
public static boolean isFirstRun() {
return runNumber == startingRunNumber.getValue();
}
public static boolean isLastRun() {
return runNumber >= endingRunNumber.getValue();
}
@Output(name = "Software Name",
description = "The licensed name for the simulation software.",
reportable = true,
sequence = 0)
public String getSoftwareName(double simTime) {
return modelName;
}
@Output(name = "Software Version",
description = "The release number for the simulation software.",
reportable = true,
sequence = 1)
public String getSoftwareVersion(double simTime) {
return AboutBox.version;
}
@Output(name = "Configuration File",
description = "The configuration file that has been loaded.",
reportable = true,
sequence = 2)
public String getConfigFileName(double simTime) {
if (InputAgent.getConfigFile() != null)
return InputAgent.getConfigFile().getPath();
return "";
}
@Output(name = "RunNumber",
description = "The counter used to indentify an individual simulation run when multiple runs "
+ "are being made.",
unitType = DimensionlessUnit.class,
reportable = true,
sequence = 3)
public int getRunNumber(double simTime) {
return runNumber;
}
@Output(name = "RunIndex",
description = "The list of run indices that correspond to the run number.",
unitType = DimensionlessUnit.class,
reportable = true,
sequence = 4)
public IntegerVector getRunIndex(double simTime) {
return runIndexList;
}
@Output(name = "Present Time and Date",
description = "The present local time and date.",
reportable = true,
sequence = 5)
public String getPresentTime(double simTime) {
String timeStamp = new SimpleDateFormat("MMM dd, yyyy HH:mm").format(Calendar.getInstance().getTime());
return timeStamp;
}
@Output(name = "Initialization Duration",
description = "The length of time the model was executed prior to the start of statistics "
+ "collection.",
unitType = TimeUnit.class,
reportable = true,
sequence = 6)
public double getInitializationDuration(double simTime) {
return initializationTime.getValue();
}
@Output(name = "Run Duration",
description = "The length of time over which statistics were collected.",
unitType = TimeUnit.class,
reportable = true,
sequence = 7)
public double getRunDuration(double simTime) {
return runDuration.getValue();
}
@Output(name = "Present Simulation Time",
description = "The value for the simulation clock at the present time.",
unitType = TimeUnit.class,
reportable = true,
sequence = 8)
public double getPresentSimulationTime(double simTime) {
return simTime;
}
}