diff --git a/README.md b/README.md index fe548354..8d6af625 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,47 @@ The code used in this exercise is based on [Chapter 7 of the book "Learning Scie ## Project description +This code solves the diffusion equation in 2D over a square domain which is at a certain temperature and a circular disc at the center which is at a higher temperature. This code solves the diffusion equation using the Finite Difference Method. The thermal diffusivity and initial conditions of the system can be changed by the user. The code produces four plots at various timepoints of the simulation. The diffusion process can be clearly observed in these plots. + ## Installing the package ### Using pip3 to install from PyPI +Direct installation is possible from PyPI by using the following command: + +```sh +pip install -i https://test.pypi.org/simple/ puranivt-diffusion2d==0.0.1 +``` + ### Required dependencies +The following dependencies will be automatically installed: + +1. `numpy`: It supports large, multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays. +2. `matplotlib`: A plotting library commonly used in Python. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits. + ## Running this package +The equation solver is implemented in the `solve` function of the package. To make the code run: + +Simply open a python shell and run the following commands: + +```python +from puranivt_diffusion2d.diffusion2d import solve + +solve(dx = 0.1, dy = 0.1, D = 4) +``` + +Play around with the values of these parameters to observe changes in the output. + ## Citing + +```bibtex +@software{puranivt_diffusion2d, + author = {Vedant Puranik}, + title = {{{puranivt_diffusion2d}: A project that implementes the diffusion equation solver over a series of timesteps based on configurable parameters: (dx, dy, D)}}, + year = {2024}, + version = {0.0.1}, + url = {"https://github.com/VedantKP/diffusion2D"}, +} +``` \ No newline at end of file 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/puranivt_diffusion2d-0.0.1-py3-none-any.whl b/dist/puranivt_diffusion2d-0.0.1-py3-none-any.whl new file mode 100644 index 00000000..2c743b0b Binary files /dev/null and b/dist/puranivt_diffusion2d-0.0.1-py3-none-any.whl differ diff --git a/dist/puranivt_diffusion2d-0.0.1.tar.gz b/dist/puranivt_diffusion2d-0.0.1.tar.gz new file mode 100644 index 00000000..b38ee822 Binary files /dev/null and b/dist/puranivt_diffusion2d-0.0.1.tar.gz differ diff --git a/puranivt_diffusion2d.egg-info/PKG-INFO b/puranivt_diffusion2d.egg-info/PKG-INFO new file mode 100644 index 00000000..c966683b --- /dev/null +++ b/puranivt_diffusion2d.egg-info/PKG-INFO @@ -0,0 +1,75 @@ +Metadata-Version: 2.1 +Name: puranivt_diffusion2d +Version: 0.0.1 +Summary: A project that implementes the diffusion equation solver over a series of timesteps based on configurable parameters: (dx, dy, D) +Author-email: Vedant Puranik +Project-URL: Homepage, https://github.com/VedantKP/diffusion2D +Keywords: diffusion_equation,diffusion2d,puranivt,SSE +Classifier: Programming Language :: Python :: 3 +Classifier: License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +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 + +This code solves the diffusion equation in 2D over a square domain which is at a certain temperature and a circular disc at the center which is at a higher temperature. This code solves the diffusion equation using the Finite Difference Method. The thermal diffusivity and initial conditions of the system can be changed by the user. The code produces four plots at various timepoints of the simulation. The diffusion process can be clearly observed in these plots. + +## Installing the package + +### Using pip3 to install from PyPI + +Direct installation is possible from PyPI by using the following command: + +```sh +pip3 install puranivt-diffusion2d +``` + +### Required dependencies + +The following dependencies will be automatically installed: + +1. `numpy`: It supports large, multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays. +2. `matplotlib`: A plotting library commonly used in Python. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits. + +## Running this package + +The equation solver is implemented in the `solve` function of the package. To make the code run: + +Either simply open a python shell and run the following commands: + +```python +from puranivt_diffusion2d.diffusion2d import solve + +solve(dx = 0.1, dy = 0.1, D = 4) +``` +**OR** + +As the starting point of the package is defined as the `solve` function itself, only calling the solve function with the optional parameters would suffice. + +```python +solve(dx = 0.1, dy = 0.1, D = 4) +``` + +## Citing + +```bibtex +@software{puranivt_diffusion2d, + author = {Vedant Puranik}, + title = {{{puranivt_diffusion2d}: A project that implementes the diffusion equation solver over a series of timesteps based on configurable parameters: (dx, dy, D)}}, + year = {2024}, + version = {0.0.1}, + url = {"https://github.com/VedantKP/diffusion2D"}, +} +``` diff --git a/puranivt_diffusion2d.egg-info/SOURCES.txt b/puranivt_diffusion2d.egg-info/SOURCES.txt new file mode 100644 index 00000000..27a12a23 --- /dev/null +++ b/puranivt_diffusion2d.egg-info/SOURCES.txt @@ -0,0 +1,12 @@ +LICENSE +README.md +pyproject.toml +puranivt_diffusion2d/__init__.py +puranivt_diffusion2d/diffusion2d.py +puranivt_diffusion2d/output.py +puranivt_diffusion2d.egg-info/PKG-INFO +puranivt_diffusion2d.egg-info/SOURCES.txt +puranivt_diffusion2d.egg-info/dependency_links.txt +puranivt_diffusion2d.egg-info/entry_points.txt +puranivt_diffusion2d.egg-info/requires.txt +puranivt_diffusion2d.egg-info/top_level.txt \ No newline at end of file diff --git a/puranivt_diffusion2d.egg-info/dependency_links.txt b/puranivt_diffusion2d.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/puranivt_diffusion2d.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/puranivt_diffusion2d.egg-info/entry_points.txt b/puranivt_diffusion2d.egg-info/entry_points.txt new file mode 100644 index 00000000..374b3659 --- /dev/null +++ b/puranivt_diffusion2d.egg-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +solve = puranivt_diffusion2d.diffusion2d:solve diff --git a/puranivt_diffusion2d.egg-info/requires.txt b/puranivt_diffusion2d.egg-info/requires.txt new file mode 100644 index 00000000..aa094d9f --- /dev/null +++ b/puranivt_diffusion2d.egg-info/requires.txt @@ -0,0 +1,2 @@ +numpy +matplotlib diff --git a/puranivt_diffusion2d.egg-info/top_level.txt b/puranivt_diffusion2d.egg-info/top_level.txt new file mode 100644 index 00000000..82ffb557 --- /dev/null +++ b/puranivt_diffusion2d.egg-info/top_level.txt @@ -0,0 +1 @@ +puranivt_diffusion2d diff --git a/puranivt_diffusion2d/__init__.py b/puranivt_diffusion2d/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/puranivt_diffusion2d/diffusion2d.py b/puranivt_diffusion2d/diffusion2d.py new file mode 100644 index 00000000..beab5084 --- /dev/null +++ b/puranivt_diffusion2d/diffusion2d.py @@ -0,0 +1,78 @@ +""" +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 +from puranivt_diffusion2d.output import create_plot, output_plots + +def solve(dx: float = 0.1, dy: float = 0.1, D: int = 4): + """Wrapper for the diffusion equation solver and image rendering functionality + + Keyword arguments: + dx -- intervals in x- directions, mm + dy -- intervals in y- directions, mm + D -- Thermal diffusivity of steel, mm^2/s + """ + # plate size, mm + w = h = 10. + + # 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 + + # 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 + fig, im = create_plot(fig_counter, fig, u, T_cold, T_hot, n, dt) + + # Plot output figures + output_plots(fig, im) + + +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 diff --git a/puranivt_diffusion2d/output.py b/puranivt_diffusion2d/output.py new file mode 100644 index 00000000..2272c11a --- /dev/null +++ b/puranivt_diffusion2d/output.py @@ -0,0 +1,34 @@ +import matplotlib.pyplot as plt + + +def create_plot(fig_counter, fig, u, T_cold, T_hot, n, dt): + """Create one plot for a particular time stamp + + Keyword arguments: + fig_counter -- counter for the subfigure + fig -- matplotlib figure object + u -- matrix of temperature values + T_cold -- value representing cold temperature + T_hot -- value representing hot temperature + n -- value for timestep + dt -- stable timestamp value + """ + 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)) + return fig, im + + +def output_plots(fig, im): + """Outputs all the plots as one figure + + Keyword arguments: + fig -- matplotlib figure object + im -- image for color bar axes + """ + 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() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..449cfaf3 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[build-system] +requires = ["setuptools", "wheel"] + +[project] +name = "puranivt_diffusion2d" +authors = [ + {name = "Vedant Puranik", email = "vedant.puranik@gmail.com"}, +] +description = "A project that implementes the diffusion equation solver over a series of timesteps based on configurable parameters: (dx, dy, D)" +readme = "README.md" +keywords = ["diffusion_equation", "diffusion2d", "puranivt", "SSE"] +classifiers = [ + "Programming Language :: Python :: 3", + "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", + "Operating System :: OS Independent", +] +dependencies = [ + "numpy", + "matplotlib", +] +version = "0.0.1" +requires-python = ">=3.6" + +[project.entry-points.console_scripts] +solve = "puranivt_diffusion2d.diffusion2d:solve" + +[project.urls] +Homepage = "https://github.com/VedantKP/diffusion2D" \ No newline at end of file