Introduction to JSim Version 2.0

Contents:

  • Compiler Overview
  • Bug fixes in version 2.0
    • No more "Not all tools sequenced" error messages
    • Faster detection of underspecified models and implicit equations
    • Improved ODE & PDE blocking
    • Improved microstep sequencing
    • Improved event sequencing
    • Improved relation sequencing
    • Improved VFC sequencing
    • Improved user diagnostics
    • Expedited bug resolution
  • New features in version 2.0
    • Improved microstep caching
    • Improved event sequencing
    • Nth order ODEs
    • Events for ODE variables
    • Procedures may be used as initial conditions
    • More flexible initial condition and boundary condition specification
    • More flexible domain controls
    • XMML Output
    • Model browser
    • SBML Output
    • Improved variable tracing
    • More consistent integrals
    • More flexible sums
  • Coming features in version 2.0
    • N-dimensional state variables
    • SBML-style events in MML
    • Implicit block declarations in MML
    • 2D & 3D PDE solver support
    • Improved model browser
    • Synchronous run-time support
    • User modifiable run-time variables
    • Steppable API for joint JSim/CFD projects
  • Known bugs in version 2.0

Complier Overview

Some technical understanding of the JSim compiler is helpful in understanding improvements in JSim version 2.0. The compiler consists of 8 phases, each of whose results feeds to the next. The starting point is MML model text. The end point is a JSim model run-time object or an appropriate error message. The compiler phases, in order of execution, are listed below. Phases 4 through 7 were rewritten for version 2.0. The JSim model run-time library (utilized by the runnable model object) has not been changed for initial release, although some changes will be rolled in in the coming months.

# Phase Description
1 Parsing Scans MML text and, based on MML's syntactic rules, creates data structures that comprise the model: units, variables, equations, events, etc.
2 Flattening Reduces templates (BCL items) to flat (mathematical) MML. Currently, this phase affects only a small number of models (XSim and MFAX models).
3 Unit correction If unit conversion is on, checks for unit errors, adds conversion factors to equations and assigns units to variables whose units were not specified in the MML.
4 Tooling Examines equations to figure out how each variable will be calculated (e.g. via an expression, an ODE, an implicit equation). Generates errors for over-specified and under-specified models.
5 Sequencing Places all calculations in proper order so that variables are calculated before they are used. Generates errors for circular dependencies.
6 ODE & PDE blocking Collects ODEs and PDEs into blocks to be solved together, resulting in faster and more accurate calculations than if calculated individually.
7 Java code generation Writes Java code that uses the JSim run-time library to perform model calculations based on the above calculation sequence.
8 Java compilation & instantiation Compiles the generated model Java code using Sun's Java compiler, and creates a model object ready for use within the JSim computational engine.

Bug Fixes in version 2.0

No more "Not all tools sequenced" error messages: This message in version 1.6 indicated that the sequencing phase failed to place all calculations in correct sequence. It was very frustrating to users because the compiler could not give the user specific information as to where the problem was. In most cases, the problem was in the compiler which made internal errors in formulating calculation dependencies. These errors have been corrected in version 2.0. However, the message could also be caused by genuine circular dependencies in model calculations. Version 2.0 contains algorithms to locate such circular dependencies and present them to the user.

Faster detection of underspecified models and implicit equations:In version 1.6, detection of implicit equation blocks was done via an inefficient and exhaustive search of the unprocessed equations. This could take minutes, or even hours, because a system of N equations contains N! possible implicit equation blocks. In practice, blocks of more that 3 implicit equations were rarely found before the compilation timed out. Even worse, every underspecified model made this search, meaning that underspecified models often had very long compilation times, and ended up needing to be canceled by the user. Version 2.0's implicit equation search is much more efficient and, by default, limits itself to 1,000,000 search blocks with a maximum block size of 10 equations. Testing indicates this algorithm performs quickly and accurately for all known MML models, and should enable modelers to use more implicit equations in their models. Even better, this eliminates long compile times for underspecified models. The user may tune the parameters of the implicit search in the case of models needing a larger search space. See also Implicit block declarations in MML.

