How the Simulator Works
If you want to learn how to use the simulator, take a look at this tutorial.
Let's discuss how simulation models run inside Flux.
First of all, Flux comes with a built-in, state of the art programmable electronics simulator. Electronic circuit simulation software has been around since at least the mid 70s in form of SPICE and there is an ocean of open-source successors available today. Yet electronic circuit simulation hasn't found ubiquitous application because it's challenging to build the simulation models that define the behavior of each electrical component (e.g. a resistor).
So how does this state of the art programmable electronics simulator work you ask? For those interested in the specifics of the core simulation engine we recommend reading Electronic Circuit and System Simulation Methods. In short, our simulator is based on a n*n matrix that computes the simulation outputs for us. Unlike software, electronic circuits are non sequential so imagine this like a giant spreadsheet that contains a flattened version of your circuit including all the nested sub circuits and so on that solves the equation that is your circuit and provides us with voltages/currents at any intersection of the circuit over time.
What's especially cool about using such a matrix is that we can run it on the consumer grade GPU inside the computer you are using right now. A GPU is a chip thats essentially designed for high performance matrix computation and is extremely well suited for this kind of workload, so you can simulate huge circuits in realtime on your client.
Now that's all nice you say, but I have never heard about matrix computation and neither do I want to get into it. We've got good news for you: You don't have to worry about all this! We build an abstraction layer on top of the core simulation engine with a really simple API that lets anyone without a math PhD build models for the parts they need in their circuits.
Another key advantage of this abstraction layer is that it allows us to run your models in a secure sandbox so that you can share your models and use other people's models without having to worry about security aspects of running third party code on your machine.
We hope that this will enable the birth of a huge part simulation model ecosystem of unprecedented granularity and fidelity.

The way the abstraction layer works is that we provide simulation model primitives such as resistor, diode, transistor on top of which you can build your own complex models.
An example for simple resistor:
// listen to the simulation setup event
flux.on("setup", (event) => {
flux.simulationModel = {
type: "resistor", // The type of model we want to set
resistance: 1000, // The resistance of the resistor
map_input_to_terminal_uid: "1e5f31d6-2e01-427f-18b7-c4661ce4f0d2", // map the terminals
map_output_to_terminal_uid: "d6839958-464a-22d4-c933-293fecbddc1c", // map the terminals
};
});
Now lets do something more interesting and change the resistance with the tolerance over time:
const tolerance = 1; // tolerance in percent
// listen to the simulation setup event
flux.on("setup", (event) => {
flux.simulationModel = {
type: "resistor", // The type of model we want to set
resistance: applyTolerance(1000, tolerance), // The resistance of the resistor
map_input_to_terminal_uid: "1e5f31d6-2e01-427f-18b7-c4661ce4f0d2", // map the terminals
map_output_to_terminal_uid: "d6839958-464a-22d4-c933-293fecbddc1c", // map the terminals
};
});
// register a event that fires before every simulation step
flux.on("beforeStep", (event) => {
flux.simulationModel = {
resistance: applyTolerance(1000, tolerance), // The resistance of the resistor
};
});
// apply a random tolerance within spec
function applyTolerance(resistance: number, tolerance: number) {
const max = tolerance;
const min = -tolerance;
const randomTolerance = (Math.random() * (max - min) + min) / 100;
return resistance * (1 - randomTolerance)
}
As you can see its super easy to leverage the primitives we provide to build complex and time based models.
High Frequency Circuits
This simulator simulates the circuit using a series of short time steps. In each step the changes to the voltages and currents in the circuit are calculated based on the component models and the current circuit state. For this process to work the time steps used need to be significantly shorter than the duration of any event of interest in the circuit. Or, if you prefer, the time steps need to be significantly shorter than the period of the highest frequency signal of interest.
By default the simulator uses a 5µs step size. This is OK for audio frequency signals but not for radio frequency signals or fast digital signals. The step size can be changed from the "Simulator" panel in the document inspector.
The step size shouldn't be confused with the "Simulation Speed" controlled by the slider in the same panel. The step size controls how long (in simulated time) each step is. The "Simulation Speed" slider controls how often (in real time) the computer calculates a step.
What's important to know here for your own part models is to use simulator time, not real world time.
Example
flux.on("beforeStep", (event) => {
const maxVoltage = 5;
const dcOffset = 0;
const frequency = 40;
const phaseShift = 0;
// This is the meat (unless you are vegan)
// We are grabbing .step and .step_size_time from the callback and
// dividing them to get the current simulation time in ms
const time = (event.step * event.step_size_time) / 1000;
// Lets calculate a sine wave
const wave = 2 * Math.PI * (time + phaseShift) * frequency;
const voltage = (Math.sin(wave) * maxVoltage) + dcOffset;
flux.simulationModel = {
type: "voltageSource",
voltage: voltage,
map_anode_to_terminal_uid: anodeTerminalElement?.uid,
map_cathode_to_terminal_uid: cathodeTerminalElement?.uid,
};
});
Caveats
Physics simulations are not real life, and don't assume that simulation and reality are necessarily identical! It's easy to built part models that idealize their real world counterparts. Wires and component leads have no resistance. Voltage sources are ideal - they will try and supply infinite current if you let them. Capacitors and inductors are 100% efficient. Logic gate inputs draw zero current - not too bad as an approximation for CMOS logic, but not typical of 1980s TTL for example.
It's on you and the community to provide as accurate as possible models for parts!
And until we have perfect virtual representations of all parts, by all means use this simulator to help design, debug and visualize circuits, but always test in reality.
Sorry to break it to you folks, but the simulator numerically approximates models of components that are also approximate. Even without allowing for any bugs it is just a rough guide to reality. This simulator may be helpful for visualization, but used the wrong way any simulator can give a false sense of security. Some people don't really grasp this important concept - I've even had one user accuse the simulator of "lying" because he (or she) didn't take account of the component idealizations and didn't understand the actual performance of the components they chose to use. It's a key learning for all electronic engineers that they must always be fully aware of real-world component (and system) characteristics and how these differ from any particular simulator they use.