Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions mwe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from src.custom_pathsim_blocks import FestimWall

from pathsim import Simulation, Connection
import pathsim.blocks
import numpy as np
import matplotlib.pyplot as plt


# Create blocks
blocks, events = [], []

# Create Festim wall
festim_wall = FestimWall(thickness=1, D_0=1, E_D=0, temperature=300, n_vertices=100)
source_c0 = pathsim.blocks.Constant(0)
source_cL = pathsim.blocks.Constant(1)

scope = pathsim.blocks.Scope(labels=["flux_0", "flux_L"])

blocks = [festim_wall, source_c0, source_cL, scope]

connections = [
Connection(source_c0, festim_wall[0]),
Connection(source_cL, festim_wall[1]),
Connection(festim_wall[0], scope[0]),
Connection(festim_wall[1], scope[1]),
]

simulation = Simulation(blocks=blocks, connections=connections, dt=0.005)
simulation.run(0.1)

scope.plot(marker="o")
plt.show()
208 changes: 208 additions & 0 deletions saved_graphs/festim_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
{
"nodes": [
{
"id": "4",
"type": "constant",
"position": {
"x": 1093.1885987981248,
"y": 271.20138523630243
},
"data": {
"label": "cL",
"value": "0"
},
"measured": {
"width": 205,
"height": 53
},
"selected": false,
"dragging": false
},
{
"id": "5",
"type": "scope",
"position": {
"x": 1271,
"y": 457
},
"data": {
"label": "scope 5"
},
"measured": {
"width": 120,
"height": 140
},
"selected": false,
"dragging": false
},
{
"id": "9",
"type": "scope",
"position": {
"x": 967.9637725351604,
"y": 81.60628755860085
},
"data": {
"label": "scope 9"
},
"measured": {
"width": 120,
"height": 140
},
"selected": false,
"dragging": false
},
{
"id": "10",
"type": "stepsource",
"position": {
"x": 589,
"y": 224
},
"data": {
"label": "stepsource 10",
"amplitude": "1",
"delay": "0.2"
},
"measured": {
"width": 120,
"height": 120
},
"selected": false,
"dragging": false
},
{
"id": "12",
"type": "wall",
"position": {
"x": 952,
"y": 417
},
"data": {
"label": "wall",
"thickness": "1",
"surface_area": "1",
"temperature": "300",
"D_0": "0.05",
"E_D": "0",
"n_vertices": "100"
},
"measured": {
"width": 70,
"height": 200
},
"selected": true,
"dragging": false
}
],
"edges": [
{
"id": "e4-9",
"source": "4",
"target": "9",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e10-9",
"source": "10",
"target": "9",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e10-12-to_c_0",
"source": "10",
"target": "12",
"sourceHandle": null,
"targetHandle": "c_0",
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e4-12-to_c_L",
"source": "4",
"target": "12",
"sourceHandle": null,
"targetHandle": "c_L",
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e12-5-from_flux_L",
"source": "12",
"target": "5",
"sourceHandle": "flux_L",
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
}
],
"nodeCounter": 13,
"solverParams": {
"dt": "0.02",
"dt_min": "1e-6",
"dt_max": "1.0",
"Solver": "SSPRK22",
"tolerance_fpi": "1e-6",
"iterations_max": "100",
"log": "true",
"simulation_duration": "2",
"extra_params": "{}"
},
"globalVariables": []
}
5 changes: 5 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Background,
useNodesState,
useEdgesState,
addEdge,

Check failure on line 9 in src/App.jsx

View workflow job for this annotation

GitHub Actions / test (20.x, 3.10)

'addEdge' is defined but never used. Allowed unused vars must match /^[A-Z_]/u

Check failure on line 9 in src/App.jsx

View workflow job for this annotation

GitHub Actions / test (20.x, 3.11)

'addEdge' is defined but never used. Allowed unused vars must match /^[A-Z_]/u
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import './App.css';
Expand All @@ -29,6 +29,7 @@
import MultiplierNode from './MultiplierNode';
import { Splitter2Node, Splitter3Node } from './Splitters';
import BubblerNode from './BubblerNode';
import WallNode from './WallNode';

