Fixed some bugs
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
model m_Test
|
||||
model m_Constant0
|
||||
output Real y(quantity="Length", unit="m");
|
||||
parameter Real v = 2;
|
||||
equation
|
||||
y = v;
|
||||
end m_Constant0;
|
||||
model m_Gain0
|
||||
input Real u;
|
||||
output Real y;
|
||||
parameter Real k(quantity="Current", unit="A") = 2.5;
|
||||
equation
|
||||
y = k*u;
|
||||
end m_Gain0;
|
||||
m_Constant0 Constant0;
|
||||
m_Gain0 Gain0;
|
||||
equation
|
||||
Gain0.u = Constant0.y;
|
||||
annotation(
|
||||
experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002));
|
||||
end m_Test;
|
||||
@@ -25,8 +25,6 @@ def infer_causality(component: dict[str, Any], toplevel: bool = True) -> dict[st
|
||||
"""
|
||||
|
||||
if toplevel:
|
||||
log.info("Causality inference")
|
||||
|
||||
# Reset causalities
|
||||
reset_causality(component)
|
||||
|
||||
@@ -61,7 +59,13 @@ def infer_causality(component: dict[str, Any], toplevel: bool = True) -> dict[st
|
||||
|
||||
|
||||
|
||||
# Soft choices
|
||||
# Soft choices may need several passes when a junction has multiple
|
||||
# unresolved bonds. Stop as soon as a pass makes no further progress.
|
||||
while True:
|
||||
unresolved_before = sum(
|
||||
con.get('type') == 'power' and con.get('causality', 'none') == 'none'
|
||||
for con in graph.get('connections', [])
|
||||
)
|
||||
for block in graph.get("blocks", []):
|
||||
for port in block.get('interface', {}).get('ports', []):
|
||||
if port.get('type', '') != 'power':
|
||||
@@ -72,9 +76,23 @@ def infer_causality(component: dict[str, Any], toplevel: bool = True) -> dict[st
|
||||
propagate_from_port(block, port, 'effort out', graph, id_list)
|
||||
elif port.get('causality', 'indifferent') == 'likes flow out':
|
||||
propagate_from_port(block, port, 'flow out', graph, id_list)
|
||||
elif port.get('causality', 'indifferent') in ['indifferent', 'single flow in', 'single effort in']:
|
||||
elif port.get('causality', 'indifferent') == 'single effort in':
|
||||
evaluate_junction_constraints(block, port, graph, id_list)
|
||||
if not is_port_fully_assigned(block, port, graph):
|
||||
propagate_from_port(block, port, 'flow out', graph, id_list)
|
||||
elif port.get('causality', 'indifferent') == 'single flow in':
|
||||
evaluate_junction_constraints(block, port, graph, id_list)
|
||||
if not is_port_fully_assigned(block, port, graph):
|
||||
propagate_from_port(block, port, 'effort out', graph, id_list)
|
||||
elif port.get('causality', 'indifferent') == 'indifferent':
|
||||
# Force an arbitrary assignment on the first unassigned bond connected to this port
|
||||
propagate_from_port(block, port, 'effort out', graph, id_list)
|
||||
unresolved_after = sum(
|
||||
con.get('type') == 'power' and con.get('causality', 'none') == 'none'
|
||||
for con in graph.get('connections', [])
|
||||
)
|
||||
if unresolved_after == 0 or unresolved_after >= unresolved_before:
|
||||
break
|
||||
|
||||
# Last check
|
||||
for con in graph.get('connections', []):
|
||||
|
||||
@@ -80,6 +80,7 @@ def emit_model(
|
||||
id_list: dict[str, Any],
|
||||
indent: int = 0,
|
||||
connection_counts: dict[str, int] | None = None,
|
||||
connection_signs: dict[str, list[float]] | None = None,
|
||||
) -> str:
|
||||
"""Emit a component and its nested definitions as Modelica source."""
|
||||
|
||||
@@ -92,16 +93,31 @@ def emit_model(
|
||||
implementation_kind = implementation.get("kind")
|
||||
nested_graph = implementation.get("graph", {})
|
||||
port_counts = connection_counts or _interface_connection_counts(graph)
|
||||
macros = _port_count_macros(graph, port_counts)
|
||||
port_signs = connection_signs or _interface_connection_signs(graph)
|
||||
macros = _port_connection_macros(graph, port_counts, port_signs)
|
||||
|
||||
if indent == 0 and _contains_power_port(graph):
|
||||
lines.extend(
|
||||
(
|
||||
f"{body_indent}connector BondPort \"Bond graph power port\"",
|
||||
f"{body_indent}\tReal e \"Effort variable\";",
|
||||
f"{body_indent}\tflow Real f \"Flow variable\";",
|
||||
f"{body_indent}end BondPort;",
|
||||
)
|
||||
)
|
||||
|
||||
if implementation_kind == "graph":
|
||||
for block in nested_graph.get("blocks", []):
|
||||
block_counts, block_signs = _block_connection_data(
|
||||
nested_graph, block["id"]
|
||||
)
|
||||
lines.extend(
|
||||
emit_model(
|
||||
block,
|
||||
{},
|
||||
indent + 1,
|
||||
_block_connection_counts(nested_graph, block["id"]),
|
||||
block_counts,
|
||||
block_signs,
|
||||
)
|
||||
.rstrip()
|
||||
.splitlines()
|
||||
@@ -157,7 +173,9 @@ def emit_model(
|
||||
target = _endpoint_expression(
|
||||
connection["target"], graph, blocks, junctions, endpoint_indices
|
||||
)
|
||||
# Connector types may require different equations in future.
|
||||
if connection.get("type") == "power":
|
||||
lines.append(f"{body_indent}connect({source}, {target});")
|
||||
else:
|
||||
lines.append(f"{body_indent}{target} = {source};")
|
||||
else:
|
||||
initial_equations = str(
|
||||
@@ -213,10 +231,14 @@ def cleanup_graph(graph: dict[str, Any]) -> dict[str, Any]:
|
||||
def _port_declaration(
|
||||
port: dict[str, Any], direction: str, indent: int, macros: dict[str, str]
|
||||
) -> str:
|
||||
port_type = modelica_type(port.get("valueType", "real"))
|
||||
indentation = "\t" * indent
|
||||
port_name = identifier(port["name"])
|
||||
dimensions = _port_dimensions(port, port_name)
|
||||
if port.get("type") == "power":
|
||||
return expand_bevalues(
|
||||
f"{indentation}BondPort {port_name}{dimensions};", macros
|
||||
)
|
||||
port_type = modelica_type(port.get("valueType", "real"))
|
||||
attributes = _quantity_unit_attributes(port)
|
||||
declaration = (
|
||||
f"{indentation}{direction} {port_type} {port_name}{dimensions}{attributes};"
|
||||
@@ -299,16 +321,21 @@ def _index_array_endpoint(
|
||||
return f"{expression}[{endpoint_indices[key]}]"
|
||||
|
||||
|
||||
def _block_connection_counts(
|
||||
def _block_connection_data(
|
||||
graph: dict[str, Any], block_id: str
|
||||
) -> dict[str, int]:
|
||||
) -> tuple[dict[str, int], dict[str, list[float]]]:
|
||||
counts: dict[str, int] = {}
|
||||
signs: dict[str, list[float]] = {}
|
||||
for connection in graph.get("connections", []):
|
||||
for endpoint in (connection.get("source", {}), connection.get("target", {})):
|
||||
for endpoint, sign in (
|
||||
(connection.get("source", {}), -1.0),
|
||||
(connection.get("target", {}), 1.0),
|
||||
):
|
||||
if endpoint.get("block") == block_id and endpoint.get("port"):
|
||||
port_id = endpoint["port"]
|
||||
counts[port_id] = counts.get(port_id, 0) + 1
|
||||
return counts
|
||||
signs.setdefault(port_id, []).append(sign)
|
||||
return counts, signs
|
||||
|
||||
|
||||
def _interface_connection_counts(component: dict[str, Any]) -> dict[str, int]:
|
||||
@@ -324,19 +351,56 @@ def _interface_connection_counts(component: dict[str, Any]) -> dict[str, int]:
|
||||
return counts
|
||||
|
||||
|
||||
def _port_count_macros(
|
||||
component: dict[str, Any], connection_counts: dict[str, int]
|
||||
def _interface_connection_signs(component: dict[str, Any]) -> dict[str, list[float]]:
|
||||
implementation = component.get("implementation", {})
|
||||
if implementation.get("kind") != "graph":
|
||||
return {}
|
||||
signs: dict[str, list[float]] = {}
|
||||
for connection in implementation.get("graph", {}).get("connections", []):
|
||||
for endpoint, sign in (
|
||||
(connection.get("source", {}), -1.0),
|
||||
(connection.get("target", {}), 1.0),
|
||||
):
|
||||
port_id = endpoint.get("interface")
|
||||
if port_id:
|
||||
signs.setdefault(port_id, []).append(sign)
|
||||
return signs
|
||||
|
||||
|
||||
def _port_connection_macros(
|
||||
component: dict[str, Any],
|
||||
connection_counts: dict[str, int],
|
||||
connection_signs: dict[str, list[float]],
|
||||
) -> dict[str, str]:
|
||||
macros: dict[str, str] = {}
|
||||
interface = component.get("interface", {})
|
||||
for port in interface.get("ports", []):
|
||||
if port.get("multipleConnections", False):
|
||||
macros[f"{identifier(port['name'])}_N"] = str(
|
||||
connection_counts.get(port["id"], 0)
|
||||
)
|
||||
macro_name = identifier(port["name"])
|
||||
port_id = port["id"]
|
||||
macros[f"{macro_name}_N"] = str(connection_counts.get(port_id, 0))
|
||||
signs = connection_signs.get(port_id, [])
|
||||
macros[f"{macro_name}_S"] = "{" + ", ".join(
|
||||
f"{sign:.1f}" for sign in signs
|
||||
) + "}"
|
||||
return macros
|
||||
|
||||
|
||||
def _contains_power_port(component: dict[str, Any]) -> bool:
|
||||
if any(
|
||||
port.get("type") == "power"
|
||||
for port in component.get("interface", {}).get("ports", [])
|
||||
):
|
||||
return True
|
||||
implementation = component.get("implementation", {})
|
||||
if implementation.get("kind") != "graph":
|
||||
return False
|
||||
return any(
|
||||
_contains_power_port(block)
|
||||
for block in implementation.get("graph", {}).get("blocks", [])
|
||||
)
|
||||
|
||||
|
||||
def expand_bevalues(text: str, values: dict[str, str]) -> str:
|
||||
"""Replace BEdit ``$name$`` macros and reject unresolved composer values."""
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import socket
|
||||
@@ -54,6 +56,7 @@ class ModelBuildResult:
|
||||
|
||||
check_summary: str
|
||||
build_result: Any
|
||||
diagnostics: str = ""
|
||||
|
||||
|
||||
class OpenModelicaInterface:
|
||||
@@ -100,6 +103,12 @@ class OpenModelicaInterface:
|
||||
"""Load and build one composed model as an ordered worker operation."""
|
||||
|
||||
def operation(omc, _temp_dir: Path):
|
||||
capture = _LogCapture()
|
||||
ompython_logger = logging.getLogger("OMPython")
|
||||
previous_propagate = ompython_logger.propagate
|
||||
ompython_logger.addHandler(capture)
|
||||
ompython_logger.propagate = False
|
||||
try:
|
||||
unit_checking = omc.sendExpression(
|
||||
'setCommandLineOptions("--unitChecking")'
|
||||
)
|
||||
@@ -108,13 +117,28 @@ class OpenModelicaInterface:
|
||||
loaded = omc.sendExpression(f"loadString({json.dumps(model)})")
|
||||
if loaded is not True:
|
||||
raise RuntimeError("OpenModelica could not load the composed model")
|
||||
diagnostics = [_read_omc_diagnostics(omc)]
|
||||
check_summary = omc.sendExpression(f"checkModel({model_name})")
|
||||
diagnostics.append(_read_omc_diagnostics(omc))
|
||||
if not isinstance(check_summary, str) or not check_summary.strip():
|
||||
raise RuntimeError(
|
||||
"OpenModelica did not return a model-check summary"
|
||||
)
|
||||
build_result = omc.sendExpression(f"buildModel({model_name})")
|
||||
return ModelBuildResult(check_summary, build_result)
|
||||
raw_build_result = omc.sendExpression(
|
||||
f"buildModel({model_name})", parsed=False
|
||||
)
|
||||
build_result = _parse_modelica_string_array(raw_build_result)
|
||||
diagnostics.append(_read_omc_diagnostics(omc))
|
||||
diagnostics.extend(capture.messages)
|
||||
diagnostic_text = "\n".join(
|
||||
item.strip()
|
||||
for item in diagnostics
|
||||
if isinstance(item, str) and item.strip()
|
||||
)
|
||||
return ModelBuildResult(check_summary, build_result, diagnostic_text)
|
||||
finally:
|
||||
ompython_logger.removeHandler(capture)
|
||||
ompython_logger.propagate = previous_propagate
|
||||
|
||||
self._submit("build model", operation, callback, error_callback)
|
||||
|
||||
@@ -266,6 +290,51 @@ class OpenModelicaInterface:
|
||||
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||
|
||||
|
||||
def _read_omc_diagnostics(omc) -> str:
|
||||
"""Read OMC diagnostics without sending multiline text through OMPython's parser."""
|
||||
|
||||
raw = omc.sendExpression("getErrorString()", parsed=False)
|
||||
if isinstance(raw, bytes):
|
||||
raw = raw.decode("utf-8", errors="replace")
|
||||
if not isinstance(raw, str):
|
||||
return ""
|
||||
text = raw.strip()
|
||||
if not text:
|
||||
return ""
|
||||
try:
|
||||
decoded = json.loads(text)
|
||||
except json.JSONDecodeError:
|
||||
return text
|
||||
return decoded if isinstance(decoded, str) else text
|
||||
|
||||
|
||||
class _LogCapture(logging.Handler):
|
||||
"""Collect dependency log messages for forwarding through BEdit's logger."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(level=logging.WARNING)
|
||||
self.messages: list[str] = []
|
||||
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
self.messages.append(record.getMessage())
|
||||
|
||||
|
||||
def _parse_modelica_string_array(raw: Any) -> tuple[str, ...]:
|
||||
"""Parse the string array returned by ``buildModel`` in raw mode."""
|
||||
|
||||
if isinstance(raw, bytes):
|
||||
raw = raw.decode("utf-8", errors="replace")
|
||||
if not isinstance(raw, str):
|
||||
raise RuntimeError(f"OpenModelica returned an invalid build result: {raw!r}")
|
||||
values = tuple(
|
||||
json.loads(token)
|
||||
for token in re.findall(r'"(?:\\.|[^"\\])*"', raw)
|
||||
)
|
||||
if not values:
|
||||
raise RuntimeError(f"OpenModelica returned an invalid build result: {raw!r}")
|
||||
return values
|
||||
|
||||
|
||||
def _deliver_callback(callback: Callable[[Any], None], value: Any) -> None:
|
||||
try:
|
||||
callback(value)
|
||||
|
||||
@@ -45,11 +45,10 @@ class Simulation:
|
||||
graph: dict[str, Any],
|
||||
callback: Callable[[str], None] | None = None,
|
||||
error_callback: ErrorCallback | None = None,
|
||||
message_callback: Callable[[SimulationMessage], None] | None = None,
|
||||
) -> None:
|
||||
"""Compose and retain the active graph's Modelica representation."""
|
||||
|
||||
return
|
||||
|
||||
self.model_path = None
|
||||
self.compose_source(graph)
|
||||
|
||||
@@ -64,6 +63,24 @@ class Simulation:
|
||||
log.error("%s", failure)
|
||||
return
|
||||
log.info("%s", result.check_summary.strip())
|
||||
if message_callback is not None:
|
||||
message_callback(
|
||||
SimulationMessage(
|
||||
stream="build",
|
||||
type="info",
|
||||
text=result.check_summary.strip(),
|
||||
)
|
||||
)
|
||||
if result.diagnostics:
|
||||
log.warning("OpenModelica build diagnostics:\n%s", result.diagnostics)
|
||||
if message_callback is not None:
|
||||
message_callback(
|
||||
SimulationMessage(
|
||||
stream="build",
|
||||
type="warning",
|
||||
text=result.diagnostics,
|
||||
)
|
||||
)
|
||||
log.info("Compiling OK: %s", result.build_result)
|
||||
try:
|
||||
self.model_path = str(result.build_result[0])
|
||||
@@ -77,6 +94,14 @@ class Simulation:
|
||||
else:
|
||||
log.error("%s", failure)
|
||||
return
|
||||
if message_callback is not None:
|
||||
message_callback(
|
||||
SimulationMessage(
|
||||
stream="build",
|
||||
type="info",
|
||||
text=f"Compiling OK: {result.build_result}",
|
||||
)
|
||||
)
|
||||
if callback is not None:
|
||||
callback(self.model_path)
|
||||
|
||||
@@ -134,7 +159,7 @@ class Simulation:
|
||||
error_callback,
|
||||
)
|
||||
|
||||
self.compose(graph, run_model, error_callback)
|
||||
self.compose(graph, run_model, error_callback, message_callback)
|
||||
|
||||
def get_progress(self) -> SimulationProgress | None:
|
||||
"""Return the most recently received simulation status."""
|
||||
|
||||
Binary file not shown.
@@ -177,13 +177,13 @@
|
||||
"source": {
|
||||
"equations": "der(state) = p.f;\np.e = state/c;",
|
||||
"declarations": "",
|
||||
"initialEquations": ""
|
||||
"initialEquations": "state = 0;"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "bfa506d8-ee41-4bab-ae19-a97fd67bfcf6",
|
||||
"name": "1",
|
||||
"name": "j1",
|
||||
"position": {
|
||||
"x": -96.0,
|
||||
"y": -160.0
|
||||
@@ -256,8 +256,8 @@
|
||||
"implementation": {
|
||||
"kind": "text",
|
||||
"source": {
|
||||
"equations": "flow = p[1].f;\nsum(p[i].e for i in 1:$p_N$) = 0;\nfor i in 2:$p_N$ loop\n p[i].f = p[i-1].f;\nend for;",
|
||||
"declarations": "Real flow;",
|
||||
"equations": "f = s[1] * p[1].f;\nsum(s[i] * p[i].e for i in 1:$p_N$) = 0;\nfor i in 2:$p_N$ loop\n s[i] * p[i].f = s[i-1] * p[i-1].f;\nend for;",
|
||||
"declarations": "parameter Real s[$p_N$] = $p_S$;\nReal f;",
|
||||
"initialEquations": ""
|
||||
}
|
||||
}
|
||||
@@ -399,7 +399,7 @@
|
||||
"parameters": [
|
||||
{
|
||||
"id": "parameter-d056bc27",
|
||||
"name": "effort",
|
||||
"name": "e",
|
||||
"type": "real",
|
||||
"value": "1",
|
||||
"quantity": "",
|
||||
@@ -446,15 +446,15 @@
|
||||
"implementation": {
|
||||
"kind": "text",
|
||||
"source": {
|
||||
"equations": "p.e = effort;\nflow = p.f;",
|
||||
"declarations": "Real flow;",
|
||||
"equations": "p.e = e;\nf = p.f;",
|
||||
"declarations": "Real f;",
|
||||
"initialEquations": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "140ae14b-9dbb-4756-aa25-29101ef2a99e",
|
||||
"name": "0",
|
||||
"name": "j0",
|
||||
"position": {
|
||||
"x": -96.0,
|
||||
"y": -32.0
|
||||
@@ -527,130 +527,8 @@
|
||||
"implementation": {
|
||||
"kind": "text",
|
||||
"source": {
|
||||
"equations": "effort = p[1].e;\nsum(p[i].f for i in 1:$p_N$) = 0;\nfor i in 2:$p_N$ loop\n p[i].e = p[i-1].e;\nend for;",
|
||||
"declarations": "Real effort;",
|
||||
"initialEquations": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "6a6fbadd-28ec-4d10-b854-876752a6b287",
|
||||
"name": "C0",
|
||||
"position": {
|
||||
"x": -96.0,
|
||||
"y": 96.0
|
||||
},
|
||||
"rotation": 0.0,
|
||||
"interface": {
|
||||
"ports": [
|
||||
{
|
||||
"id": "port-2e1d884f",
|
||||
"name": "p",
|
||||
"position": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"properties": {
|
||||
"iconPosition": {
|
||||
"x": 64.0,
|
||||
"y": 64.0
|
||||
}
|
||||
},
|
||||
"type": "power",
|
||||
"multipleConnections": false,
|
||||
"valueType": "real",
|
||||
"quantity": "",
|
||||
"unit": "",
|
||||
"dimensions": {
|
||||
"rows": 1,
|
||||
"columns": 1
|
||||
},
|
||||
"description": "",
|
||||
"orientation": "input",
|
||||
"domain": "power",
|
||||
"causality": "preferred effort out"
|
||||
},
|
||||
{
|
||||
"id": "port-ca7716d5",
|
||||
"name": "state",
|
||||
"position": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"properties": {
|
||||
"iconPosition": {
|
||||
"x": 88.0,
|
||||
"y": 40.0
|
||||
}
|
||||
},
|
||||
"type": "signal",
|
||||
"multipleConnections": false,
|
||||
"valueType": "real",
|
||||
"quantity": "",
|
||||
"unit": "",
|
||||
"dimensions": {
|
||||
"rows": 1,
|
||||
"columns": 1
|
||||
},
|
||||
"description": "",
|
||||
"orientation": "output",
|
||||
"domain": "power",
|
||||
"causality": "indifferent"
|
||||
}
|
||||
]
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"id": "parameter-d056bc27",
|
||||
"name": "c",
|
||||
"type": "real",
|
||||
"value": "1",
|
||||
"quantity": "",
|
||||
"unit": "",
|
||||
"dimensions": {
|
||||
"rows": 1,
|
||||
"columns": 1
|
||||
},
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"icon": {
|
||||
"shape": "rectangle",
|
||||
"fill": "#f4f4f4",
|
||||
"border": "#303030",
|
||||
"text": "Text",
|
||||
"size": {
|
||||
"width": 128.0,
|
||||
"height": 128.0
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "text",
|
||||
"x": 40.0,
|
||||
"y": 40.0,
|
||||
"width": 48.0,
|
||||
"height": 48.0,
|
||||
"text": "C",
|
||||
"color": "#303030",
|
||||
"fontSize": 32.0,
|
||||
"lineStyle": "solid",
|
||||
"lineWidth": 1.5,
|
||||
"stroke": "#303030",
|
||||
"fill": "#ffffff"
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"showName": false
|
||||
},
|
||||
"library": {
|
||||
"showSubtree": true
|
||||
},
|
||||
"implementation": {
|
||||
"kind": "text",
|
||||
"source": {
|
||||
"equations": "der(state) = p.f;\np.e = state/c;",
|
||||
"declarations": "",
|
||||
"equations": "e = p[1].e;\nsum(p[i].f for i in 1:$p_N$) = 0;\nfor i in 2:$p_N$ loop\n p[i].e = p[i-1].e;\nend for;",
|
||||
"declarations": "Real e;",
|
||||
"initialEquations": ""
|
||||
}
|
||||
}
|
||||
@@ -699,7 +577,7 @@
|
||||
"id": "parameter-d056bc27",
|
||||
"name": "r",
|
||||
"type": "real",
|
||||
"value": "1",
|
||||
"value": "10",
|
||||
"quantity": "",
|
||||
"unit": "",
|
||||
"dimensions": {
|
||||
@@ -868,7 +746,7 @@
|
||||
"source": {
|
||||
"equations": "der(state) = p.e;\np.f = state/i;",
|
||||
"declarations": "",
|
||||
"initialEquations": ""
|
||||
"initialEquations": "state = 0;"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -906,23 +784,6 @@
|
||||
"waypoints": []
|
||||
},
|
||||
"type": "power",
|
||||
"causality": "target"
|
||||
},
|
||||
{
|
||||
"id": "ae95fbfc-c771-47f2-8f9e-1c823daaf6b8",
|
||||
"source": {
|
||||
"block": "140ae14b-9dbb-4756-aa25-29101ef2a99e",
|
||||
"port": "port-3e53bf80"
|
||||
},
|
||||
"target": {
|
||||
"block": "6a6fbadd-28ec-4d10-b854-876752a6b287",
|
||||
"port": "port-2e1d884f"
|
||||
},
|
||||
"name": "",
|
||||
"properties": {
|
||||
"waypoints": []
|
||||
},
|
||||
"type": "power",
|
||||
"causality": "source"
|
||||
},
|
||||
{
|
||||
@@ -977,7 +838,7 @@
|
||||
"causality": "target"
|
||||
},
|
||||
{
|
||||
"id": "d6940de3-5b4c-42be-a247-639b3803d85e",
|
||||
"id": "e67f412c-39ae-404d-a513-d4a0c389ef40",
|
||||
"source": {
|
||||
"block": "bfa506d8-ee41-4bab-ae19-a97fd67bfcf6",
|
||||
"port": "port-3e53bf80"
|
||||
@@ -996,7 +857,13 @@
|
||||
],
|
||||
"annotations": [],
|
||||
"junctions": [],
|
||||
"simulation": {}
|
||||
"simulation": {
|
||||
"startTime": 0.0,
|
||||
"stopTime": 10.0,
|
||||
"intervalMode": "numberOfIntervals",
|
||||
"numberOfIntervals": 500,
|
||||
"intervalTime": 0.002
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user