Modeling Electromagnetic Fields Using Differential Equations
Advisor: Mr. Andrew Magee
Onsite Mentor: Ms. Simran Brar
Electromagnetic fields appear in every aspect of our everyday lives, impacting not only the domain of computing and communications technologies but also those of health and environmental safety. Devices emitting EM fields are used in communication, medicine, cybersecurity, and so on. EM fields are typically produced by current-carrying circuits and electrical charges, and modeling the behavior of the EM fields produced by a circuit setup can help identify the possible effects of the circuit on its surrounding environment as well as reveal weaknesses in the circuit’s performance. The behavior of EM fields, however, is immensely complex and often requires computer simulation. This project aims to develop an open source program written in C/C++ to simulate electromagnetic fields. The software will be developed to prioritize versatility and open access, allowing for students and independent users to conveniently adapt the software to their own uses.The EM fields are modeled using differential equations, specifically Maxwell’s equations of electromagnetism. Solutions for those equations, given a set of initial conditions determined by the user, are then found through algorithms that solve the equations numerically. By developing an open source version of the simulation software, students and researchers will be able to access the necessary tools for their projects without having to spend hundreds of dollars on proprietary software.
Project Blog
Week 0: Introduction
Hello everyone! This is my first senior project blog post. Today, I will be discussing the basics of my project, an open source program for simulating electromagnetic fields. I will be working on this project in the next couple of months, so watch out!
Throughout my years studying CS and physics, I’ve always been particularly interested in computational physics, or the application of computer algorithms to analyze the behavior of physical systems. Moreover, my favorite topic in physics has always been classical electrodynamics, which is governed ultimately by Maxwell’s equations. This set of differential equations is both elegant and powerfully predictive, allowing for an explanation of phenomena ranging from diamagnetism to EM waves to polarization in charged molecules.
With the rising need for innovation in computing and communications hardware, engineers and designers have an urgent need to simulate the electromagnetic fields produced by prototyped systems in order to properly design efficient and safe hardware. Because most electromagnetic field simulation software is proprietary and expensive, this puts independent tinkerers at a disadvantage. My software will aim to provide every curious-minded person with the resources to develop an understanding of EM fields.
To start my project, I plan on doing two weeks of research to review my knowledge of classical electrodynamics and determine the tools and methods that I need to understand in order to build the software. From there, I will then begin to plan out the general structure of my software and the individual components. I already have a general idea of what I need, for instance a solver algorithm and a workable user interface. I’ll start coding after I plan sufficiently. In the months that I have, I aim to complete, test, and optimize my software to produce a fully working EM field simulator in C++.
For curious minded people who want to learn about EM fields and even tinker around with circuits and charge setups, the options for EM field simulation are severely limited, with the playing field dominated by overpriced proprietary software. I plan on producing a workable open source alternative that allows anyone motivated enough to pursue their interests in physics. If you want to keep reading, see you people next week.
Week 1: Learning the Theory
Hello my fellow human beings. Welcome back to my blog, where I will be tracking my progress on my EM field simulation project. This week, I worked on reviewing some theoretical knowledge on the behavior of electromagnetic fields. This knowledge will be necessary in the future when I develop, test, and debug the simulation algorithm.
For the first two days, I reviewed the basics of electrostatics. This subfield of electrodynamics aims to describe the behavior of electric fields when all the charges are at rest (hence electrostatics). The main building blocks of electrostatics are Gauss’ Law and Coulomb’s Law. Both laws relate the behavior of the electric field to the distribution of the electric charge producing the field. Together, the two laws predict that the electrostatic field is both spherically symmetrical and, like the Newtonian gravitational field, obeys the inverse square law.
Gauss’ Law is Lorentz invariant, which means that the law remains the same when shifting relativistically from one inertial frame to another. Coulomb’s Law, however, is not Lorentz invariant. This means that electrostatic theory fails for moving charges. As we take into account systems of charges moving relativistically, the situation becomes more complicated. According to Maxwell’s equations, charges moving relativistically produce both electric and magnetic fields. Moreover, the force experienced by a charge moving through an EM field is given by the Lorentz force law, which essentially expresses that the total force can be divided into a magnetic and an electric force.
For the next two days of the project, I reviewed the basics of magnetostatics, which investigates the behavior of magnetic fields produced by steadily moving charges. The main building blocks of magnetostatics are Ampere’s Law and the Biot-Savart Law, which are essentially analogous to Gauss’ Law and Coulomb’s Law for electrostatics. Together, these laws state that magnetic fields arise from moving charges and that there are no magnetic monopoles.
Of course, both magnetostatics and electrostatics are both subsets of the full theory of classical electrodynamics in which certain assumptions are made to simplify the physical analysis. However, situations in both areas are easy to solve by hand and offer a more intuitive understanding of electrodynamics. This makes electrostatic and magnetostatic systems optimal for constructing simple tests for my algorithm.
In my next week, I will review the other two Maxwell’s equations (in addition to the ones we already have reviewed, which are Gauss’ and Ampere’s Laws). Moreover, I will begin finding and comparing algorithms for solving Maxwell’s equations. Goodbye, my fellow human beings.
Week 2: Learning More Theory
Hello readers! Welcome back to my blog, where I will be tracking my progress through my EM field simulation project. This week, I researched numerical methods for finding solutions to Maxwell’s equations. Knowledge of the available algorithms for solving Maxwell’s equations will allow me to implement the core of my project: an efficient, stable, and accurate simulation program.
In order to understand the numerical methods needed to solve Maxwell’s equations, I first needed to develop a good understanding of the equations themselves. There are four equations in total:
All four of the equations are PDEs (partial differential equations) involving the partial derivatives of the E and B fields with respect to time and space. Some of these equations should look familiar; (1) is Gauss’ Law, while (4) is the Ampere-Maxwell Law, which is the generalization of Ampere’s Law to systems with changing electric fields. As for the unfamiliar-looking ones, (2) essentially states that magnetic monopoles cannot exist and (3) is Faraday’s Law, which states that a change in the magnetic field will create an induced electric field.
To solve this system of equations given some initial values, we can use the Finite-Difference Time Domain (FDTD) method. As apparent in the name, the FDTD method makes use of a technique called finite differencing. With finite differencing, continuous space (or space-time) is replaced by a discrete lattice. In this discrete space/space-time, derivatives with respect to space and time are represented as discrete differences. The time evolution of the system can then easily be calculated using the finite difference equations (which now resemble recurrence relations for a discrete sequence).
One of the most popular FDTD algorithms for solving Maxwell’s equations is Yee’s algorithm. First proposed in 1966, the algorithm uses finite-differencing to approximate to 1st order accuracy the behavior of EM fields in an uniform medium. One of the main optimizations of Yee’s algorithm is the staggered grid method, which calculates E and B at staggered lattice points in space (visualized below).
While the algorithm is easy to implement and reasonably efficient (requiring no matrix operations!), the stability of the algorithm depends on the ratio between the temporal and spatial step sizes (fun fact: the stability condition is an instance of a Courant-Friedrichs-Lewy, or CFL, criterion). Moreover, algorithms have been proposed with higher orders of accuracy and greater adaptability to different geometries than Yee’s algorithm. These include finite element methods and time integration algorithms, the latter of which does away with discretization completely.
My initial implementation will use Yee’s algorithm because it is the easiest to implement. After the initial implementation, however, I will also experiment with more complex algorithms and compare their performances. Next week, I will start by setting up the development environment before implementing and testing a simple Maxwell’s equation solver. Wow! How exciting! See you next week.
Sources:
https://engineering.purdue.edu/wcchew/ece604f20/Lecture%20Notes/Lect37.pdf
https://home.cc.umanitoba.ca/~lovetrij/cECE7810/Papers/Yee%201966%20HiRes.pdf
Week 3: (Finally) Implementing Yee’s Algorithm
Hey friends! Welcome back to my blog, where I’ll be tracking my progress on my EM field simulation project. We left off last week with a comparison of the different algorithms commonly used to find solutions to Maxwell’s equations. Out of the variety of available methods, Yee’s algorithm looked promising as a realistic starting point. I promised to implement Yee’s algorithm in this week’s blog, and I’m glad to say that this task has been completed. In this blog, I’ll be focusing less on the theoretical aspects of Yee’s algorithm (which were covered in last week’s entry). Instead, I’ll focus on the technical aspects of implementing Yee’s algorithm.
Despite its apparent simplicity, Yee’s algorithm looked relatively challenging to implement, especially in 2D. Thus, I decided to start with a 1D version of the algorithm to map out the general ideas of the algorithm and find any potential roadblocks I would face during implementation.
Finite Differencing
The program stores the calculated E and B fields in multidimensional arrays. Because we are working in 1D space with an additional dimension of time, the arrays need to be two-dimensional. The fields at each time step are calculated using our information about the fields at previous timesteps. The implementation is very similar to most standard dynamic programming problems.
Staggered Grids
The above image shows how the B fields are calculated. The outermost loop steps through time, while the inner loop iterates through the different x-values. The indexing may look strange because of how I chose to implement the staggered grid, but notice how the time-derivative of the B field is related to the x-derivative of the E field. This resembles the relation between the fields as apparent in the finite difference equations we studied last week.
Moreover, as we found out last week, Yee’s algorithm uses a “staggered grid” to calculate the E and B fields at discrete points in spacetime (shown below). However, we cannot have fractional indices in our arrays, so directly implementing the staggered grid will have to take some creativity.
For my program, I shifted all the half-indices in space to the left by half a unit.
I’ll explain further. Looking at the diagram we can see that the B field is calculated at fractional length indices. In order to store the B field in an array, we then assign index 0 in the array to x = 0.5, index 1 to x = 1.5, and so on. This solves the problem of implementing the staggered grid.
Testing
I tested my program with a variety of physical situations such as sinusoidal EM waves and interfering wave pulses. Although my program generally worked well, it was limited greatly by the CFL stability condition, which put a limit on the timestep size. This meant that to simulate evolution over a longer period of time, I had to extend the number of timesteps, increasing the time and space complexity of the program. Also, because I ran out of time, I didn’t properly implement boundary conditions, which meant that the simulation sometimes came up with strange solutions.
I also implemented Yee’s algorithm in 2D, but I mostly expanded on the 1D version here because it’s the same as the 2D version but easier to explain. Next week, we will work on improving the algorithm and testing out other algorithms. Bye!
Week 4: Implementing a 3D EM Field Simulator
Hello and welcome back to my blog, where I’ll be tracking my progress on my EM field simulation project. Last week, I finished implementing the Yee algorithm in 1D and 2D. In addition to the obvious limitation of having less dimensions, our program also had various drawbacks such as lack of support for inhomogeneous media, crude boundary conditions, no support for lossy media (such as dielectrics), etc.
This week, I implemented the 3D Yee algorithm with a focus on adding greater functionality to our so-far simple simulation. This means that along with the challenge of translating our original simulation into 3D, I had to experience even more loss of sanity by implementing completely new concepts into our program.
Structuring the Program
Not much thought was given into structuring the actual program with the 1D simulation due to its simplicity. The entire program was stored in one file and the entire simulation process was implemented in the Simulation class. Now, with the intent of adding more functionality to the simulation, I have to (unfortunately) structure the whole program with modularity, readability, and maintainability in mind.
To make the program more modular, I’ve isolated the part of the program responsible for updating and storing the Yee grid. This way, I can implement complex features such as boundary conditions without having to change the constant part of the program.
Yee Grid in 3D
After giving some thought to the overall structure of the program, I started looking at the details for implementing the 3D Yee grid. As I’ve mentioned, the Yee algorithm discretizes the EM fields by storing them in a staggered grid, with some fields being stored at half-steps in space. Having implemented the staggered grid before, all I had to do was generalize it to 3D. The 3D simulation now has to calculate all 3 components of both fields. The arrangement of the fields on the Yee cell is shown below, with the electric fields on the midpoints of the edges of the cell and the magnetic field components on the faces.
The update equations for the program remain the same, just generalized to 3D (there’s also more of them because we now have 6 field components to update). Once again, the equations are derived by discretizing Ampere’s and Faraday’s Laws.
ABC (Absorbing Boundary Conditions)
In order to avoid having our fields reflect back at the boundaries, we must have a boundary condition that completely absorbs the field. This way, the simulation appears to be surrounded by infinite space.
There are several types of ABCs, and I chose to implement a first-order ABC based on the Advection Equations (shown below):
A solution to either advection equation is also a solution to the wave equation, which dictates how an electric/magnetic field propagates in free space. Essentially, the ABC works by using the advection equation to predict the behavior of the fields near the boundary in order to calculate the values needed at the boundary to absorb the incoming field. Once again, the calculation is performed by discretizing the differential equation.
TFSF (Total Field Scattered Field) Boundary
Another kind of boundary condition I implemented was the TFSF boundary. The purpose of this boundary condition is to allow the presence of an incident field within a restricted area of the simulation. The TFSF boundary is implemented by dividing the total simulation area into two regions, the total field region and the scattered field region. In the total field region, an incident field term is added to the update equations to simulate the presence of a source. The incident term can be calculated analytically, but in some cases, a subsidiary Yee algorithm can be used to track the evolution of the incident term before plugging it into the main algorithm.
Conclusion
Thanks for reading the whole thing! In the next week, I will finish up my implementation and show some EM field simulations in 2D and 3D. Stay tuned for the results!
Sources:
Week 5: Making a (Somewhat) Complete Implementation
Hello everyone, and welcome back to my blog. Today I have some very exciting news: most of the core aspects of my simulation program have been implemented! My blog today will focus on the process of implementation and the challenges I faced along the way.
Implementing the Grid class
The most important part of the simulation program is the Grid class, whose task is to calculate and update the fields using the discretized Ampere and Faraday’s Laws (essentially a 3D implementation of Yee’s algorithm). I’ll refrain from discussing any theoretical details of Yee’s algorithm here, but here is a good source if any readers are feeling curious.
In 3D, there are 6 field components to be calculated. Thus, every Yee cell now has six different field values to be stored (shown above). In theory, all of the components are offset by half spatial steps, but the halves are suppressed in practice so that all of the members of the Yee cell actually have the same indices.
Another aspect of indexing that I had to be careful of was setting the proper 3D array sizes for the fields. Notice that the E fields (black circles in the image above) “stick out” in the direction they face while the H fields (white squares) “stick out” in the two directions the field doesn’t face. For example, the Ex field is offset a half-step in the x-direction, while the Hx field is offset a half-step in the y- and z-directions. This means that if the grid is M blocks wide in the x-direction, the grid of Ex field values would only be M - 1 blocks wide. Applying this logic to all the fields, we have the below code for initializing the grid:
(Here, _init_3d_array is a helper function to initialize a 3D array with the given x, y, and z dimensions)
Moving on, I then implemented the update equations for the fields. The code below is the update equation for the x-component of the E field. ExE and ExH are grids storing scalar coefficients, while Ex, Hy, Hz are grids for storing the values of the respective field components. The rest is pretty self-explanatory, and particularly curious/motivated/masochistic readers can compare the code to the theoretical update equation for some more clarity.
Adding Boundary Conditions and Sources
After implementing the Grid class, I was ready to add some basic field sources and boundary conditions to test the simulation. As promised last week, I implemented a simple ABC (absorbing boundary condition) based on the advection equations. To make coding easier in the future, I first coded a BoundaryCond class that all boundary conditions have to inherit from. Notice that each boundary condition has to bind itself to a Grid in order to be usable. Moreover, the update() method allows for each unique boundary condition to have its own custom update equations.
The FirstOrderABC class inherits from BoundaryCond (nothing special there). The hardest part of implementing the ABC was making sure the implementation of the update equations was bug-free. To show a bit of what I mean, here’s the code for updating the fields along the YZ oriented boundaries of the simulation space:
For the more insane readers out there, here is a good explanation of how ABCs work in full detail. Although it may be hard to tell at first, the code above resembles the advection equations I showed last week, but this time discretized and rearranged to solve for a particular term (it might be helpful to note that EyX0 stores the Ey fields at the X = 0 boundary of the simulation space at the previous timestep, and so on).
I also implemented (with much less frustration, to my relief) some EM wave sources. Right now, all the sources I use are additive sources, meaning that a value is simply being added onto certain points in space at given times (as opposed to using a TFSF boundary).
The code is pretty self-explanatory; I’ve implemented one sinusoidal waveform and one Ricker wavelet:
Visualizing the Simulation
Visualization is one of the most important tasks of the simulation program. Without proper visualization, it would be hard for users to decipher the results of the simulation.
To effectively visualize the simulation, I wrote a program to take “snapshots” of 2D slices in the 3D simulation grid at given instants in time. The snapshotting is performed by the snapshot method of the GridVisualizer class, as shown below:
The argument “dim” refers to the dimension along which the 2D snapshot slice is taken and “slice_index” refers to the coordinate along the chosen dimension to slice the grid. So for instance, if dim = 0 and slice_index = 10, the snapshot would be of the YZ plane at the coordinate x = 10. An example of what a snapshot would look like is shown below.
By compiling many snapshots together, a GIF of the field’s evolution over time is created. Shown below is the visualization of the Ex field of an electric dipole:
Here’s another one, but it’s the Hy field of the electric dipole:
Conclusion
Thanks for reading my blog all the way through! If you want more insight into the details of all the theory behind my code, you can take a look at the sources below (or look at my GitHub repo https://github.com/switchpiggy/yee-algorithm). Have a great day! (Make sure you get some sunlight, especially after experiencing the ordeal that is reading my blog).
Sources:
https://eecs.wsu.edu/~schneidj/ufdtd/
https://github.com/flaport/fdtd?tab=readme-ov-file
https://engineering.purdue.edu/wcchew/ece604s20/Lecture%20Notes/Lect37.pdf
(Next up: Perfectly Matched Layers, Objects)
Week 6: Finishing up the Algorithm (and Next Steps)
Hello everyone, and welcome back to my blog. Today I have some very exciting news: I’ve finished coding most of the features that I’ve planned to implement, including PMLs (Perfectly Matched Layers) and simulating objects. This week, I’ll be giving a quick overview of the new features as well as discussing the challenges I encountered while implementing them. Also, I’ll be discussing my plans for deploying the algorithm as a web app.
PML (Perfectly Matched Layer)
A PML, or Perfectly Matched Layer, is essentially a more powerful version of the simple absorbing boundary condition we implemented earlier. The PML works by introducing a lossy layer in order to absorb all fields normal to the boundary surface while allowing the tangential fields to remain intact. For more on the unnecessarily brain-damaging math, read this.
Disclaimer: my PML is not actually properly implemented and the code is buggy. When implementing the PML, I spent hours trying to find the bug but nothing came up. It’s also really hard to debug the program when I have to implement my own test cases, so hopefully I will find the bug by the end of next week.
Implementing Objects
So far, all of our simulations have been in free space. This means that we assume the relative permeability and emissivity to both be equal to 1 and for there to be no loss (electric and magnetic conductivity are equal to zero). This places a limit on the versatility of the simulation software. Because of this, I wanted to implement a feature that would allow objects such as conductors and dielectrics to be placed into the grid for simulation.
There are a wide variety of objects to implement, but ultimately all of them have some common features. For instance, each object has a certain domain in space in which constants such as permittivity and conductivity have specially modified values. To implement objects, I first coded a general Object class from which different types of objects could inherit.
The Object class allows for objects to specify their spatial domain as well as custom update parameters and even custom update equations. For instance, a PerfectConductor class that inherits from the Object class can set the electric fields inside its spatial domain to zero using custom update equations.
Conclusion
All of the core features of my algorithm are now complete. The next step is to give access to the algorithm to a wide audience through deploying a web app and designing an effective UI. In the coming weeks, I will shift from a computational physics perspective to a more software-design based perspective as I prepare my algorithm to be effectively deployed. For any readers who wish to see the full code, come here. Otherwise, stay tuned!
Sources:
https://eecs.wsu.edu/~schneidj/ufdtd/
https://github.com/flaport/fdtd?tab=readme-ov-file
https://engineering.purdue.edu/wcchew/ece604s20/Lecture%20Notes/Lect37.pdf
https://ijariie.com/AdminUploadPdf/TFSF_boundary_implementation_in_the_FDTD_Algorithm_for_the_Study_of_the_Propagation_of_Electromagnetic_Waves_in_Vacuum_ijariie10883.pdf
(Next: Coding and Deploying the Web App)
Week 7: Making a Web App
Hello everyone, and welcome back to my blog. Today, I’ll be starting the next step of the project, which is to implement the algorithm into a web app that will allow users to experiment with simulations.
Before I start talking about the web app, I’d like to reiterate the purpose of the project (which we may have forgotten with all the theoretical junk I’ve been throwing at readers for the past 6 weeks). The purpose of my project is to create an open source program that will allow users to simulate EM fields. Right now, I’ve finished researching and coding the core algorithm that will actually perform the simulation. What remains is to create a web app with an interface that will allow the user to interact with the simulation’s backend. I’ll talk today about my design process and a few problems that I’ve anticipated.
Hosting
This is probably the easiest “problem” to solve. As usual, I’m going for the simplest option and I’m probably gonna host my app through a service like Heroku or Vercel.
Choosing Frameworks/Libraries
Choosing is always hard, especially when there’s an overwhelming amount of options. In order to narrow down the tools that are right for me, I’ve decided to use my web development experience as a main factor. The main languages that most web development frameworks use are Javascript and Python, but development in Javascript is frustrating because of how poorly made the language is. Moreover, in this situation where I’m quickly developing a simplistic app, I have to prioritize usability over more complete features and customizability in my tools. This is why I’ve decided to go with an easy-to-use and well documented Python framework called Django for my app backend. As for the frontend, I’m going to avoid using any fancy tools altogether and instead have a simple HTML/JS page (It’s going to look janky but the real beauty of my app lies in my algorithm anyways).
Designing the Backend
When designing the backend, I have to keep in mind where and how users should access the algorithm. Moreover, because the algorithm is quite computationally heavy, I must estimate how much load the server can handle and design my backend around that (so that my server doesn’t keep crashing).
As a good first step, I’ve coded a simple app backend that allows users minimal customizability (almost none), upon which I will build up layers of usability depending on how I anticipate users will want to use the simulation.
Conclusion
If you’ve made it this far, we’re almost at the end! We’ve already slogged through all of the theoretical physics-y parts of the project. All that remains is to make a well-designed app to showcase the algorithm’s usefulness. Stay tuned!
Sources:
https://eecs.wsu.edu/~schneidj/ufdtd/
https://github.com/flaport/fdtd?tab=readme-ov-file
https://engineering.purdue.edu/wcchew/ece604s20/Lecture%20Notes/Lect37.pdf
(Next: Building the Web App)
Week 8: (Actually) Making the Web App
Hello everyone, and welcome back to my blog. Today, I’ll be continuing with the next step of the project, which is to implement the algorithm into a web app that will allow users to experiment with simulations.
This week, I’ve implemented a simple web app that will allow itself to easily be expanded into a fully functional app with versatile configurations for simulating a wide variety of systems.
Hosting
I’m talking about hosting first just to get it out of the way because it’s not really that important. I’m using Heroku to host the entire project, but for development purposes, I’m going to be testing everything on my local machine before putting it onto the production server.
Minimalistic Frontend
The frontend of the web app is the part that interacts with the users. In this case, I’ve made a simple webpage that allows the user to configure and run EM field simulations from their browser. As I’ve mentioned last week, the entire webpage is written in pure vanilla HTML/JS. One of the problems with not choosing a more complex framework such as ReactJS is that my webpage ends up with less aesthetic appeal than I would’ve liked (but it’s okay).
Below is an early version of the website. I started by implementing one button to run a default simulation and an empty configuration form that I would later fill in.
Later, I filled the configuration form with some simple attributes such as the dimensions and maximum timesteps of the simulation. The result is shown below.
The code for the config form is also quite simple. All I had to do was look up some documentation for the HTML input element and I ended up with a nice looking form for my webpage.
(Not so minimalistic) Backend
Now that I’ve coded the frontend, it’s time to make all the pieces fit together by connecting it to my backend server where the algorithm is actually run. The backend implementation is significantly more challenging than the frontend, so I’ll talk more in detail about it.
The server communicates with the browser through exchanging HTTP requests. Essentially, the browser sends a request to the server to retrieve or modify information stored on the server. The server then processes the request and determines the correct response, which is then sent back to the browser.
Thus, the first logical step to constructing our backend would be to allow it to process incoming HTTP requests. Thankfully, I’m using the Django framework which has a built-in system for conveniently processing requests and generating responses. When a request comes to an address on the server, Django uses the request URL to route it to essentially what is a specific Python function that generates a response to the request. For instance, here is the function to which the “/sim” URL is routed to. The below function is responsible for running simulations on the server when the frontend sends a POST request to the server with the given configuration in the request body.
Of course, once we’ve set up the backend to receive requests, we also set up the frontend to send requests. I’ve implemented a JS function that runs when the “run” button is clicked which sends a POST request with the correct formatting to the server.
When the simulation is finished running on the server, the server returns a GIF of the visualized simulation back to the frontend to display.
To summarize, the user interacts with the frontend by configuring the simulation and pressing the run button. When the run button is pressed, an HTTP request is sent to the server, which upon receiving the request runs the simulation with the given configuration. The result of the simulation is then returned to the frontend and displayed back to the user.
Conclusion
If you made it this far, we’re almost at the end but not there yet. There’s still a lot more work to do before we have our final product but the end is in sight! Next week, I’ll finish up the web app and deploy it to Heroku, as well as talk about the troubles I’ve encountered when coding. Thank you and see you next week!
Sources:
https://eecs.wsu.edu/~schneidj/ufdtd/
https://github.com/flaport/fdtd?tab=readme-ov-file
https://engineering.purdue.edu/wcchew/ece604s20/Lecture%20Notes/Lect37.pdf
(Next: Finishing the Web App)