pdesolver 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {pdesolver-0.1.2 → pdesolver-0.1.3}/PKG-INFO +1 -1
  2. {pdesolver-0.1.2 → pdesolver-0.1.3}/pdesolver.egg-info/PKG-INFO +1 -1
  3. pdesolver-0.1.3/pdesolver.egg-info/SOURCES.txt +14 -0
  4. pdesolver-0.1.3/pdesolver.egg-info/top_level.txt +1 -0
  5. {pdesolver-0.1.2 → pdesolver-0.1.3}/pyproject.toml +1 -1
  6. pdesolver-0.1.2/pdesolver/Auxs/FuncAux.py +0 -24
  7. pdesolver-0.1.2/pdesolver/Auxs/PDESEncoder.py +0 -13
  8. pdesolver-0.1.2/pdesolver/Auxs/Visualize.py +0 -266
  9. pdesolver-0.1.2/pdesolver/Auxs/__init__.py +0 -2
  10. pdesolver-0.1.2/pdesolver/Disc/Disc.py +0 -372
  11. pdesolver-0.1.2/pdesolver/Disc/__init__.py +0 -1
  12. pdesolver-0.1.2/pdesolver/Disc/boundaries/__init__.py +0 -44
  13. pdesolver-0.1.2/pdesolver/Disc/boundaries/boundary_base.py +0 -36
  14. pdesolver-0.1.2/pdesolver/Disc/boundaries/dirichlet.py +0 -83
  15. pdesolver-0.1.2/pdesolver/Disc/boundaries/neumann.py +0 -48
  16. pdesolver-0.1.2/pdesolver/Disc/boundaries/periodic_example.py +0 -30
  17. pdesolver-0.1.2/pdesolver/Disc/boundaries/robin.py +0 -51
  18. pdesolver-0.1.2/pdesolver/PDE.py +0 -29
  19. pdesolver-0.1.2/pdesolver/PDES.py +0 -196
  20. pdesolver-0.1.2/pdesolver/Solvers/CN.py +0 -157
  21. pdesolver-0.1.2/pdesolver/Solvers/RKF.py +0 -395
  22. pdesolver-0.1.2/pdesolver/Solvers/__init__.py +0 -3
  23. pdesolver-0.1.2/pdesolver/Solvers/bdf2.py +0 -186
  24. pdesolver-0.1.2/pdesolver/Solvers/solver_base.py +0 -304
  25. pdesolver-0.1.2/pdesolver/__init__.py +0 -5
  26. pdesolver-0.1.2/pdesolver.egg-info/SOURCES.txt +0 -34
  27. pdesolver-0.1.2/pdesolver.egg-info/top_level.txt +0 -1
  28. {pdesolver-0.1.2 → pdesolver-0.1.3}/README.md +0 -0
  29. {pdesolver-0.1.2 → pdesolver-0.1.3}/pdesolver.egg-info/dependency_links.txt +0 -0
  30. {pdesolver-0.1.2 → pdesolver-0.1.3}/pdesolver.egg-info/requires.txt +0 -0
  31. {pdesolver-0.1.2 → pdesolver-0.1.3}/setup.cfg +0 -0
  32. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_adveccao.py +0 -0
  33. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_burgers.py +0 -0
  34. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_calor.py +0 -0
  35. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_fitzhugh.py +0 -0
  36. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_load.py +0 -0
  37. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/test_reacao1d.py +0 -0
  38. {pdesolver-0.1.2 → pdesolver-0.1.3}/tests/tests__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdesolver
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Symbolic PDE solver using finite difference discretization
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/maiocacedo/PDESsolver
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdesolver
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Symbolic PDE solver using finite difference discretization
5
5
  License: MIT
6
6
  Project-URL: Repository, https://github.com/maiocacedo/PDESsolver
@@ -0,0 +1,14 @@
1
+ README.md
2
+ pyproject.toml
3
+ pdesolver.egg-info/PKG-INFO
4
+ pdesolver.egg-info/SOURCES.txt
5
+ pdesolver.egg-info/dependency_links.txt
6
+ pdesolver.egg-info/requires.txt
7
+ pdesolver.egg-info/top_level.txt
8
+ tests/test_adveccao.py
9
+ tests/test_burgers.py
10
+ tests/test_calor.py
11
+ tests/test_fitzhugh.py
12
+ tests/test_load.py
13
+ tests/test_reacao1d.py
14
+ tests/tests__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pdesolver"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "Symbolic PDE solver using finite difference discretization"
9
9
  readme = {file = "README.md", content-type = "text/markdown"}
10
10
  license = { text = "MIT" }
