EPS Example Notebook

This notebook shows an example replicating previous the simple electric power system implemented in IBFM in the eps example directory, with some basic fault propagation and visualization.

Copyright © 2024, United States Government, as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.

The “"Fault Model Design tools - fmdtools version 2"” software is 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.
[1]:
from examples.eps.eps import EPS
import fmdtools.sim.propagate as propagate

This script provides some example I/O for using static models, using the EPS system implemented in eps.py as an example.

A graphical representaiton of this system is shown below:

[2]:
mdl= EPS()
mg = mdl.as_modelgraph()
fig, ax = mg.draw()
../../_images/examples_eps_EPS_Example_Notebook_3_0.png

As with dynamic models, in static models we use fp.run_one_fault to see the effects of single faults. All setup is performed in the Model class definition

[3]:
result, mdlhist = propagate.one_fault(mdl, 'ee_to_me', 'toohigh_torque', desired_result="graph")

In this case, however, the output in mdlhists will be a single-dimensional dictionary (not something we can plot very well)

[4]:
fig, ax = mdlhist.plot_line(*mdlhist.nominal.keys())
C:\Users\dhulse\Documents\GitHub\fmdtools\fmdtools\analyze\history.py:776: UserWarning: Attempting to set identical low and high xlims makes transformation singular; automatically expanding.
  ax.set_xlim(min_ind, max_ind)
../../_images/examples_eps_EPS_Example_Notebook_7_1.png

As a result, it’s better to look at the results graph for a visualization of what went wrong. In this case resgraph better represents the fault propagation of the system than in a dynamic model, since there is only one time-step to represent (rather than a set)

[5]:
result.graph.set_edge_labels(title='')
fig, ax = result.graph.draw(figsize=(14,10))
../../_images/examples_eps_EPS_Example_Notebook_9_0.png

We can run the set of single-fault scenarios on this model using fmdtools.sim.propagate.single_faults. For single-fault scenarios, one does not need to use a SampleApproach, since all faults are injected at a single time-step.

[6]:
endclasses, mdlhists = propagate.single_faults(mdl, staged=True)
SCENARIOS COMPLETE: 100%|██████████| 35/35 [00:00<00:00, 57.22it/s]

Using analyze.tabulate.result_summary_fmea, one can see the degradation effects of this fault on the flows:

[7]:
from fmdtools.analyze.tabulate import result_summary_fmea
[8]:
tab = result_summary_fmea(endclasses, mdlhists, *mdl.fxns, *mdl.flows)
tab
[8]:
degraded faulty rate cost expected_cost
import_ee_low_v_t0p0 [] [] 0.00001 700.0 306.6
import_ee_high_v_t0p0 ['me', 'oe', 'he'] [] 0.000005 2100.0 459.9
import_ee_no_v_t0p0 [] [] 0.00001 1550.0 678.9
supply_ee_adverse_resist_t0p0 [] [] 0.000002 1650.0 144.54
supply_ee_minor_overload_t0p0 [] [] 0.00001 5150.0 2255.7
supply_ee_major_overload_t0p0 ['me', 'oe', 'he'] [] 0.000003 2400.0 315.36
supply_ee_short_t0p0 [] [] 0.0 5150.0 22.557
supply_ee_open_circuit_t0p0 [] [] 0.0 1450.0 3.1755
store_ee_low_storage_t0p0 ['me', 'oe', 'he'] [] 0.000005 2000.0 438.0
store_ee_no_storage_t0p0 [] [] 0.000005 3250.0 711.75
import_signal_partial_signal_t0p0 [] [] 0.00001 2000.0 876.0
import_signal_no_signal_t0p0 [] [] 0.000001 2000.0 87.6
distribute_ee_adverse_resist_t0p0 [] [] 0.00001 2750.0 1204.5
distribute_ee_poor_alloc_t0p0 [] [] 0.00002 1750.0 1533.0
distribute_ee_short_t0p0 [] [] 0.00002 4750.0 4161.0
distribute_ee_open_circuit_t0p0 [] [] 0.00003 2750.0 3613.5
ee_to_me_high_torque_t0p0 ['oe', 'he'] [] 0.0001 450.0 1971.0
ee_to_me_low_torque_t0p0 [] [] 0.0001 4950.0 21681.0
ee_to_me_toohigh_torque_t0p0 [] [] 0.00005 5050.0 11059.5
ee_to_me_open_circuit_t0p0 ['oe', 'he'] [] 0.00005 650.0 1423.5
ee_to_me_short_t0p0 [] [] 0.00005 4950.0 10840.5
ee_to_oe_optical_resist_t0p0 ['me', 'he'] [] 0.0 520.0 11.388
ee_to_oe_burnt_out_t0p0 ['me', 'he'] [] 0.000002 550.0 48.18
ee_to_he_low_heat_t0p0 ['me', 'oe'] [] 0.000002 550.0 48.18
ee_to_he_high_heat_t0p0 ['me', 'oe'] [] 0.0 2500.0 10.95
ee_to_he_toohigh_heat_t0p0 [] [] 0.0 5100.0 111.69
ee_to_he_open_circuit_t0p0 ['me', 'oe'] [] 0.0 550.0 2.409
export_he_hot_sink_t0p0 ['me', 'oe'] [] 0.00001 600.0 262.8
export_he_ineffective_sink_t0p0 ['me', 'oe'] [] 0.000005 1500.0 328.5
export_waste_h1_hot_sink_t0p0 ['me', 'oe', 'he'] [] 0.00001 500.0 219.0
export_waste_h1_ineffective_sink_t0p0 ['me', 'oe', 'he'] [] 0.000005 1000.0 219.0
export_waste_ho_hot_sink_t0p0 ['me', 'oe', 'he'] [] 0.00001 500.0 219.0
export_waste_ho_ineffective_sink_t0p0 ['me', 'oe', 'he'] [] 0.000005 1000.0 219.0
export_waste_hm_hot_sink_t0p0 ['me', 'oe', 'he'] [] 0.00001 500.0 219.0
export_waste_hm_ineffective_sink_t0p0 ['me', 'oe', 'he'] [] 0.000005 1000.0 219.0
nominal ['me', 'oe', 'he'] [] 1.0 0.0 0.0