packages = ["numpy", "matplotlib", "pysd", "pandas",]
PyML with PySD System Dynamics Demonstrations
These introductory models can be edited and run with the green play buttons. The PyML function names are tentative. See GitHub for the latest PyML library and future examples at pyml.fun.
source = "# netCDF4"
with open('netCDF4.py', 'w') as f: f.write(source)
target = "sim_output"
import pysd
import matplotlib.pyplot as plot
import matplotlib as mpl
mpl.rcParams['axes.spines.top'] = False
mpl.rcParams['axes.spines.right'] = False
def model_init(start, stop, dt):
global xmile_header, model, model_specs
xmile_header = f"""
Ray Madachy
Battle Simulator
PyML .20 dev
"""
model_specs = f"""
{stop}
{start}
{dt}
"""
model = ""
build_model()
def add_stock(name, initial, inflows=[], outflows=[]):
global model
inflow_string, outflow_string = "", ""
for flow in inflows:
inflow_string += f""""{flow}""""
for flow in outflows:
outflow_string += f""""{flow}""""
model += f"""
{name}
{inflow_string}
{outflow_string}
{initial}
"""
build_model()
def add_flow(name, equation):
global model
model += f"""
{name}
{equation}
"""
build_model()
def add_auxiliary(name, equation):
global model
model += f"""
{name}
{equation}
"""
build_model()
def build_model():
global xmile_string
xmile_closing = """
"""
model_string = """
""" + f"{model}" + """
"""
xmile_string = xmile_header + model_specs + model_string + xmile_closing
with open('test.xmile', 'w') as f:
f.write(xmile_string)
def model_run():
import pysd
global output
model = pysd.read_xmile('./test.xmile')
output = model.run(progress=False)
return(output)
PyScript.write(target, output, append=True)
def plot_output(*outputs):
pyscript.write('sim_output', '', append=False)
global fig
for var in outputs:
fig, axis = plot.subplots(figsize=(5, 4))
axis.set(xlabel = 'Time', ylabel = var)
axis.plot(output.index, output[var].values, label=var)
axis.legend(loc="best", )
# plot.show()
pyscript.write('sim_output', fig, append=True)
def plot_output2(*outputs):
pyscript.write('sim_output2', '', append=False)
global fig
for var in outputs:
fig, axis = plot.subplots(figsize=(5, 4))
axis.set(xlabel = 'Time', ylabel = var)
axis.plot(output.index, output[var].values, label=var)
axis.legend(loc="best", )
# plot.show()
pyscript.write('sim_output2', fig, append=True)
target = "sim_output"
def sim():
pyscript.write('plot', '', append=False)
pyscript.write('sim_output', '', append=False)
# Battle Simulator using Lanchester's Law for Aimed Fire
model_init(start=0, stop=1.5, dt=.2)
add_stock("x", 1000, outflows=["x_attrition"])
add_flow("x_attrition", "y*y_lethality")
add_auxiliary("x_lethality", .8)
add_stock("y", 800, outflows=["y_attrition"])
add_flow("y_attrition", "x*x_lethality")
add_auxiliary("y_lethality", .9)
model_run()
plot_output('x', 'y')
# Rayleigh curve staffing model
model_init(start=0, stop=6, dt=.2)
add_stock("cumulative_effort", 0, inflows=["effort rate"])
add_flow("effort rate", "learning_function * (estimated_total_effort - cumulative_effort)")
add_auxiliary("learning_function", "manpower_buildup_parameter * time")
add_auxiliary("manpower_buildup_parameter", .5)
add_auxiliary("estimated_total_effort", 15)
model_run()
plot_output2('cumulative_effort', 'effort rate', "learning_function")
sim()
# Battle Simulator using Lanchester's Law for Aimed Fire
model_init(start=0, stop=1.5, dt=.2)
add_stock("x", 1000, outflows=["x_attrition"])
add_flow("x_attrition", "y*y_lethality")
add_auxiliary("x_lethality", .8)
add_stock("y", 800, outflows=["y_attrition"])
add_flow("y_attrition", "x*x_lethality")
add_auxiliary("y_lethality", .9)
model_run()
plot_output('x', 'y')
# Rayleigh curve staffing model
model_init(start=0, stop=6, dt=.2)
add_stock("cumulative_effort", 0, inflows=["effort rate"])
add_flow("effort rate", "learning_function * (estimated_total_effort - cumulative_effort)")
add_auxiliary("learning_function", "manpower_buildup_parameter * time")
add_auxiliary("manpower_buildup_parameter", .5)
add_auxiliary("estimated_total_effort", 15)
model_run()
plot_output2('cumulative_effort', 'effort rate', "learning_function")