diff --git a/README.md b/README.md index fe548354..7b0a1b32 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,18 @@ The code used in this exercise is based on [Chapter 7 of the book "Learning Scie ## Project description -## Installing the package +`diffusion2D` is a Python package that numerically solves the 2D diffusion equation using the Finite Difference Method. The package simulates the process of heat diffusion in a square domain, with a circular heat source at the center. The simulation produces visual plots showing the temperature distribution at various time steps. -### Using pip3 to install from PyPI +### Features: +- Solves the 2D diffusion equation numerically for a given domain and initial conditions. +- Visualizes the temperature distribution over time using Matplotlib. +- Parameters such as grid spacing (`dx`, `dy`) and thermal diffusivity (`D`) can be customized. -### Required dependencies +--- -## Running this package +## Installing the package -## Citing +### Using pip3 to install from PyPI +Once the package is uploaded to PyPI, you can install it using pip: +```bash +pip install --user --index-url https://test.pypi.org/simple/ youssemd_diffusion2d diff --git a/diffusion2d.py b/diffusion2d.py deleted file mode 100644 index c0c6083a..00000000 --- a/diffusion2d.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Solving the two-dimensional diffusion equation - -Example acquired from https://scipython.com/book/chapter-7-matplotlib/examples/the-two-dimensional-diffusion-equation/ -""" - -import numpy as np -import matplotlib.pyplot as plt - -# plate size, mm -w = h = 10. -# intervals in x-, y- directions, mm -dx = dy = 0.1 -# Thermal diffusivity of steel, mm^2/s -D = 4. - -# Initial cold temperature of square domain -T_cold = 300 - -# Initial hot temperature of circular disc at the center -T_hot = 700 - -# Number of discrete mesh points in X and Y directions -nx, ny = int(w / dx), int(h / dy) - -# Computing a stable time step -dx2, dy2 = dx * dx, dy * dy -dt = dx2 * dy2 / (2 * D * (dx2 + dy2)) - -print("dt = {}".format(dt)) - -u0 = T_cold * np.ones((nx, ny)) -u = u0.copy() - -# Initial conditions - circle of radius r centred at (cx,cy) (mm) -r = min(h, w) / 4.0 -cx = w / 2.0 -cy = h / 2.0 -r2 = r ** 2 -for i in range(nx): - for j in range(ny): - p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 - if p2 < r2: - u0[i, j] = T_hot - - -def do_timestep(u_nm1, u, D, dt, dx2, dy2): - # Propagate with forward-difference in time, central-difference in space - u[1:-1, 1:-1] = u_nm1[1:-1, 1:-1] + D * dt * ( - (u_nm1[2:, 1:-1] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[:-2, 1:-1]) / dx2 - + (u_nm1[1:-1, 2:] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[1:-1, :-2]) / dy2) - - u_nm1 = u.copy() - return u_nm1, u - - -# Number of timesteps -nsteps = 101 -# Output 4 figures at these timesteps -n_output = [0, 10, 50, 100] -fig_counter = 0 -fig = plt.figure() - -# Time loop -for n in range(nsteps): - u0, u = do_timestep(u0, u, D, dt, dx2, dy2) - - # Create figure - if n in n_output: - fig_counter += 1 - ax = fig.add_subplot(220 + fig_counter) - im = ax.imshow(u.copy(), cmap=plt.get_cmap('hot'), vmin=T_cold, vmax=T_hot) # image for color bar axes - ax.set_axis_off() - ax.set_title('{:.1f} ms'.format(n * dt * 1000)) - -# Plot output figures -fig.subplots_adjust(right=0.85) -cbar_ax = fig.add_axes([0.9, 0.15, 0.03, 0.7]) -cbar_ax.set_xlabel('$T$ / K', labelpad=20) -fig.colorbar(im, cax=cbar_ax) -plt.show() diff --git a/dist/youssemd_diffusion2d-0.0.1-py3-none-any.whl b/dist/youssemd_diffusion2d-0.0.1-py3-none-any.whl new file mode 100644 index 00000000..abd148e5 Binary files /dev/null and b/dist/youssemd_diffusion2d-0.0.1-py3-none-any.whl differ diff --git a/dist/youssemd_diffusion2d-0.0.1.tar.gz b/dist/youssemd_diffusion2d-0.0.1.tar.gz new file mode 100644 index 00000000..2a168463 Binary files /dev/null and b/dist/youssemd_diffusion2d-0.0.1.tar.gz differ diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..d68a5941 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,28 @@ +[metadata] +name = youssemd_diffusion2d +version = 0.0.1 +author = Mohamed Youssef +author_email = mohamedloutfy97@gmail.com +description = A Python package for solving the 2D diffusion equation using Finite Difference Method +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/MohamedAlyLoutfy/diffusion2D.git +classifiers = + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + License :: OSI Approved :: MIT License + Operating System :: OS Independent + +[options] +packages = find: +python_requires = >=3.6 +install_requires = + numpy + matplotlib + +[options.package_data] +* = *.txt, *.md diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..7f1a1763 --- /dev/null +++ b/setup.py @@ -0,0 +1,4 @@ +from setuptools import setup + +if __name__ == "__main__": + setup() diff --git a/youssemd_diffusion2d.egg-info/PKG-INFO b/youssemd_diffusion2d.egg-info/PKG-INFO new file mode 100644 index 00000000..a8041e92 --- /dev/null +++ b/youssemd_diffusion2d.egg-info/PKG-INFO @@ -0,0 +1,46 @@ +Metadata-Version: 2.1 +Name: youssemd_diffusion2d +Version: 0.0.1 +Summary: A Python package for solving the 2D diffusion equation using Finite Difference Method +Home-page: https://github.com/MohamedAlyLoutfy/diffusion2D.git +Author: Mohamed Youssef +Author-email: mohamedloutfy97@gmail.com +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Requires-Python: >=3.6 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: numpy +Requires-Dist: matplotlib + +# diffusion2D + +## Instructions for students + +Please follow the instructions in [pypi_exercise.md](https://github.com/Simulation-Software-Engineering/Lecture-Material/blob/main/03_building_and_packaging/pypi_exercise.md). + +The code used in this exercise is based on [Chapter 7 of the book "Learning Scientific Programming with Python"](https://scipython.com/book/chapter-7-matplotlib/examples/the-two-dimensional-diffusion-equation/). + +## Project description + +`diffusion2D` is a Python package that numerically solves the 2D diffusion equation using the Finite Difference Method. The package simulates the process of heat diffusion in a square domain, with a circular heat source at the center. The simulation produces visual plots showing the temperature distribution at various time steps. + +### Features: +- Solves the 2D diffusion equation numerically for a given domain and initial conditions. +- Visualizes the temperature distribution over time using Matplotlib. +- Parameters such as grid spacing (`dx`, `dy`) and thermal diffusivity (`D`) can be customized. + +--- + +## Installing the package + +### Using pip3 to install from PyPI +Once the package is uploaded to PyPI, you can install it using pip: +```bash +pip install --user --index-url https://test.pypi.org/simple/ youssemd_diffusion2d diff --git a/youssemd_diffusion2d.egg-info/SOURCES.txt b/youssemd_diffusion2d.egg-info/SOURCES.txt new file mode 100644 index 00000000..b13055d2 --- /dev/null +++ b/youssemd_diffusion2d.egg-info/SOURCES.txt @@ -0,0 +1,12 @@ +LICENSE +README.md +setup.cfg +setup.py +youssemd_diffusion2d/__init__.py +youssemd_diffusion2d/diffusion2d.py +youssemd_diffusion2d/output.py +youssemd_diffusion2d.egg-info/PKG-INFO +youssemd_diffusion2d.egg-info/SOURCES.txt +youssemd_diffusion2d.egg-info/dependency_links.txt +youssemd_diffusion2d.egg-info/requires.txt +youssemd_diffusion2d.egg-info/top_level.txt \ No newline at end of file diff --git a/youssemd_diffusion2d.egg-info/dependency_links.txt b/youssemd_diffusion2d.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/youssemd_diffusion2d.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/youssemd_diffusion2d.egg-info/requires.txt b/youssemd_diffusion2d.egg-info/requires.txt new file mode 100644 index 00000000..aa094d9f --- /dev/null +++ b/youssemd_diffusion2d.egg-info/requires.txt @@ -0,0 +1,2 @@ +numpy +matplotlib diff --git a/youssemd_diffusion2d.egg-info/top_level.txt b/youssemd_diffusion2d.egg-info/top_level.txt new file mode 100644 index 00000000..ec04e141 --- /dev/null +++ b/youssemd_diffusion2d.egg-info/top_level.txt @@ -0,0 +1 @@ +youssemd_diffusion2d diff --git a/youssemd_diffusion2d/__init__.py b/youssemd_diffusion2d/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/youssemd_diffusion2d/__pycache__/__init__.cpython-39.pyc b/youssemd_diffusion2d/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..2bf212da Binary files /dev/null and b/youssemd_diffusion2d/__pycache__/__init__.cpython-39.pyc differ diff --git a/youssemd_diffusion2d/__pycache__/diffusion2d.cpython-39.pyc b/youssemd_diffusion2d/__pycache__/diffusion2d.cpython-39.pyc new file mode 100644 index 00000000..4379cbe1 Binary files /dev/null and b/youssemd_diffusion2d/__pycache__/diffusion2d.cpython-39.pyc differ diff --git a/youssemd_diffusion2d/__pycache__/output.cpython-39.pyc b/youssemd_diffusion2d/__pycache__/output.cpython-39.pyc new file mode 100644 index 00000000..ac3d9977 Binary files /dev/null and b/youssemd_diffusion2d/__pycache__/output.cpython-39.pyc differ diff --git a/youssemd_diffusion2d/diffusion2d.py b/youssemd_diffusion2d/diffusion2d.py new file mode 100644 index 00000000..a4e1f941 --- /dev/null +++ b/youssemd_diffusion2d/diffusion2d.py @@ -0,0 +1,68 @@ +""" +Solving the two-dimensional diffusion equation + +Example acquired from https://scipython.com/book/chapter-7-matplotlib/examples/the-two-dimensional-diffusion-equation/ +""" + +import numpy as np +from youssemd_diffusion2d.output import create_plot, output_plots +import matplotlib.pyplot as plt + + +def solve(dx=0.1, dy=0.1, D=4.0): + # Plate size, mm + w = h = 10.0 + # Thermal diffusivity of steel, mm^2/s + T_cold = 300 + T_hot = 700 + + # Number of discrete mesh points in X and Y directions + nx, ny = int(w / dx), int(h / dy) + + # Computing a stable time step + dx2, dy2 = dx * dx, dy * dy + dt = dx2 * dy2 / (2 * D * (dx2 + dy2)) + + print(f"dt = {dt}") + + u0 = T_cold * np.ones((nx, ny)) + u = u0.copy() + + # Initial conditions - circle of radius r centered at (cx,cy) (mm) + r = min(h, w) / 4.0 + cx = w / 2.0 + cy = h / 2.0 + r2 = r ** 2 + for i in range(nx): + for j in range(ny): + p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 + if p2 < r2: + u0[i, j] = T_hot + + def do_timestep(u_nm1, u, D, dt, dx2, dy2): + # Propagate with forward-difference in time, central-difference in space + u[1:-1, 1:-1] = u_nm1[1:-1, 1:-1] + D * dt * ( + (u_nm1[2:, 1:-1] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[:-2, 1:-1]) / dx2 + + (u_nm1[1:-1, 2:] - 2 * u_nm1[1:-1, 1:-1] + u_nm1[1:-1, :-2]) / dy2) + + u_nm1 = u.copy() + return u_nm1, u + + # Number of timesteps + nsteps = 101 + # Output 4 figures at these timesteps + n_output = [0, 10, 50, 100] + fig_counter = 0 + fig = plt.figure() + + # Time loop + for n in range(nsteps): + u0, u = do_timestep(u0, u, D, dt, dx2, dy2) + + # Create figure + if n in n_output: + fig_counter += 1 + im = create_plot(fig, u, T_cold, T_hot, n, dt, fig_counter) + + # Plot output figures + output_plots(fig, im) diff --git a/youssemd_diffusion2d/output.py b/youssemd_diffusion2d/output.py new file mode 100644 index 00000000..d93de777 --- /dev/null +++ b/youssemd_diffusion2d/output.py @@ -0,0 +1,19 @@ +import matplotlib.pyplot as plt + + +def create_plot(fig, u, T_cold, T_hot, time_step, dt, fig_counter): + """Creates a single plot for a specific time step.""" + ax = fig.add_subplot(220 + fig_counter) + im = ax.imshow(u.copy(), cmap=plt.get_cmap('hot'), vmin=T_cold, vmax=T_hot) + ax.set_axis_off() + ax.set_title(f'{time_step * dt * 1000:.1f} ms') + return im + + +def output_plots(fig, im): + """Finalizes and displays the combined plots.""" + fig.subplots_adjust(right=0.85) + cbar_ax = fig.add_axes([0.9, 0.15, 0.03, 0.7]) + cbar_ax.set_xlabel('$T$ / K', labelpad=20) + fig.colorbar(im, cax=cbar_ax) + plt.show()