Improved ODE & PDE blocking: In version 1.6, ODEs and PDEs were blocked before they were sequenced. Version 2.0 performs blocking (phase 6) after sequencing (phase 5). This eliminates one case of the Not all tools sequenced bug above.

Improved microstep sequencing: In version 1.6, variables were sometimes calculated out of order within ODE microsteps. This behaviour was inconsistent, but when it occurred would result in numerical inaccuracy, solver aborts or poor performance. In a case study with Max Neal's VS001 model, calculations were made out of order, but numerical inaccuracy was masked by the use of an adaptive ODE solver. However the resulting numeric instability caused the solver to call the microstep routine about twice as many times, resulting in a doubling of calculation time. This bug is fixed in version 2.0.

Improved event sequencing: In version 1.6, events were sometimes sequenced out of order. This could force modelers to make obscure and seemingly arbitrary hacks to their models for them to run correctly. These problems have been fixed in version 2.0, however event sequencing remains a difficult and subtle subject. More documentation on this will be forthcoming.

Improved relation sequencing: Relations can be used in MML to trigger error conditions so that worthless long model runs can be avoided. In version 1.6, the sequencing algorithm often placed relation tests well after the calculation of a variable, blunting the effectiveness of the mechanism. This has been corrected in version 2.0 where relations are now sequenced immediately after the relevant variable is calculated.

Improved VFC sequencing: Variable function calls (VFCs) are queries to the non-current value of a variable. Two notable uses are for delay lines and data curve interpolation. These two VFCs differ for sequencing purposes. Delay VFCs may be calculated in the same loop as the source variable, while arbitrary query VFCs can only be calculated once the source variable is complete. Version 1.6 did not attempt to distinguish these two cases, often resulting in VFCs returning NaNs. Version 2.0 attempts to recognize delays, and sequence them within the same loop as their source variable. VFC's not recognized as delays are attempted to be sequenced after the source variable loop is complete. If this attempt results in a circular dependency, the VFC is sequenced as a delay and a warning message is issued to inform the user of the situation.

Improved user diagnostics: Generating good error messages, especially for code as complicated as a language compiler, remains a bit of an art, and subject to continuous feedback and review. In general, version 2.0 error messages were improved in the following ways:

  • A systematic review of all error messages was performed.
  • An attempt was made to distinguish internal compiler errors from errors resulting from incorrectly written models.
  • An attempt was made to add line number information to more error messages.
  • Messages regarding circular sequence dependencies (see above) are now much more explicit.
  • Messages relating to underspecified and overspecified models remain difficult to interpret. However, new model dependency graphs are expected to be helpful in these cases.
  • Despite these efforts, we expect users will still express confusion over some error messages. We will continue to work to address these concerns.

Expedited bug resolution: The version 2.0 compiler have a more modular design and contain better internal workings auditing, in hopes of expediting resolution of future bugs. The version 1.6 compiler had been hacked numerous times over the previous 9 years, resulting in code that was exceedingly difficult and time-consuming to debug. Our hope is that future bugs can be resolved much more quickly, but time will tell...

New Features in version 2.0

Improved microstep caching: Version 2.0 does a better job of calculating ODE microstepped variables. For example, under version 1.6, variable a in the following model was not microstepped, leading to less accurate numerical solution:

math main {
        realDomain t, x;
        t.min=0; t.max=3; t.delta=0.25;
        x.min=0; x.max=1; x.delta=0.1;
        real a(t) = t+1;
        real u(t,x);
        when (t=t.min) u=x;
        u:t = a + u;
}

Improved event sequencing: Multiple events in a model can create ambiguous calculation semantics. Version 2 properly sequences unambiguous calculations, and issues warnings about ambiguous calculations. Version 1 did not guarantee proper event sequencing and issued no warnings.

Nth order ODEs: Version 2.0 allows modelers to write Nth order ODEs directly in MML. In version 1.6, modelers needed to explicitly reduce and Nth order ODE to N separate 1st order ODEs. Example usage:

math main {
  realDomain t;
  t.min=0; t.max=2*PI; t.ct=13;
  real u(t);
  when (t=t.min) { u=1; u:t=0; }
  u:t:t = -u;  // 2nd order sinusoidal ODE 
}

Events for ODE variables: Version 2.0 allows events to affect ODE variables. Under version 1.6, events could only affect realState or intState variables. Example usage:

math main {
  realDomain t;
  t.min=0; t.max=5; t.delta=.1;
  real u(t);
  when (t=t.min) u=1;
  u:t = -u;
  event (u<.2) u=1;
}

Procedures may be used as initial conditions: In version 1.6, procedure calls within when clauses were not treated correctly. This problem has been fixed in version 2.0. Example usage:

source procedure double(a; b) {
        language="java";
        reentrant="true";
        maincode={{
            double aval = a.realVal();
            b.set(aval*2);
        }};
}

math main {
        realDomain t;
        t.min=0; t.max=3; t.delta=1;
        real u(t) = t+1;
        real v(t);
        when (t=t.min) double(u, v);
        v:t = -v;
}

More flexible initial condition and boundary condition specification: Under version 1.6, specification of initial and boundary conditions required a "when" clause. When clauses are still supported under version 2.0, but modelers may alternatively use variable function calls (e.g. u(t.min)). This change was made to support future PDE boundary conditions which equate left and right hand boundaries (e.g. u(x.max) = v(x.min)). Example usage:

math main {
        realDomain t;
        t.min=0; t.max=3; t.delta=0.25;
        real u(t);
        u(t.min)=1;
        u:t = u;
}

More flexible domain controls: Under version 1.6, for domain x, specification of domain controls x.min and x.max were required along with one of x.delta and x.ct. Under version 2.0 any 3 domain controls is sufficient. Example usage:

math main {
  realDomain t;
  t.min=0; t.delta=3; t.ct=4;  // t.max=12 will be calculated
}

Also under version 2.0, some domain controls may be left undefined. In this case, a warning message will be issued and the user must specify the control before running the model. Example usage:

math main {
  realDomain t;
  t.min=0; t.delta=1; // t.max must be specified at run-time
}

XMML Output: XMML is an XML representation of a JSim model, designed to export models to modeling and bioinformatics applications. XMML is the underlying technology for JSim model graphs and SBML export. It is also used in Max Neal's SemSim application. See specification in JSim XMML.

Model browser: Version 2.0 implements the model browser, a tool for exploring model structure visually via graphical representations of model dependencies. Initially a very basic version of this concept will be available which be refined and improved upon in the coming months. Browser graphs utilize XMML as a communications medium. In the JSim GUI, a model's browser may be found within the new "Browser" tab. Thanks to Bart Jardine for the model graph implementation. Browser documentation is under development.

SBML Output: Version 2.0 allows you to output MML models as SBML. Since SBML has a small mathematical vocabulary in comparison with MML, this feature works only for a subset of MML models (those with a single domain, ODEs, implicit equations and events). SBML output utilizes XMML as a communications medium. Further documentation of this feature may be found here. Thanks to Lucian Smith for the SBML output implementation.

Improved variable tracing: Version 2.0 implements the -initNaN, -traceNaN, -abortNaN and -traceVars compiler switches in a more efficient way, and a time-point is now provided for microstepped calculation output.

More consistent integrals: In version 2.0, the short and long integral formulations are calculated via an interpolative procedure. Previously, the short form was calculated via an interpolative procedure and the long form via a hidden ODE. Thus I1 and I2 calculate the same under version 2, but not version 1:

math main {
  realDomain t;
  t.min=0; t.max=5; t.delta=1;
  real a(t) = t^2;
  real I1 = integral(a@t); // integral short form
  real I2 = integral(t=t.min to t.max, a); // integral long form
}

New documentation for integrals may be found here.

More flexible sums: Version 2 supports a long form of the sum function analagous to the long form of the integral function:

math main {
  realDomain t;
  t.min=0; t.max=5; t.delta=1;
  real a(t) = t^2;
  real S(t) = sum(t=t.min to t, a);
}

New documentation for sums may be found here.

Coming Features in version 2.0

N-dimensional state variables: Version 2.0 allows multi-domain realState and intState variables. Under version 1.6, state variable had to be 1-dimensional. Example usage:

math main {
  realDomain t, x;
  t.min=0; t.max=10; t.delta=1;
  x.min=0; x.max=1; x.delta=.1;
  realState r(t,x);
  when(t=t.min) r=1;
  event(t>5) r=r+1;
}

