Skip to content

Commit d67d1d8

Browse files
committed
Merge branch 'csv_download' of github.com:tasnimxvi/fuel-cycle-sim into csv_download
2 parents 6ccecf0 + a0588ec commit d67d1d8

File tree

9 files changed

+550
-41
lines changed

9 files changed

+550
-41
lines changed

mwe.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from src.custom_pathsim_blocks import FestimWall
2+
3+
from pathsim import Simulation, Connection
4+
import pathsim.blocks
5+
import numpy as np
6+
import matplotlib.pyplot as plt
7+
8+
9+
# Create blocks
10+
blocks, events = [], []
11+
12+
# Create Festim wall
13+
festim_wall = FestimWall(thickness=1, D_0=1, E_D=0, temperature=300, n_vertices=100)
14+
source_c0 = pathsim.blocks.Constant(0)
15+
source_cL = pathsim.blocks.Constant(1)
16+
17+
scope = pathsim.blocks.Scope(labels=["flux_0", "flux_L"])
18+
19+
blocks = [festim_wall, source_c0, source_cL, scope]
20+
21+
connections = [
22+
Connection(source_c0, festim_wall[0]),
23+
Connection(source_cL, festim_wall[1]),
24+
Connection(festim_wall[0], scope[0]),
25+
Connection(festim_wall[1], scope[1]),
26+
]
27+
28+
simulation = Simulation(blocks=blocks, connections=connections, dt=0.005)
29+
simulation.run(0.1)
30+
31+
scope.plot(marker="o")
32+
plt.show()