// Add nodes as a node type for this script
const nodeTypes = {
Expand All @@ -49,6 +50,7 @@
pid: DefaultNode,
splitter2: Splitter2Node,
splitter3: Splitter3Node,
wall: WallNode,
bubbler: BubblerNode,
white_noise: SourceNode,
pink_noise: SourceNode,
Expand Down Expand Up @@ -609,6 +611,9 @@
case 'splitter3':
nodeData = { ...nodeData, f1: '1/3', f2: '1/3', f3: '1/3' };
break;
case 'wall':
nodeData = { ...nodeData, thickness: '', surface_area: '1', temperature: '', D_0: '1', E_D: '0', n_vertices: '100' };
break;
case 'bubbler':
nodeData = { ...nodeData, conversion_efficiency: '0.95', vial_efficiency: '0.9', replacement_times: '' };
break;
Expand Down Expand Up @@ -778,7 +783,7 @@
return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, [selectedEdge, selectedNode, copiedNode, duplicateNode, setCopyFeedback]);

Check warning on line 786 in src/App.jsx

View workflow job for this annotation

GitHub Actions / test (20.x, 3.10)

React Hook useEffect has missing dependencies: 'deleteSelectedEdge' and 'deleteSelectedNode'. Either include them or remove the dependency array

Check warning on line 786 in src/App.jsx

View workflow job for this annotation

GitHub Actions / test (20.x, 3.11)

React Hook useEffect has missing dependencies: 'deleteSelectedEdge' and 'deleteSelectedNode'. Either include them or remove the dependency array

return (
<div style={{ width: '100vw', height: '100vh', position: 'relative' }}>
Expand Down
68 changes: 68 additions & 0 deletions src/WallNode.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import { Handle } from '@xyflow/react';

export default function WallNode({ data }) {
return (
<div
style={{
width: 50,
height: 180,
background: '#DDE6ED',
color: 'black',
borderRadius: 0,
padding: 10,
fontWeight: 'bold',
position: 'relative',
cursor: 'pointer',
}}
>
<div style={{ marginBottom: 4 }}>{data.label}</div>

{/* Left side handles with labels */}
<Handle type="target" id="c_0" position="left" style={{ background: '#555', top: '40%' }} />
<div style={{
position: 'absolute',
left: '5px',
top: '35%',
fontSize: '12px',
fontWeight: 'normal'
}}>
c₀
</div>

<Handle type="source" id="flux_0" position="left" style={{ background: '#555', top: '60%' }} />
<div style={{
position: 'absolute',
left: '5px',
top: '55%',
fontSize: '12px',
fontWeight: 'normal'
}}>
φ₀
</div>

{/* Right side handles with labels */}
<Handle type="target" id="c_L" position="right" style={{ background: '#555', top: '40%' }} />
<div style={{
position: 'absolute',
right: '5px',
top: '35%',
fontSize: '12px',
fontWeight: 'normal'
}}>
cₗ
</div>

<Handle type="source" id="flux_L" position="right" style={{ background: '#555', top: '60%' }} />
<div style={{
position: 'absolute',
right: '5px',
top: '55%',
fontSize: '12px',
fontWeight: 'normal'
}}>
φₗ
</div>
</div>
);
}
24 changes: 19 additions & 5 deletions src/convert_to_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
from inspect import signature

from pathsim.blocks import Scope
from .custom_pathsim_blocks import (
Process,
Splitter,
Bubbler,
)
from .custom_pathsim_blocks import Process, Splitter, Bubbler, FestimWall
from .pathsim_utils import (
map_str_to_object,
make_blocks,
Expand Down Expand Up @@ -162,11 +158,29 @@ def make_edge_data(data: dict) -> list[dict]:
raise ValueError(
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
)
elif isinstance(block, FestimWall):
if edge["sourceHandle"] == "flux_0":
output_index = 0
elif edge["sourceHandle"] == "flux_L":
output_index = 1
else:
raise ValueError(
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
)
else:
output_index = 0

if isinstance(target_block, Scope):
input_index = target_block._connections_order.index(edge["id"])
elif isinstance(target_block, FestimWall):
if edge["targetHandle"] == "c_0":
input_index = 0
elif edge["targetHandle"] == "c_L":
input_index = 1
else:
raise ValueError(
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
)
else:
input_index = block_to_input_index[target_block]

Expand Down
Loading
Loading