SBML-style events in MML: Historically, JSim events and SBML events have differed in their triggering semantics. In JSim, an event is launched whenever its trigger expression evaluates to true. In SBML, an event is launched when it trigger expression becomes true, i.e. on the "rising edge". In the next few months, MML syntax will be expanded to allow the user to designated events with rising edge trigger semantics. At the same time, various other features of SBML events (delays, cancelable events, initial trigger values) will also be implemented. These changes are made possible by fixes to basic event handling in version 2.0.

Implicit block declarations in MML: While version 2.0 has significantly improved detection of implicit equation blocks, it remains an inherently difficult problem. If modelers end up writing large number of implicit equations in their models, it is possible that an explicit MML declaration will be needed for adequate compiler performance. If so, such a declaration might look something like for following:

... lots of model equations ...
implicit {
  a + b + c = 0;
  a^2 - c = 10;
  b + c = 5;
}
... lots more model equations ...

2D & 3D PDE solver support: The tooling and sequencing phases of the version 2.0 compiler now support 2D and 3D PDEs. In order to make such equations available to users, NSR will be implementing run-time numeric methods to solve such problems. As with current 1D PDE solvers, implementation of such methods will be an ongoing process in JSim development.

Improved model browser: The initial release of version 2.0 will include a fairly minimal implementation of the model browser. The graphs will be refined and improved based on user feedback as part of the ongoing process of JSim development. Bart Jardine will be primarily responsible for this development. Below are some example graphs from a prototype by Gary Yngve, which illustrate where we're headed:

Synchronous run-time support: Currently, the JSim computational engine runs asynchronously from the user interface. This methodology provides buffering for high performance. However, there are some scenarios that would be better served by synchronous operation, that is, a lock step between the computational engine and user interface. Now that underlying changes have been made in the version 2.0 compiler, it will now be possible to provide a synchronous run-time option, thus enabling three functionality targets: improved SBW support, user modifiable run-time variables and a steppable API for joint JSim/CFD projects. See below.

Improved SBW support: With a synchronous run-time available JSim will be able to function within SBW as "simulator". Currently, JSim functions in SBW only as an "analyzer". Also, with SBML output available, JSim will also be able to function as an SBW "editor".

User modifiable run-time variables: With a synchronous run-time available, it will be possible for users to modify some model variables during the course of a model run. In particular, time-variable inputs and ODE state variables should be modifiable.

Steppable API for joint JSim/CFD projects: With a synchronous run-time available, a synchronous API will allow program driven intra-run interaction with external programs. In particular, this functionality will support joint JSim/CFD (computational fluid dynamics) models now under development.

Known bugs in version 2.0

The following bugs are not yet resolved. However, we continue to work on them:

3 of 5000 tested models generate spurious error messages that were not generated in version 1.

7 of 5000 tested models take a long time to compile - about 90 seconds on the NSR server (gloin).

Event warnings are sometimes generated unnecessarily. For example, the fibonacci calculation:

math main {
  realDomain n;
  n.min=1; n.max=10; n.delta=1;
  intState f(n);
  when (n=n.min) f=1;
  event (n>2) f = f(n-1) + f(n-2);
}

Comments or Questions?

Give feedback

Model development and archiving support at https://www.imagwiki.nibib.nih.gov/physiome provided by the following grants: NIH U01HL122199 Analyzing the Cardiac Power Grid, 09/15/2015 - 05/31/2020, NIH/NIBIB BE08407 Software Integration, JSim and SBW 6/1/09-5/31/13; NIH/NHLBI T15 HL88516-01 Modeling for Heart, Lung and Blood: From Cell to Organ, 4/1/07-3/31/11; NSF BES-0506477 Adaptive Multi-Scale Model Simulation, 8/15/05-7/31/08; NIH/NHLBI R01 HL073598 Core 3: 3D Imaging and Computer Modeling of the Respiratory Tract, 9/1/04-8/31/09; as well as prior support from NIH/NCRR P41 RR01243 Simulation Resource in Circulatory Mass Transport and Exchange, 12/1/1980-11/30/01 and NIH/NIBIB R01 EB001973 JSim: A Simulation Analysis Platform, 3/1/02-2/28/07.