saved_graphs/festim_example.json

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
{
2+
"nodes": [
3+
{
4+
"id": "4",
5+
"type": "constant",
6+
"position": {
7+
"x": 1093.1885987981248,
8+
"y": 271.20138523630243
9+
},
10+
"data": {
11+
"label": "cL",
12+
"value": "0"
13+
},
14+
"measured": {
15+
"width": 205,
16+
"height": 53
17+
},
18+
"selected": false,
19+
"dragging": false
20+
},
21+
{
22+
"id": "5",
23+
"type": "scope",
24+
"position": {
25+
"x": 1271,
26+
"y": 457
27+
},
28+
"data": {
29+
"label": "scope 5"
30+
},
31+
"measured": {
32+
"width": 120,
33+
"height": 140
34+
},
35+
"selected": false,
36+
"dragging": false
37+
},
38+
{
39+
"id": "9",
40+
"type": "scope",
41+
"position": {
42+
"x": 967.9637725351604,
43+
"y": 81.60628755860085
44+
},
45+
"data": {
46+
"label": "scope 9"
47+
},
48+
"measured": {
49+
"width": 120,
50+
"height": 140
51+
},
52+
"selected": false,
53+
"dragging": false
54+
},
55+
{
56+
"id": "10",
57+
"type": "stepsource",
58+
"position": {
59+
"x": 589,
60+
"y": 224
61+
},
62+
"data": {
63+
"label": "stepsource 10",
64+
"amplitude": "1",
65+
"delay": "0.2"
66+
},
67+
"measured": {
68+
"width": 120,
69+
"height": 120
70+
},
71+
"selected": false,
72+
"dragging": false
73+
},
74+
{
75+
"id": "12",
76+
"type": "wall",
77+
"position": {
78+
"x": 952,
79+
"y": 417
80+
},
81+
"data": {
82+
"label": "wall",
83+
"thickness": "1",
84+
"surface_area": "1",
85+
"temperature": "300",
86+
"D_0": "0.05",
87+
"E_D": "0",
88+
"n_vertices": "100"
89+
},
90+
"measured": {
91+
"width": 70,
92+
"height": 200
93+
},
94+
"selected": true,
95+
"dragging": false
96+
}
97+
],
98+
"edges": [
99+
{
100+
"id": "e4-9",
101+
"source": "4",
102+
"target": "9",
103+
"sourceHandle": null,
104+
"targetHandle": null,
105+
"type": "smoothstep",
106+
"data": {},
107+
"style": {
108+
"strokeWidth": 2,
109+
"stroke": "#ECDFCC"
110+
},
111+
"markerEnd": {
112+
"type": "arrowclosed",
113+
"width": 20,
114+
"height": 20,
115+
"color": "#ECDFCC"
116+
}
117+
},
118+
{
119+
"id": "e10-9",
120+
"source": "10",
121+
"target": "9",
122+
"sourceHandle": null,
123+
"targetHandle": null,
124+
"type": "smoothstep",
125+
"data": {},
126+
"style": {
127+
"strokeWidth": 2,
128+
"stroke": "#ECDFCC"
129+
},
130+
"markerEnd": {
131+
"type": "arrowclosed",
132+
"width": 20,
133+
"height": 20,
134+
"color": "#ECDFCC"
135+
}
136+
},
137+
{
138+
"id": "e10-12-to_c_0",
139+
"source": "10",
140+
"target": "12",
141+
"sourceHandle": null,
142+
"targetHandle": "c_0",
143+
"type": "smoothstep",
144+
"data": {},
145+
"style": {
146+
"strokeWidth": 2,
147+
"stroke": "#ECDFCC"
148+
},
149+
"markerEnd": {
150+
"type": "arrowclosed",
151+
"width": 20,
152+
"height": 20,
153+
"color": "#ECDFCC"
154+
}
155+
},
156+
{
157+
"id": "e4-12-to_c_L",
158+
"source": "4",
159+
"target": "12",
160+
"sourceHandle": null,
161+
"targetHandle": "c_L",
162+
"type": "smoothstep",
163+
"data": {},
164+
"style": {
165+
"strokeWidth": 2,
166+
"stroke": "#ECDFCC"
167+
},
168+
"markerEnd": {
169+
"type": "arrowclosed",
170+
"width": 20,
171+
"height": 20,
172+
"color": "#ECDFCC"
173+
}
174+
},
175+
{
176+
"id": "e12-5-from_flux_L",
177+
"source": "12",
178+
"target": "5",
179+
"sourceHandle": "flux_L",
180+
"targetHandle": null,
181+
"type": "smoothstep",
182+
"data": {},
183+
"style": {
184+
"strokeWidth": 2,
185+
"stroke": "#ECDFCC"
186+
},
187+
"markerEnd": {
188+
"type": "arrowclosed",
189+
"width": 20,
190+
"height": 20,
191+
"color": "#ECDFCC"
192+
}
193+
}
194+
],
195+
"nodeCounter": 13,
196+
"solverParams": {
197+
"dt": "0.02",
198+
"dt_min": "1e-6",
199+
"dt_max": "1.0",
200+
"Solver": "SSPRK22",
201+
"tolerance_fpi": "1e-6",
202+
"iterations_max": "100",
203+
"log": "true",
204+
"simulation_duration": "2",
205+
"extra_params": "{}"
206+
},
207+
"globalVariables": []
208+
}

src/App.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { makeEdge } from './CustomEdge';
2929
import MultiplierNode from './MultiplierNode';
3030
import { Splitter2Node, Splitter3Node } from './Splitters';
3131
import BubblerNode from './BubblerNode';
32+
import WallNode from './WallNode';
3233