@@ -1,24 +0,0 @@
1
- import re
2
-
3
- import sympy as sp
4
- from sympy.parsing.sympy_parser import parse_expr
5
-
6
- def symbol_references(in_list):
7
- slist = []
8
-
9
- for e in in_list:
10
- globals()[e] = sp.Symbol(e)
11
- slist.append(e)
12
- return slist
13
-
14
- def d_dt(expr_str: str) -> str:
15
- t = sp.Symbol('t')
16
- try:
17
- e = parse_expr(expr_str, evaluate=False)
18
- return str(sp.diff(e, t))
19
- except Exception:
20
- return expr_str
21
-
22
- def repl_symbol(expr: str, sym: str, repl: str) -> str:
23
- pattern = rf'(?<![A-Za-z0-9_]){sym}(?![A-Za-z0-9_])'
24
- return re.sub(pattern, repl, expr)
@@ -1,13 +0,0 @@
1
- import json
2
- import numpy as np
3
- import sympy as sp
4
-
5
- class PDESEncoder(json.JSONEncoder):
6
- def default(self, obj):
7
- if isinstance(obj, np.ndarray):
8
- return obj.tolist()
9
- if isinstance(obj, sp.Basic):
10
- return str(obj)
11
- if hasattr(obj, '__dict__'):
12
- return obj.__dict__
13
- return super().default(obj)
@@ -1,266 +0,0 @@
1
-
2
- import numpy as np
3
- import matplotlib.pyplot as plt
4
- from matplotlib.animation import FuncAnimation
5
-
6
-
7
- def visualize(pdes_obj, mode='heatmap', func_idx=0, time_step=-1, **kwargs):
8
-
9
- if pdes_obj.results is None:
10
- print("Erro: rode .solve() antes de visualizar.")
11
- return
12
-
13
- _, historico = pdes_obj.results
14
-
15
- if not historico or not historico[func_idx]:
16
- print("Erro: histórico vazio.")
17
- return
18
-
19
- if _is_1d(pdes_obj):
20
- x = _get_x1d(pdes_obj)
21
- if mode in ('plot1d', 'plot'):
22
- plot1d(historico, x, pdes_obj.funcs, func_idx, time_step, **kwargs)
23
- elif mode == 'plot1d_all':
24
- plot1d_all(historico, x, pdes_obj.funcs, func_idx, **kwargs)
25
- elif mode == 'heatmap1d':
26
- heatmap1d(historico, x, pdes_obj.funcs, pdes_obj.pdes, func_idx, **kwargs)
27
- elif mode == 'animation1d':
28
- animate1d(historico, x, pdes_obj.funcs, func_idx, **kwargs)
29
- else:
30
- print(f"Modo '{mode}' não reconhecido para 1D. "
31
- f"Use: 'plot1d', 'plot1d_all', 'heatmap1d', 'animation1d'.")
32
- return
33
-
34
- nx, ny = pdes_obj.disc_n
35
- x = np.linspace(0, 1, nx)
36
- y = np.linspace(0, 1, ny)
37
- X, Y = np.meshgrid(x, y, indexing='ij')
38
-
39
- if mode == 'heatmap':
40
- plot_heatmap(historico, X, Y, pdes_obj.funcs, pdes_obj.disc_n, func_idx, time_step)
41
- elif mode == 'animation':
42
- animate2d(historico, X, Y, pdes_obj.funcs, pdes_obj.disc_n, func_idx, **kwargs)
43
- elif mode == 'plot3d':
44
- plot3d(historico, X, Y, pdes_obj.funcs, pdes_obj.disc_n, func_idx, time_step, **kwargs)
45
- elif mode == 'animation3d':
46
- animate3d(historico, X, Y, pdes_obj.funcs, pdes_obj.disc_n, func_idx, **kwargs)
47
- else:
48
- print(f"Modo '{mode}' desconhecido para 2D. "
49
- f"Use: 'heatmap', 'animation', 'plot3d', 'animation3d'.")
50
-
51
-
52
- def _is_1d(pdes_obj):
53
- return len(pdes_obj.disc_n) == 1
54
-
55
-
56
- def _get_x1d(pdes_obj):
57
- a, b = pdes_obj.pdes[0].ivar_boundary[0]
58
- return np.linspace(a, b, pdes_obj.disc_n[0])
59
-
60
-
61
- def plot1d(historico, x, funcs, func_idx, time_step, **kwargs):
62
- color = kwargs.get('color', 'steelblue')
63
- lw = kwargs.get('lw', 2)
64
-
65
- data = np.array(historico[func_idx][time_step])
66
- label = time_step if time_step >= 0 else len(historico[func_idx]) + time_step
67
-
68
- fig, ax = plt.subplots(figsize=(7, 4))
69
- ax.plot(x, data, color=color, linewidth=lw, label=f't = passo {label}')
70
- ax.set_xlabel('x')
71
- ax.set_ylabel(funcs[func_idx])
72
- ax.set_title(f"Perfil de {funcs[func_idx]} — passo {label}")
73
- ax.legend()
74
- ax.grid(True, alpha=0.3)
75
- plt.tight_layout()
76
- plt.show()
77
-
78
-
79
- def plot1d_all(historico, x, funcs, func_idx, **kwargs):
80
- n_profiles = kwargs.get('n_profiles', 10)
81
- cmap = kwargs.get('cmap', 'viridis')
82
- lw = kwargs.get('lw', 1.5)
83
- tf_real = kwargs.get('tf', None)
84
-
85
- n_passos = len(historico[func_idx])
86
- indices = np.linspace(0, n_passos - 1, n_profiles, dtype=int)
87
- cm = plt.get_cmap(cmap)
88
- colors = [cm(i / (n_profiles - 1)) for i in range(n_profiles)]
89
-
90
- fig, ax = plt.subplots(figsize=(8, 5))
91
-
92
- for idx_cor, idx_passo in enumerate(indices):
93
- data = np.array(historico[func_idx][idx_passo])
94
- if tf_real is not None:
95
- t_val = tf_real * idx_passo / (n_passos - 1)
96
- lbl = f't = {t_val:.2f}'
97
- else:
98
- lbl = f'passo {idx_passo}'
99
- ax.plot(x, data, color=colors[idx_cor], linewidth=lw, label=lbl)
100
-
101
- ax.set_xlabel('x')
102
- ax.set_ylabel(funcs[func_idx])
103
- ax.set_title(f"Evolução de {funcs[func_idx]} ao longo do tempo")
104
- ax.legend(fontsize=8, loc='best')
105
- ax.grid(True, alpha=0.3)
106
-
107
- sm = plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=0, vmax=1))
108
- sm.set_array([])
109
- cbar = plt.colorbar(sm, ax=ax, pad=0.02)
110
- cbar.set_label('t / tf')
111
-
112
- plt.tight_layout()
113
- plt.show()
114
-
115
-
116
- def heatmap1d(historico, x, funcs, pdes, func_idx, **kwargs):
117
- cmap = kwargs.get('cmap', 'viridis')
118
- tf_real = kwargs.get('tf', None)
119
-
120
- matriz = np.array(historico[func_idx])
121
- n_passos = matriz.shape[0]
122
- t_max = tf_real if tf_real is not None else n_passos - 1
123
- a, b = pdes[0].ivar_boundary[0]
124
-
125
- fig, ax = plt.subplots(figsize=(8, 5))
126
- im = ax.imshow(
127
- matriz.T,
128
- aspect='auto',
129
- origin='lower',
130
- extent=[0, t_max, a, b],
131
- cmap=cmap
132
- )
133
- ax.set_xlabel('t')
134
- ax.set_ylabel('x')
135
- ax.set_title(f"Evolução espaciotemporal de {funcs[func_idx]}")
136
- plt.colorbar(im, ax=ax, label=funcs[func_idx])
137
- plt.tight_layout()
138
- plt.show()
139
-
140
-
141
- def animate1d(historico, x, funcs, func_idx, **kwargs):
142
- frames_step = kwargs.get('frames_step', 1)
143
- interval = kwargs.get('interval', 50)
144
- color = kwargs.get('color', 'steelblue')
145
- lw = kwargs.get('lw', 2)
146
- tf_real = kwargs.get('tf', None)
147
-
148
- n_passos = len(historico[func_idx])
149
- frames = list(range(0, n_passos, frames_step))
150
-
151
- todos = np.concatenate([historico[func_idx][f] for f in frames])
152
- y_min, y_max = todos.min(), todos.max()
153
- margem = (y_max - y_min) * 0.05 or 0.1
154
-
155
- fig, ax = plt.subplots(figsize=(8, 4))
156
- linha, = ax.plot(x, historico[func_idx][0], color=color, linewidth=lw)
157
- ax.set_xlim(x[0], x[-1])
158
- ax.set_ylim(y_min - margem, y_max + margem)
159
- ax.set_xlabel('x')
160
- ax.set_ylabel(funcs[func_idx])
161
- ax.grid(True, alpha=0.3)
162
- titulo = ax.set_title('')
163
-
164
- def update(frame_idx):
165
- passo = frames[frame_idx]
166
- linha.set_ydata(np.array(historico[func_idx][passo]))
167
- if tf_real is not None:
168
- t_val = tf_real * passo / (n_passos - 1)
169
- titulo.set_text(f"{funcs[func_idx]} — t = {t_val:.3f}")
170
- else:
171
- titulo.set_text(f"{funcs[func_idx]} — passo {passo}")
172
- return linha, titulo
173
-
174
- anim = FuncAnimation(fig, update, frames=len(frames),
175
- interval=interval, blit=True)
176
- plt.tight_layout()
177
- plt.show()
178
-
179
- def plot_heatmap(historico, X, Y, funcs, disc_n, func_idx, time_step):
180
- data = np.array(historico[func_idx][time_step]).reshape(disc_n)
181
- plt.figure(figsize=(7, 6))
182
- contorno = plt.contourf(X, Y, data, levels=30, cmap='hot')
183
- plt.title(f"Distribuição de {funcs[func_idx]} no passo {time_step}")
184
- plt.colorbar(contorno)
185
- plt.show()
186
-
187
-
188
- def animate2d(historico, X, Y, funcs, disc_n, func_idx, **kwargs):
189
- frames_step = kwargs.get('frames_step', 1)
190
- interval = kwargs.get('interval', 50)
191
-
192
- fig, ax = plt.subplots(figsize=(7, 6))
193
- Z_ini = np.array(historico[func_idx][0]).reshape(disc_n)
194
- contorno = ax.contourf(X, Y, Z_ini, levels=30, cmap='hot')
195
- fig.colorbar(contorno, ax=ax)
196
-
197
- def update(frame):
198
- ax.clear()
199
- Z = np.array(historico[func_idx][frame]).reshape(disc_n)
200
- cont = ax.contourf(X, Y, Z, levels=30, cmap='hot')
201
- ax.set_title(f"Evolução de {funcs[func_idx]} - Passo {frame}")
202
- ax.set_xlabel('x')
203
- ax.set_ylabel('y')
204
- return cont,
205
-
206
- frames_list = range(0, len(historico[func_idx]), frames_step)
207
- anim = FuncAnimation(fig, update, frames=frames_list,
208
- interval=interval, blit=False)
209
- plt.show()
210
-
211
-
212
- def plot3d(historico, X, Y, funcs, disc_n, func_idx, time_step, **kwargs):
213
- cmap = kwargs.get('cmap', 'hot')
214
- alpha = kwargs.get('alpha', 1.0)
215
- elev = kwargs.get('elev', 30)
216
- azim = kwargs.get('azim', -60)
217
-
218
- data = np.array(historico[func_idx][time_step]).reshape(disc_n)
219
- label = time_step if time_step >= 0 else len(historico[func_idx]) + time_step
220
-
221
- fig = plt.figure(figsize=(8, 6))
222
- ax = fig.add_subplot(111, projection='3d')
223
- ax.plot_surface(X, Y, data, cmap=cmap, alpha=alpha)
224
- ax.set_title(f"Superfície 3D de {funcs[func_idx]} - Passo {label}")
225
- ax.set_xlabel('x')
226
- ax.set_ylabel('y')
227
- ax.set_zlabel(str(funcs[func_idx]))
228
- ax.view_init(elev=elev, azim=azim)
229
- plt.tight_layout()
230
- plt.show()
231
-
232
-
233
- def animate3d(historico, X, Y, funcs, disc_n, func_idx, **kwargs):
234
- frames_step = kwargs.get('frames_step', 1)
235
- interval = kwargs.get('interval', 50)
236
- cmap = kwargs.get('cmap', 'hot')
237
- alpha = kwargs.get('alpha', 1.0)
238
- elev = kwargs.get('elev', 30)
239
- azim = kwargs.get('azim', -60)
240
-
241
- todos_frames = [
242
- np.array(historico[func_idx][f]).reshape(disc_n)
243
- for f in range(0, len(historico[func_idx]), frames_step)
244
- ]
245
- z_min = min(Z.min() for Z in todos_frames)
246
- z_max = max(Z.max() for Z in todos_frames)
247
-
248
- fig = plt.figure(figsize=(8, 6))
249
- ax = fig.add_subplot(111, projection='3d')
250
-
251
- def update(frame):
252
- ax.clear()
253
- Z = todos_frames[frame]
254
- ax.plot_surface(X, Y, Z, cmap=cmap, alpha=alpha)
255
- ax.set_title(
256
- f"Evolução 3D de {funcs[func_idx]} - Passo {frame * frames_step}"
257
- )
258
- ax.set_xlabel('x')
259
- ax.set_ylabel('y')
260
- ax.set_zlabel(str(funcs[func_idx]))
261
- ax.set_zlim(z_min, z_max)
262
- ax.view_init(elev=elev, azim=azim)
263
-
264
- anim = FuncAnimation(fig, update, frames=len(todos_frames),
265
- interval=interval, blit=False)
266
- plt.show()
@@ -1,2 +0,0 @@
1
- from .FuncAux import symbol_references, repl_symbol, d_dt
2
- from .Visualize import visualize