Skip to content

Analyses

In Dyad, an analysis is "the things you can do with a model". A typical workflow in Dyad is to create a set of components, and then create an analysis that runs on the entry point to that set of components. It produces a solution object that provides information about the model, and can be used to build various visualizations.

Analyses can perform a wide variety of model analytics, such as:

  • Simulate the model over a given time span

  • Analyze the stability of a controller

  • Run a parameter sweep

  • Build an FMU

  • Calibrate the model to data

and much more. All analyses have a common interface which take in the model, run an analysis, and give back a pre-defined set of artifacts, such as plots of the solution or generated binaries.

Using the Julia-Level Analysis Interface (Dyad Studio)

Dyad Studio includes a lower level interface to define and interact with analyses at the Julia level, with more flexibility than what is exposed in the GUI.

Example: TransientAnalysis of a Simple Block

Using the Dyad-Level Analysis Interface (Dyad Studio)

A TransientAnalysis for the SecondOrderSystemTest component is written in Dyad as:

dyad
analysis SecondOrderSystemTransient
  extends TransientAnalysis(stop=5)
  model = DyadExampleComponents.SecondOrderSystemTest()
end

The Dyad compiler will generate the SecondOrderSystemTransient function that will run the analysis.

julia
result = SecondOrderSystemTransient()
Transient Analysis Solution for TransientAnalysis
retcode: Success
Interpolation: 3rd order Hermite
t: 91-element Vector{Float64}:
 0.0
 9.999999999999999e-5
 0.0010999999999999998
 0.008325009772234456
 0.020994176283791393
 0.0364343358670688
 0.05674523514445098
 0.08286989819734197
 0.11221638932307687
 0.14642347979835246

 4.531377144933996
 4.600395661887067
 4.658489156486032
 4.717039575802435
 4.797097378344955
 4.853010164393907
 4.913798996999781
 4.986904078860146
 5.0
u: 91-element Vector{Vector{Float64}}:
 [0.0, 0.0]
 [1.570795034867126e-7, 5.235985172127158e-12]
 [1.9004744117386418e-5, 6.96868358226933e-9]
 [0.0010824613825442051, 3.010699496947032e-6]
 [0.006676004188171907, 4.740719263845825e-5]
 [0.018672260214054187, 0.00023715849108202821]
 [0.03852585131045319, 0.0008157098034480075]
 [0.05916280060463827, 0.0021185079283594587]
 [0.06134638493866648, 0.003951352196806262]
 [0.03540013662961773, 0.005667636390935834]

 [0.04952985663058974, 0.14529342452097024]
 [0.000127935674026706, 0.14663964118144118]
 [0.04034155170192192, 0.14753118116840172]
 [0.05933195621751569, 0.15089699947601312]
 [0.0002772715611076463, 0.1530273856659445]
 [0.03497875213568734, 0.15371414368230196]
 [0.06086038742068811, 0.15709298444433004]
 [0.0028132618482891642, 0.15940880929987014]
 [0.00015708255353278367, 0.15942252727283682]

We can plot this result, using either Plots.jl or Makie.jl. We'll use Plots here:

julia
using Plots
plot(result)

See the plotting guide for more details on how to plot the results of an analysis.

We can also get artifacts from this result, like:

julia
using DyadInterface: artifacts
artifacts(result, :SimulationSolutionTable)
91×3 DataFrame
Rowtimestampsys₊integrator1₊x(t)sys₊integrator2₊x(t)
Float64Float64Float64
10.00.00.0
20.00011.5708e-75.23599e-12
30.00111.90047e-56.96868e-9
40.008325010.001082463.0107e-6
50.02099420.0066764.74072e-5
60.03643430.01867230.000237158
70.05674520.03852590.00081571
80.08286990.05916280.00211851
90.1122160.06134640.00395135
100.1464230.03540010.00566764
110.1848290.003547460.0063481
120.2243830.00889080.00643985
130.2648340.04613330.00752472
140.3105680.06192370.010216
150.3622190.01991110.0124693
160.4111880.001947390.0127396
170.4661720.04731510.0139535
180.5164670.05949610.016941
190.5805880.005743390.0190607
200.6327960.01545590.0192735
210.68720.06112550.021478
220.7453740.03644670.0247294
230.8038780.0002425720.0254656
240.8619630.04351710.0264955
250.9171980.05913180.029718
260.9897320.001658130.0318257
271.044380.02625460.0322472
281.102220.0635980.0351578
291.166470.01610930.0380138
301.223940.008604950.038271
311.291230.06247280.0408316
321.349450.03239370.0439749
331.41240.002401110.0445805
341.475510.05470860.0462708
351.533630.04750530.0497086
361.601133.67886e-50.0509386
371.659830.04151780.0518786
381.718180.05862260.0552505
391.797370.0001422580.057305
401.853420.03527370.0579998
411.914010.06066150.0613702
421.986760.002759270.0636649
432.044030.02593630.0640852
442.103120.06355080.0670641
452.169240.01379130.069906
462.227430.01115710.0701579
472.289310.06192770.0725662
482.349580.03230350.0758348
492.411290.002030850.0764362
502.474360.05392750.0780685
512.532110.04884070.0814976
522.600615.63697e-50.0828028
532.658910.04067610.0837072
542.717390.0590740.0870724
552.797280.0001859430.0891758
562.853220.03511140.0898656
572.913960.06071540.0932425
582.987050.002679760.0955432
593.044340.02627690.0959729
603.103550.06354140.0989733
613.169940.01325610.1018
623.228120.01171990.102052
633.2890.061860.104435
643.349570.03234410.107725
653.411020.001974550.108329
663.474020.05371420.109945
673.531660.04925570.113373
683.600489.09425e-50.114703
693.658660.04046660.115599
703.717180.05922060.118964
713.797290.0002219380.121083
723.853210.03513840.121774
733.914010.06073180.125157
743.98730.002620810.127458
754.044590.02656070.127896
764.103880.06354150.130912
774.170440.01289220.133727
784.228610.01213320.133981
794.288810.06183430.136349
804.34960.03235850.139654
814.410850.00195650.140258
824.473810.05359740.141866
834.531380.04952990.145293
844.60040.0001279360.14664
854.658490.04034160.147531
864.717040.0593320.150897
874.79710.0002772720.153027
884.853010.03497880.153714
894.91380.06086040.157093
904.98690.002813260.159409
915.00.0001570830.159423

For the artifacts allowed for a given analysis, see the pages which define the given analysis.

Defining and Running an Analysis

Any analysis is available and meant to run in Julia. For an analysis called MyAnalysis in Dyad, the generated Julia code will be created with the following format:

julia
result = MyAnalysis(; kwargs...)

where the kwargs are keyword arguments corresponding to the arguments of the analysis run definition (i.e. the fields that can be set at the Dyad level). This invocation will be set to automatically have the keyword arguments default to the values defined in the Dyad version, for example for a TransientAnalysis if one had set stop = 10.0, then stop = 10.0 will be the default value in the generated function. These defaults can thus be overruled by declaring the keyword argument, for example MyAnalysis(; stop=20.0) will run a version of the analysis which overrides the stop time to 20.0.

Analysis Result Interface

The analysis results can be interacted with in two ways: there are the customizable plot and the artifacts. The most basic usage is to get the artifacts via:

julia
artifacts(result, name::Symbol)

The allowed artifacts can be queried via:

julia
artifacts(results)

which returns a list of all the available artifact names. For more details about all the artifacts,

julia
AnalysisSolutionMetadata(result)

can be used, which also includes descriptions for all the artifacts.

Additionally, some analyses include a customizable visualization:

julia
customizable_visualization(::AbstractAnalysisSolution, ::PlotlyVisualizationSpec)

This will be defined fully in future versions.

Defining Your Own Analysis

At the lowest level, analyses are implemented in Julia, see the Custom analysis tutorial for more details on how to write your own.