3334
// Add nodes as a node type for this script
3435
const nodeTypes = {
@@ -49,7 +50,11 @@ const nodeTypes = {
4950
pid: DefaultNode,
5051
splitter2: Splitter2Node,
5152
splitter3: Splitter3Node,
53+
wall: WallNode,
5254
bubbler: BubblerNode,
55+
white_noise: SourceNode,
56+
pink_noise: SourceNode,
57+
5358
};
5459

5560
// Defining initial nodes and edges. In the data section, we have label, but also parameters specific to the node.
@@ -660,8 +665,18 @@ export default function App() {
660665
case 'splitter3':
661666
nodeData = { ...nodeData, f1: '1/3', f2: '1/3', f3: '1/3' };
662667
break;
668+
case 'wall':
669+
nodeData = { ...nodeData, thickness: '', surface_area: '1', temperature: '', D_0: '1', E_D: '0', n_vertices: '100' };
670+
break;
663671
case 'bubbler':
664672
nodeData = { ...nodeData, conversion_efficiency: '0.95', vial_efficiency: '0.9', replacement_times: '' };
673+
break;
674+
case 'white_noise':
675+
nodeData = { ...nodeData, spectral_density: '1', sampling_rate: '' };
676+
break;
677+
case 'pink_noise':
678+
nodeData = { ...nodeData, spectral_density: '1', num_octaves: '16', sampling_rate: '' };
679+
break;
665680
default:
666681
// For any other types, just use basic data
667682
break;

src/WallNode.jsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react';
2+
import { Handle } from '@xyflow/react';
3+
4+
export default function WallNode({ data }) {
5+
return (
6+
<div
7+
style={{
8+
width: 50,
9+
height: 180,
10+
background: '#DDE6ED',
11+
color: 'black',
12+
borderRadius: 0,
13+
padding: 10,
14+
fontWeight: 'bold',
15+
position: 'relative',
16+
cursor: 'pointer',
17+
}}
18+
>
19+
<div style={{ marginBottom: 4 }}>{data.label}</div>
20+
21+
{/* Left side handles with labels */}
22+
<Handle type="target" id="c_0" position="left" style={{ background: '#555', top: '40%' }} />
23+
<div style={{
24+
position: 'absolute',
25+
left: '5px',
26+
top: '35%',
27+
fontSize: '12px',
28+
fontWeight: 'normal'
29+
}}>
30+
c₀
31+
</div>
32+
33+
<Handle type="source" id="flux_0" position="left" style={{ background: '#555', top: '60%' }} />
34+
<div style={{
35+
position: 'absolute',
36+
left: '5px',
37+
top: '55%',
38+
fontSize: '12px',
39+
fontWeight: 'normal'
40+
}}>
41+
φ₀
42+
</div>
43+
44+
{/* Right side handles with labels */}
45+
<Handle type="target" id="c_L" position="right" style={{ background: '#555', top: '40%' }} />
46+
<div style={{
47+
position: 'absolute',
48+
right: '5px',
49+
top: '35%',
50+
fontSize: '12px',
51+
fontWeight: 'normal'
52+
}}>
53+
cₗ
54+
</div>
55+
56+
<Handle type="source" id="flux_L" position="right" style={{ background: '#555', top: '60%' }} />
57+
<div style={{
58+
position: 'absolute',
59+
right: '5px',
60+
top: '55%',
61+
fontSize: '12px',
62+
fontWeight: 'normal'
63+
}}>
64+
φₗ
65+
</div>
66+
</div>
67+
);
68+
}

src/convert_to_python.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@
33
from inspect import signature
44

55
from pathsim.blocks import Scope
6-
from .custom_pathsim_blocks import (
7-
Process,
8-
Splitter,
9-
Bubbler,
10-
)
6+
from .custom_pathsim_blocks import Process, Splitter, Bubbler, FestimWall
117
from .pathsim_utils import (
128
map_str_to_object,
139
make_blocks,
@@ -162,11 +158,29 @@ def make_edge_data(data: dict) -> list[dict]:
162158
raise ValueError(
163159
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
164160
)
161+
elif isinstance(block, FestimWall):
162+
if edge["sourceHandle"] == "flux_0":
163+
output_index = 0
164+
elif edge["sourceHandle"] == "flux_L":
165+
output_index = 1
166+
else:
167+
raise ValueError(
168+
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
169+
)
165170
else:
166171
output_index = 0
167172

168173
if isinstance(target_block, Scope):
169174
input_index = target_block._connections_order.index(edge["id"])
175+
elif isinstance(target_block, FestimWall):
176+
if edge["targetHandle"] == "c_0":
177+
input_index = 0
178+
elif edge["targetHandle"] == "c_L":
179+
input_index = 1
180+
else:
181+
raise ValueError(
182+
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
183+
)
170184
else:
171185
input_index = block_to_input_index[target_block]
172186

0 commit comments

Comments
 (0)