diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..5292c375 --- /dev/null +++ b/404.html @@ -0,0 +1,1780 @@ + + + +
+ + + + + + + + + + + + + + + + + + +kalasim
is licensed under MIT License.
kalasim
started off as a blunt rewrite of salabim. We are deeply thankful for its permissive licence that enabled setting up kalasim
. A great starting point was in particular the wonderful article salabim: discrete event simulation and animation in Python.
salabim
s excellent documentation and wonderful examples made this project possible after all. kalasim
reimplements all core APIs of salabim
in a more typesafe API while also providing better test coverage, real-time capabilities and (arguably) more modern built-in support for visualization.
simmer is a process-oriented and trajectory-based Discrete-Event Simulation (DES) package for R.
+It centres around the concept of a trajectory that defines a component lifecycle. To enable scale it is built on top of Rcpp (C++ backend for R).
+We have adopted several examples and documentation bits from simmer
, and are deeply grateful to the simmer developers for providing such a great and well maintained tool. simmer
has also been a great source of inspiration to implement in particular the monitoring and visualization API of kalasim
.
SimJulia is a combined continuous time / discrete event process oriented simulation framework written in Julia inspired by the Simula library DISCO and the Python library SimPy.
+We have adopted several examples and documentation bits from SimJulia
, and are deeply grateful its developers for providing such a great and well maintained tool.
SimPy is a process-based discrete-event simulation framework based on standard Python. Processes in SimPy
are defined by Python generator functions. SimPy
also provides various types of shared resources to model limited capacity congestion points (like servers, checkout counters and tunnels).
We have adopted several examples and documentation bits from SimPy
, and are deeply grateful its developers for providing such a great and well maintained tool.
DSOL3 which is an open source, Java based suite of Java classes for continuous and discrete event simulation
+kalasim
is built on top of some great libraries. It was derived as merger of ideas, implementation and documentation from the following projects:
kalasim
provides a machine-readable log-format for all basics in a simulation.Visualization
+Inspirations
+With kalasim
, we strive to enable large-scale time-discrete simulation models.
+To optimize the API and the engine for perormance, we rely
+on YourKit profiler.
+With its wonderful interface into JDK performace metrics,
+YourKit profiler allows us to signifantly improve the overall speed while reducing the memory footprint of kalasim
.
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET +applications. YourKit is the creator of YourKit Java Profiler.
+Holger Brandl holds a Ph.D. degree in machine learning and has developed new concepts in the field of computational linguistics. More recently he has co-authored publications in high-ranking journals such as Nature and Science.
+To stay in sync with what's happening in tech, he's developing open-source tools, methods and algorithms for bioinformatics, high-performance computing and data science. He's passionate about machine learning, AI, analytics, elegant APIs and data visualisation. His professional scope mainly centers around systems biology and industrial manufacturing.
+ + + + + + + + + + + + + +In simulation a clear distinction is made between real time and simulation time. With real time we refer to the wall-clock time. It represents the execution time of the experiment. The simulation time is an attribute of the simulator.
+To support use cases where a simulation may drive a demonstration or system check, the kalasim
API allows to run a simulation at a defined clock speed. Such real-time simulations may be necessary
import org.kalasim.*
+import kotlin.time.Duration.Companion.seconds
+
+val timeBefore = System.currentTimeMillis()
+
+createSimulation {
+ enableComponentLogger()
+
+ // enable real-time clock synchronization
+ ClockSync(tickDuration = 1.seconds)
+
+ run(10)
+}
+
+println("time passed ${System.currentTimeMillis() - timeBefore})")
+
To enable clock synchronization, we need to add a ClockSync
to our simulation. We need to define what one tick in simulation time corresponds to in wall time. In the example, one tick equals to one second wall time. This is configured with the parameter tickDuration
. It defines the duration of a simulation tick in wall clock coordinates. It can be created with Duration.ofSeconds(1)
, Duration.ofMinutes(10)
and so on.
ClockSync
also provides settings for more advanced uses-cases
speedUp
to run a simulation faster (speedUp
> 1) or slower (speedUp
< 1) than realtime. It defaults to 1
, that is no speed-up will be applied.syncsPerTick
defines how often a clock synchronization should happen. Per default it synchronizes once per tick (i.e. an 1-increment of simulation time).It may happen that a simulation is too complex to run at a defined clock. In such a situation, it (i.e. Environment.run()
) will throw a ClockOverloadException
if the user has specified a maximum delay maxDelay
parameter between simulation and wall clock coordinates.
Even if kalasim
tries to provide a simplistic, efficient, declarative approach to define a simulation, it may come along with computational demands simulation. To allow introspection into time-complexity of the underlying computations, the user may want to enable the built-in env.tickMetrics
monitor to analyze how much time is spent per time unit (aka tick). This monitor can be enabled by calling enableTickMetrics()
when configuring the simulation.
import org.kalasim.*
+import org.kalasim.plot.letsplot.display
+
+createSimulation {
+ enableTickMetrics()
+
+ object : Component() {
+ override fun process() = sequence {
+ while(true) {
+ // create some artificial non-linear compute load
+ if(nowTT.value < 7)
+ Thread.sleep((nowTT.value * 100).toLong())
+ else {
+ Thread.sleep(100)
+ }
+
+ hold(1.minutes)
+ }
+ }
+ }
+
+ run(10.hours)
+
+ tickMetrics.display().show()
+}
+
There are multiple ways to improve the performance of a simulation.
+AssertMode
: The assertion mode determines which internal consistency checks are being performed. The mode can be set to Full
(Slowest), Light
(default) or Off
(Fastest). Depending on simulation logic and complexity, this will improve performance by ~20%.To further fine-tune and optimize simulation performance and to reveal bottlenecks, a JVM profiler (such as yourkit or the built-in profiler of Intellij IDEA Ultimate) can be used. Both call-counts and spent-time analysis have been proven useful here.
+For some use-cases, simulations may run for a very long simulation and wall time. To prevent internal metrics gathering from consuming all available memory, it needs to be disabled or at least configured carefully. This can be achieved, but either disabling timelines and monitors manually on a per-entity basis, or by setting a sensible default policy via Environment.entityTrackingDefaults
For each entity type a corresponding tracking-policy TrackingConfig
can be provisioned along with an entity matcher to narrow down its scope. A tracking-policy allows to change
There are different default implementations, but the user can also implement and register custom tracking-configurations.
+//import org.kalasim.*
+import org.kalasim.misc.*
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.minutes
+
+
+class Driver : Resource(trackingConfig = ResourceTrackingConfig(trackUtilization = false))
+class TrafficLight : State<String>("red", trackingConfig = StateTrackingConfig(logCreation = false))
+
+class Car : Component(
+ trackingConfig = ComponentTrackingConfig(logInteractionEvents = false)
+) {
+
+ val trafficLight = get<TrafficLight>()
+ val driver = get<Driver>()
+
+ override fun process() = sequence {
+ request(driver) {
+ hold(30.minutes, description = "driving")
+
+ wait(trafficLight, "green")
+ }
+ }
+}
+
+createSimulation {
+ enableComponentLogger()
+
+ // in addition or alternatively we can also change the environment defaults
+ entityTrackingDefaults.DefaultComponentConfig =
+ ComponentTrackingConfig(logStateChangeEvents = false)
+
+ // create simulation entities
+ dependency { TrafficLight() }
+ dependency { Driver() }
+
+ Car()
+}.run(5.hours)
+
Note
+Tracking configuration policies defaults must be set before instantiating simulation entities to be used
+To disable all metrics and to minimize internal event logging, the user can run env.entityTrackingDefaults.disableAll()
The same mechanism applies also fine-tune the internal event logging. By disabling some - not-needed for production - events, simulation performance can be improved significantly.
+kalasim
does not include a default mechanism to serialize and deserialize simulations yet. However, it seems that with xstream that Environment
can be saved including its current simulation state across all included entities. It can be restored from the xml snapshot and continued with run()
.
We have not succeeded to do the same with gson yet. Also, some experiments with kotlinx.serialization were not that successful.
+The simulation engine provides different levels of internal consistency checks. As these are partially computationally expensive these can be be/disabled. There are 3 modes
+OFF
- Productive mode, where asserts that may impact performance are disabled.LIGHT
- Disables compute-intensive asserts. This will have a minimal to moderate performance impact on simulations.FULL
- Full introspection, this will have a measurable performance impact on simulations. E.g. it will validate that passive components are not scheduled, and queued components have unique names.Switching off asserts, will typically optimize performance by another ~20% (depending on simulation logic).
+ + + + + + + + + + + + + +A core aspect when building simulations is to understand, define and modulate the inherent system dynamics. To build a correct simulation, the designer/developer must carefully analyze how states progress over time.
+To facilitate this process, kalasim
offers various means to analyze data created by a simulation
See chapter about monitors.
+See chapter about event logging.
+See chapter about visualization.
+The state transition of a component provide value insight into its behavior. This is facilitated by lifecycle statistics ComponentLifecycleRecord
that summarize a component's states history.
These data can also be transformed easily into a table as well +
val customers : List<Component> // = ...
+val records: List<ComponentLifecycleRecord> = customers.map { it.toLifeCycleRecord() }
+
+records.asDataFrame()
+
This transforms the customers
straight into a krangl
dataframe with the following structure
A DataFrame: 1034 x 11
+ component createdAt inCurrent inData inDataSince inInterrupted inPassive
+ 1 Vehicle.1 0.366 0 989.724 10.276 0 0
+ 2 Vehicle.2 1.294 0 984.423 15.577 0 0
+ 3 Vehicle.3 1.626 0 989.724 10.276 0 0
+ 4 Vehicle.4 2.794 0 989.724 10.276 0 0
+and 1024 more rows, and and 4 more variables: inScheduled, inStandby, inWaiting
+
Clearly if needed, the user may also work with the records directly. For instance to configure a visualization.
+Running a simulation just once, often does not provide sufficient insights into the dynamics of the system under consideration. Often, the user may want to execute a model many times with altered initial conditions, and then perform a statistical analysis over the output. This is also considered as what-if analyis. See here for simple example.
+By design kalasim
does not make use of parallelism. So when scaling up execution to run in paralell, we need to be careful, that the internal dependency injection (which relates by default to a global context variable) does not cause trouble. See here for an example that defines a parameter grid to be assessed with multi-threading with a simulation run per hyper-parameter.
To prevent memory leaks, the environment just keeps track of scheduled components, that is components that are queued for execution. In some situations the user may want to track all components irrespective of their queuing status. This can be achieved by setting up a component collector before creating the components
+createSimulation{
+ val cc = componentCollector()
+
+ // create components
+ Component("foo")
+ Component("bar")
+
+ // analyze all components created until this point
+ cc.size // will be 2
+}
+
Animation is a powerful tool to debug, test and demonstrate simulations.
+It is possible use shapes (lines, rectangles, circles, etc), texts as well image to visualize the state of a simulation model. Statistical properties may be animated by showing the current value against the time.
+Process animations can be
+All it takes is a single dependency
+dependencies {
+ api("com.github.holgerbrandl:kalasim-animation:0.7.97")
+}
+
The dependency pull everything you need to animate simulations.
+For fully worked out examples, have a look at the lunar mining or the office tower.
+If you're not sure how to configure gradle, you could also start with the provided processes animation template project.
+OPENRNDR is an open source framework for creative coding, written in Kotlin that simplifies writing real-time interactive software.
++For more details see https://openrndr.org/
+Process animation with kalasim
is using OPENRNDR
as backend and rendering engine. Animation is not part of the core API of kalasim, but support is provided by a decorator types (extending their respective base-type)
Component
-> AnimationComponent
Resource
-> AnimationResource
ComponentQueue
-> AnimationResource
These components are worked out below.
+The basic structure of a process animation is as follows
+// package org.kalasim.animation
+
+import kotlinx.coroutines.*
+import org.kalasim.ClockSync
+import org.kalasim.Environment
+import org.kalasim.misc.DependencyContext
+import org.openrndr.application
+import org.openrndr.color.ColorRGBa
+import org.openrndr.draw.loadFont
+import org.openrndr.draw.loadImage
+import java.awt.geom.Point2D
+import java.lang.Thread.sleep
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.DurationUnit
+
+fun main() {
+ application {
+ // setup simulation model
+ val sim = object : Environment(tickDurationUnit = DurationUnit.SECONDS) {
+ init {
+ ClockSync(tickDuration = 10.milliseconds, syncsPerTick = 100)
+ }
+
+ // instantiate components (not fully worked out here)
+ val worker = AnimationComponent(Point2D.Double(1.0, 3.0))
+ }
+
+ // configure the window
+ configure {
+ width = 1024
+ height = 800
+ windowResizable = true
+ title = "Simulation Name"
+ }
+
+ var frameCounter = 0
+
+ program {
+ // load resources such as images
+ val image = loadImage("src/main/resources/1024px-Phlegra_Montes_on_Mars_ESA211127.jpg")
+// val truck = loadSVG("src/main/resources/tractor-svgrepo-com.svg")
+ val font = loadFont("file:IBM_Plex_Mono/IBMPlexMono-Bold.ttf", 24.0)
+
+ // optionally enable video recording
+// extend(ScreenRecorder())
+
+ extend {
+ // draw background
+ drawer.image(image, 0.0, 0.0, width.toDouble(), height.toDouble())
+
+ // visualize simulation entities
+ with(drawer) {
+ val workerPosition = sim.worker.currentPosition
+ circle(workerPosition.x, workerPosition.y, 10.0)
+ }
+
+
+ // draw info & statistics
+ drawer.defaults()
+ drawer.fill = ColorRGBa.WHITE
+ drawer.fontMap = font
+ drawer.text("NOW: ${sim.now}", width - 150.0, height - 30.0)
+ drawer.text("Frame: ${frameCounter++}", width - 150.0, height - 50.0)
+ }
+ }
+
+ // Start simulation model
+ CoroutineScope(Dispatchers.Default).launch {
+ //rewire koin context for dependency injection to async execution context
+ DependencyContext.setKoin(sim.getKoin())
+ // wait because Openrndr needs a second to warm up
+ sleep(3000)
+ sim.run()
+ }
+ }
+}
+
For an in-depth walkthrough of the elements the an animation, see https://guide.openrndr.org/
+By changing the base class of a component from Component
to org.kalasim.animation.AnimationComponent
, we decorate the original with the following features
Point2D
)moveTo(newLocation:Point2D)
the API provides suspendable wrapper around hold()
c.currentPosition
. Positions are linearly interpolated.hold()
InteractionsAn animation can track the status hold()
interaction with holdProgress
. It's a 2 step process
First, we need to register what type of holds we would like to monitor +
val UNLOADING = "Unloading"
+val c: Component = Component()
+
+c.registerHoldTracker(UNLOADING) { it.description.startsWith("unloading")}
+
Once it has been registered, the tracker can be consumed in the rendering loop with isHolding
and holdProgress
.
+
if(c.isHolding(UNLOADING)) {
+ drawer.contour(contour.sub(0.0, (1 - c.holdProgress(UNLOADING)!!)))
+}
+
For a fully worked out example, see how the mining process is animated in the lunar mining demo.
+Dedicated support for resource rendering is coming soon. See lunar mining to see how it's done.
+Dedicated support for state rendering is coming soon.
+Dedicated support for collection rendering is coming soon.
+The animation support API does not bind to a particular rendering engine. However, until now only https://openrndr.org/ has been explored for process animation with kalasim
.
\n", + "Full moon photograph taken 10-22-2010 from Madison, Alabama, USA; CC BY-SA 3.0\n", + "
\n", + "\n", + "ESPA has ordered their process specialists to work out a simulation model of the mining process. With the simulation, the number of mining robots needed to supply the base with enough water must be determined. Also, water production rates shall be estimated. \n", + "\n", + "ESPA simulation engineers have to solve two very typical tasks in industrial engineering\n", + "\n", + "1. Capacity Planning (number of mining robots needed)\n", + "2. Forecast of Production KPIs (tons of water/day)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "\n", + "## Simulation Model\n", + "\n", + "There is a complex interplay of rate-limited processes (transport, search, mining), limited resources and the harsh realities of deep space. The latter is abstracted away in the model as it does not contribute to model performance\n", + "\n", + "* While the specific locations of ice-deposits are unknown, their average distribution and size on the moon had been determined already using a [satellite](https://blog.jatan.space/p/how-nasa-and-chandrayaan-discovered-water-on-the-moon) equipped with the onboard radar, ultraviolet detectors as well as a neutron spectrometer\n", + "* Small harvester robots are being deployed from a central depot to scan the lunar surface for water deposits\n", + "* When finding a depot they deplete it\n", + "* They have a limited storage capacity (100kg), so they will need to shuttle the cargo to the base\n", + "* The base will consume water constantly (exponentially distributed with a mean of 5 kg/h)\n", + "* The base has an initial deposit of 100kg water (which was shipped to the moon very expensively with rockets from earth)\n", + "* Idle harvesters will consult the base for nearby deposits discovered by other units\n", + "\n", + "The complete model definition can be found [here](https://github.com/holgerbrandl/kalasim/blob/master/simulations/lunar-mining/src/main/kotlin/org/kalasim/demo/moon/LunarMining.kt). As an example, we inspect the unloading process of water at the base\n", + "\n", + "```kotlin\n", + "fun unload() = sequence {\n", + " moveTo(base.position)\n", + "\n", + " val unloadingUnitsPerHours = 20 // speed of unloading\n", + "\n", + " // unloading time correlates with load status\n", + " currentState = UNLOADING\n", + " hold((tank.level / unloadingUnitsPerHours).roundToInt().hours,\n", + " \"Unloading ${tank.level} water units\")\n", + " \n", + " // put the water into the refinery of the base\n", + " put(get\n", + "API surface of the lunar mining simulation model\n", + "
\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "\n", + "## Process Animation\n", + "\n", + "The model can be expressed easily in approximately 200 lines of [process definitions](../component.md#process-definition) in [`LunarMining.kt`](https://github.com/holgerbrandl/kalasim/blob/master/simulations/lunar-mining/src/main/kotlin/org/kalasim/demo/moon/LunarMining.kt). Howvever, it was not initially clear, if the intended dynamics were implemented correctly. [Process animation](animation.md) comes to resuce, as it allows to debug the model visually.\n", + "\n", + "A process animation was developed as well to better understand the spatio-temporal dynamics of the model. In [LunarMiningHQ.kt](https://github.com/holgerbrandl/kalasim/blob/master/simulations/lunar-mining/src/main/kotlin/org/kalasim/demo/moon/LunarMiningHQ.kt) the animation of this process is worked out in just about 150 lines of code.\n", + "\n", + "\n", + "Mining robots scan the surface of the moon for depletable water deposits.
+From Wikipedia on Lunar Resources
+++The Moon bears substantial natural resources which could be exploited in the future. Potential lunar resources may encompass processable materials such as volatiles and minerals, along with geologic structures such as lava tubes that together, might enable lunar habitation. The use of resources on the Moon may provide a means of reducing the cost and risk of lunar exploration and beyond.
+
In a not so distant future, mankind will have established a permanent base on the moon. To fulfil its demand for water, the Earth Space Agency (ESPA) has decided to deploy a fleet of autonomous water-ice mining robots. These robots are designed to first analyze areas for possible water deposits. Detected deposits will be mined, and ice/water will be shipped and stored in the base station. It is a race against time for life and death, because the astronauts are very thirsty.
+ ++Full moon photograph taken 10-22-2010 from Madison, Alabama, USA; CC BY-SA 3.0 +
+ +ESPA has ordered their process specialists to work out a simulation model of the mining process. With the simulation, the number of mining robots needed to supply the base with enough water must be determined. Also, water production rates shall be estimated.
+ESPA simulation engineers have to solve two very typical tasks in industrial engineering
+There is a complex interplay of rate-limited processes (transport, search, mining), limited resources and the harsh realities of deep space. The latter is abstracted away in the model as it does not contribute to model performance
+The complete model definition can be found here. As an example, we inspect the unloading process of water at the base
+fun unload() = sequence {
+ moveTo(base.position)
+
+ val unloadingUnitsPerHours = 20 // speed of unloading
+
+ // unloading time correlates with load status
+ currentState = UNLOADING
+ hold((tank.level / unloadingUnitsPerHours).roundToInt().hours,
+ "Unloading ${tank.level} water units")
+
+ // put the water into the refinery of the base
+ put(get<Base>().refinery, tank.level)
+
+ // empty the tank
+ take(tank, tank.level)
+
+ activate(process = Harvester::harvesting)
+}
+
activate()
.
+A state variable currentState
allows for later analysis about what the robots were doing. Unloading is actually separated over 2 independent resources:
Both are modelled as depletable resource, so they can be consumed and refilled with take()
and put()
respectively.
Once water unloading is complete, another sub-process of the ice harvester is activated: It's going back into harvesting mode, i.e. the robot is returning to its last mined deposit to continue ice collection.
+ ++API surface of the lunar mining simulation model +
+ +The model can be expressed easily in approximately 200 lines of process definitions in LunarMining.kt
. Howvever, it was not initially clear, if the intended dynamics were implemented correctly. Process animation comes to resuce, as it allows to debug of the model vsually.
A process animation was developed as well to better understand the spatio-temporal dynamics of the model. In LunarMiningHQ.kt the animation of this process is worked out in just about 150 lines of code.
+We used different capabilties of the animation system (based on OPENRNDR)
+To assess how many ice harvesters are needed to ensure base survival we can play what-if with our model. We do so in a fully reproducible manner right in place here. First we load kalasim
and import required classes.
@file:Repository("*mavenLocal")
+
+%useLatestDescriptors on
+%use kalasim(0.7.94)
+%use kravis(0.8.4)
+
+@file:DependsOn("org.kalasim.demo:lunar-mining:1.0-SNAPSHOT")
+
+import org.kalasim.demo.moon.*
+import krangl.asDataFrame
+import krangl.bindRows
+
Next we can run the simulation multiple times with different numbers of robots and compare the outcome.
+val sims = List(9) { numHarvesters ->
+ List(100) {
+ LunarMining(numHarvesters+1, 15, false, it).apply { run(60*60) }
+ }
+}.flatten()
+
To work with the data, we first combine the refinery water level timelines into a data-frame.
+val waterSupply = sims.withIndex().map { (idx, sim) ->
+ sim.base.refinery.levelTimeline//.statistics()
+ .stepFun()
+ .asDataFrame()
+ .addColumn("num_harvesters") { sim.harvesters.size }
+ .addColumn("run") { idx }
+}.bindRows()
+
First, we can study the water level in the central refinery across all the 100 simuation runs.
+waterSupply
+ .addColumn("num_harvesters"){
+ it["num_harvesters"].map<Int>{ it.toString()+ " harvesters"}
+ }
+ .plot(x = "time", y = "value", group="run", color="num_harvesters")
+ .geomLine( alpha = .1)
+ .facetWrap("num_harvesters", scales=FacetScales.free_y)
+ .guides(color=LegendType.none)
+
With more ice harvesters working around the base, supply of water is ensured. Initially there is a phase, were no deposits are yet discovererd, so the base is under a severe risk of running dry. To assess how often this happens, we count the number of runs per harvester where the base's refinery was depleted.
+sims.map { sim ->
+ ("h "+sim.harvesters.size) to
+ sim.base.refinery.levelTimeline.statistics().min
+}.plot(x={ first}, fill={second==0.0})
+ .geomBar()
+ .labs(x="# harvesters", y="# simulation runs", fill = "Base Depleted?")
+
As shown in the figure, it turns out, that with >=5 ice harvestering robots, the risk of water supply depletion at the base station is within an acceptable range.
+We have just analyzed our lunar mining model using controlled randomization, and have performed a basic capacity analysis.
+The model could be extended to model robot health as well
+ESPA is relieved. The simulation model showed that sufficient water-supplies can be gathered with 5 mining robots. The astronauts can even take a shower every Sunday from now on.
+Using a discrete event simulation model built with kalasim
, we have animated the process and have analyzed its statistical properties.
After quite some months of exploration, API refinements, countless simulations, and some literature research, we present with great pleasure the next milestone release of kalasim!
+kalasim
v0.7 is not just for engineers, but for process analysts and industrial engineers who need to go beyond the limitations of existing simulation tools to model and optimize their business-critical use-cases. So, we deliberately took some time with this release to gather and analyze feedback from our users.
With this milestone release, we have stabilized the core API considerably, improved its performance dramatically while adding new features all over the place.
+Major enhancements in this release are
+processRepeated
to streamline modelling of reiterating processesComponentList
to provide metrics-enhanced collection similar to the existing ComponentQueue
display()
support API on all major components and their collections (including Resource
, Component
or List<Component>
, MetricTimeline
)See kalasim
's changlog for a complete list of technical changes in the v0.7 milestone release
We've rewritten a large part of the documentation for better readability. In particular, we've focussed on resources and components, which are the key elements of every business process model. A new chapter about collections was added, and the numerous advanced topics were worked out to cover more aspects of the product in much more detail.
+Several new examples were added including the famous Bridge Games. The ATM was rebuilt using a jupyter-notebook example to better illustrate parallelization and the new visualization support API. Finally, we started a new larger scale example simulation to model the interplay of processes in an emergency room.
+Different individuals and organizations made this milestone release possible. Most importantly, we'd like to thank SYSTEMA GmbH for supporting the project. Special thanks go to Ilya Muradyan and Igor Alshannikov from JetBrains for their patience with us and their wonderful support with Kotlin data-science tooling. We like to thank Arnaud Giuliani for providing great koin support and guidance, which is the basement on which we managed to build kalasim
.
Finally, we'd like to thank the wonderful folks at CASUS for providing us the opportunity to introduce kalasim
to a great simulation experts panel.
We're having a packed feature roadmap. On the top of our roadmap are the following ideas
+Please note, that the kalasim
APIs will be subject to breaking changes until a very distant major release.
If you think that kalasim
is missing some important feature, please just let us know.
After some more months of continued refinements, extensions and refactorings, and - for sure - a sightly number of new simulations across different domains and industries, we present with great pleasure the next milestone v0.8 release of kalasim!
+kalasim
v0.8 has matured considerable across the entire API. From a small experimental API it has grown into a battle-tested real-time scalable open-architecture simulation engine, designed not just for engineers, but for business process analysts and industrial engineers who need to go beyond the limitations of existing simulation tools to model and optimize their business-critical use-cases.
With this milestone release, we have further stabilized its core API, improved its performance while adding new features all over the place.
+Major enhancements in this release are
+kotlin.time.Duration
across the entire API. Processes can be expressed much more naturally using time-units:val sim = createSimulation {
+ object : Component() {
+ override fun process() = sequence {
+ hold(3.days)
+ // some action
+ hold(2.minutes)
+ }
+ }
+}
+
+sim.run(3.years)
+
Added new options to model resource honor policies allowing for more configurable request queue consumption +
val r = Resource(honorPolicy = RequestHonorPolicy.StrictFCFS)
+
Added Timeline Arithmetics. It is now possible to perform stream arithmetics on timeline attributes
+val tank = DepletableResource(capacity=100, initialLevel=60)
+
+put(gasSupply, 50, capacityLimitMode = CapacityLimitMode.CAP)
+
AnimationComponent
to streamline rendering. To demonstrate the capabilities, we have worked out several examples such as the moon base and the office tower.Other notable enhancements in this release are a streamlined predicate consumption in wait()
, more supported statistical distributions, improved bottleneck analysis using resource request-ids and RequestScopeContext
in honor block. First community PRs were merged, in particular
+#35 which improved the support for asynchronous event consumption.
For a complete list of technical changes in the v0.8 milestone release check out our change log.
+Several new examples were added as part of this release. First, we explored resource mining on the moon, where we don't just demonstrate how to model a complex mining and logistics operation, but also showcase how to animate this process. In the office tower we explore capacity planning via an interactive UI to size elevators in a busy office building.
+Different individuals and organizations made this milestone release possible. Most importantly, we'd like to thank SYSTEMA GmbH for supporting the project.
+While improving kalasim
, we have dropped some roadmap items sketched out earlier.
org.kalasim.Environment
can be configured to be incompatible on various levels which can't be resolved with a simple +
Next on our roadmap are various open tickets as well as the following meta-tasks
+kotlin.time.Duration
equivalents.Please note, that the kalasim
APIs will be subject to breaking changes until a first major release.
If you think that kalasim
is missing some important feature, please just let us know.
kalasim
will be very present this year at the Winter Simulation Conference 2022 (Singapore, December 11-14, 2022). Feel welcome to reach out to us at the conference to discuss about simulation, kalasim
, process analytics & optimization, or kotlin for data science. We are also ready - and eager - to support you with your simulations written in kalasim
at the conference. We intentionally do not have a physical booth - our booth will just be where we meet you!
As part of the research initiative AISSI, where various partners from industry and academy develop, integrate and apply novel AI-based approaches to bring scheduling to a new level, we have modelled a complex production process with kalasim
. By applying reinforcement learning in a framework for autonomous, integrated production and maintenance scheduling, we strive to outperform classical planning methods wrt critical KPIs such as throughput or due date adherence.
As part of the Modeling and Simulation of Semiconductor Manufactoring track, we - Holger Brandl (lead dev of kalasim), Philipp Rossbach, and Hajo Terbrack from SYSTEMA GmbH and Tobias Sprogies from NEXPERIA Germany GmbH) - will proudly present our analysis of a complex manufacturing process simulation implemented with kalasim
.
++Maximizing Throughput, Due Date Compliance and Other Partially Conflicting Objectives Using Multifactorial AI-powered Optimization
+
For the abstract see here
+kalasim
has grown very quickly from small experimental API into a battle-tested real-time scalable open-architecture next-generation code-first simulation engine, designed not just for engineers, but for business process analysts and industrial engineers who need to go beyond the limitations of existing simulation tools to model and optimize their business-critical use-cases.
If you want to get started with kalasim
, need support, or if you think that some important feature is yet missing, feel welcome to get in touch.