Poisson's Equation
mattferraro.dev
mattferraro.dev
Edit - it looked something like this:
https://thumbs.dreamstime.com/b/broken-badminton-racket-phot...
Some links for people who've never heard of minimal surfaces:
https://en.wikipedia.org/wiki/Minimal_surface
https://minimalsurfaces.blog/ (lots of illustrations)
https://makmanx.github.io/math3435s18/talks/MSE.pdf (brief intro with historical remarks and illustrations)
[0]: More specifically, it's a solution to Plateau's problem: https://en.wikipedia.org/wiki/Plateau%27s_problem
I'm not saying the badminton racket follows exactly a (discrete) 2D Poisson equation. But it's certainly related enough to be more than a surface similarly.
The cords are under high tension, which means that any curvature along x (that is, dz^2/dx^2) will result in a net z-axis tension force unless balanced by an oppositely curved cord running in the y direction. Since it's in static equilibrium, there can be no unbalanced forces and so that must be the case. Therefore at each intersection, (d^2/dx^2 + d^2/dy^2)z = 0, which is Poisson's equation in 2D for z height being the function. Approximately, assuming equal tension in x and y, small z, and so on.
One can make a similar heuristic argument, though, as to why the surface you observed should follow the minimal-surface equation.
EDIT, as you've updated your comment:
> Isn't Poisson's equation basically describing a minimal surface for small z?
Small changes in z, I think.
I very much appreciate this sort of post.
I may be tripping over something here but this doesn't sound right. If you mean polynomial in the real number sense, i.e.
Lu = a0 + a1 Delta(u) + a2 Delta(u)^2 + ...
(where Delta = Laplacian, and a0, a1, ... real numbers), then is this true? The famous wave operator doesn't have this form.
And if you mean "polynomial" as in a series over function space, i.e.
Lu ~ a0 + a1 Du + a2 D^2u + ... (infinite terms, not equality but convergence)
where D is the usual differential operator and a0 is a number, a1 is a 1-d vector, a2 is a 2d matrix, so on, then this is standard calculus of variations on any reasonable function space. Taylor series for function spaces if you want. I don't think that's limited to nice Galilean operators.
The proof basically goes that commuting with translations implies immediately that L has constant coefficients. Then on the Fourier side applying L translates to multiplying by a polynomial, and commuting with rotations translates to the claim that that polynomial is rotation invariant. And every rotation invariant polynomial in several variables is p(|x|^2) for some polynomial p in on variable. Then on the spacial side p(|x|^2) translates to L = p(laplacian).
Basically the note-taking gizmo is a graph. Nodes are given conceptual masses either through pagerank or betweenness centrality (i.e. either through how many random walks or how many shortest paths cross a node). Then we calculate a potential energy (gravity potential) if we by inverting the graph laplacian (a few methods are available). Special attention is given to nodes that "float the most.
E: forgot to link to it! https://github.com/asemic-horizon/sursis/
In a one-dimensional function, the second derivative is 0 when there is no curvature, aka a straight line (of any slope), and any point on a line is equal to the average of its neighborhood. A plane also has this property, but in 2+ dimensions you can also make other shapes (like saddles), that are made up of lines (like a plane) but the lines are twisted relative to each other in interesting ways (like "string art"). You can also visualize (aka impose a coordinate system for) these surfaces as having positive curvature (concave up) in one direction, and exactly opposite negative curvature (convex up, or concave down) in the orthogonal direction, summing to 0.
Like the transition from the elegant, 5-character Laplace equation to the relatively verbose and complex numerical Julia solver, there is an additional and necessary step in making the numerical solution further scalable with present technology. In particular, the notion that the computational boundaries map nicely to the physical boundaries must be thrown out, because now we must respect the layer of "virtual boundaries" between the partitions.
One of the most impressive programs solved Laplaces equation for heat flow in a pipe. They used some mysterious plotting library that put ASCII art to draw contour lines and output directly to a line printer. I thought it was the coolest thing ever, but it was hard for a high school kid to understand.
Over the years I’ve thought of writing that program in a modern language, but it was never worth the time and effort to go over that FORTRAN program in detail. Numerical methods are too often explained from the point of view of mathematicians and engineers, and not computer programmers.
The blog post here is 1000x more readable and much higher quality and does a lot to demystify the subject. I especially like his progression from simple brute force methods to more efficient solutions…which is the natural way to learn. His comment about “Laplace’s equation just means every point is the average of its neighbours” is perfect.
Believe or it not I was in need of just such a tutorial … for something I’ve been thinking about at work. His article really hit the spot and I’m grateful for it.
Now, I wonder if the author regards it important in his particular area (aerospace engineering), I'm new to the field so I don't see how. Right now I'm reading a book [0] on models to solve problems concerning aerospace applications and they mostly use a simplified form of the Navier-Stokes equations together with some elasticity assumptions.
[0] Fluid Structure Interacion, Morand-Ohayon.
[1] Partial Differential Equations, Evans.
Of course, the author here isn't really selling anything, at least not to the lay man. He's writing niche articles for a niche audience. That is to say, not me.
https://www.ted.com/talks/simon_sinek_how_great_leaders_insp...
The other ways of solving the example of arbitrary heat sources and sinks on a plate range from hacky combinations of simpler methods, to tedious math, to complicated general methods. If you switch from heat to pressure distribution, you'd have the same types of options, but the specific methods would be different.
Some poor soul wrote a somewhat competent and maybe even lengthy blog post / article about something they really care about and are knowledgeable about. It may be directed at a specific audience, or maybe just screaming into the void to record down some insight they had for themselves to read again later, or similar. And they use a more-than-necessary general title like "the best tool you'll ever see" with "you" meaning either just themselves or a narrow target audience or so.
And then somebody comes along who finds it interesting, submits it to HN, it makes front page, and now it looks like the poor author with their more-general-than-needed title is making a general statement about sth for the changed audience which is the HN crowd, but which is distinctly different from the original target audience.
Case in point: The articles author self describes as: "I'm an aerospace engineer that writes software. I love math and science, and I have two cats."
For an aerospace engineer this all makes a lot of sense and is a super great tool, I'm sure. It's just not for the overall HN crowd. And it's not the authors fault.
Anyway, the premise that "everything I see has to appeal to me" would best stay on YouTube where it originated.
The HN crowd has a different average toolbox than the article's author, so the apparent mismatch between headline and article content was confusing.
The first paragraph of the conclusion would have better served as the Introductory remark: "Poisson's equation comes up in many domains. Once you know how to recognize it and solve it, you will be capable of simulating a very wide range of physical phenomena." That is a great sentence. I'm interested now, and I know its context.
Hence the line of questioning. Thanks for the response!
Parent's concern was for the misleading titles that appear on HN, due to HN's fear of submitters.
I found it a throwback to my university years, but I did study Industrial Engineering with thermodynamics, fluid mechanics and whatnot so I did find it interesting. I'm pretty sure it's usable by a bunch of people in HN as well in many fields where software intends to emulate the real world, like designing a smart appliance, games, VR, etc.
That the author himself submitted it (under that original title?) would then be his own "fault". But my general original point remains.
I tried to skim the article, I started to read comments, and it's only now that I've gotten to yours that I have the slightest idea of what this article is even about.
If it wouldn't get as much attention with that title, then perhaps it isn't appropriate for HN in the first place.
The dilemma with titles is that most of them fall into one of two categories:
- titles where the author didn't put much effort into
- titles where the author tried too hard
The first category is often confusing because the article doesn't fit the title well. The second category often ends up as clickbait.
The article seems like a decent introduction to the Poisson-equation. But the original title was very misleading.
Because the Poisson-equation isn't some super-useful tool so much as a Day-1 topic discussed in intro-level classes. It's a really simple equation compared to others used in Engineering, Math, and Physics, so it's often introduced as a starting point.
Brogue's creator also "invented" djikstra maps, which I believe is also exactly the same[0][1], to handle AI strategic pathfinding (e.g. avoid hazards while reaching treasure).
In Game AI Pro (I forget which article/book), someone suggests taking AI preferences (e.g. hunger, health) and computing a flow-field per preference (e.g. a food-map, a danger-map, etc), and multiplying the values against the preference to act as a weight (so food-map * %hunger, danger-map * %health), and summing the maps together to produce the final map used for pathfinding. Notably, the food-map can be shared by all entities consuming the same kind of food -- only the weight has to be re-calculated, and the final sum.
[0] http://www.roguebasin.com/index.php?title=The_Incredible_Pow...
[1] http://www.roguebasin.com/index.php/Dijkstra_Maps_Visualized
In an otherwise excellent article, this is the only issue I could find. We really need to stop using/recommending/normalizing rainbow color maps (i.e. jet). They actively confuse readers by creating visual artifacts that aren't actually in the data.
This article has some great explanations and visuals.
https://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-co...
The original post uses a rainbow color map to represent temperature-related things because having a diverging color map is often a useful intuition for temperature heat maps. But in that case, we should prefer one of the following diverging color maps listed on the matplotlib site (this list definitely isn't exhaustive, but it is helpful).
https://matplotlib.org/stable/_images/sphx_glr_colormaps_004...
More on matplotlib's well-chosen color maps:
https://matplotlib.org/stable/tutorials/colors/colormaps.htm...
For a more technical description the information behind the newer matplotlib defaults, particularly the scipy talk, is great. https://bids.github.io/colormap/
And for those that do not like the matplotlib options, colorcet provides a wider range of alternatives that are not trash (unlike Jet) https://colorcet.holoviz.org/index.html
What’s nice about the Laplace equation is that there are some exact analytical solutions in some situations which is really helpful for validating numerical codes and sanity checking. It’s also simple enough to implement in an Excel spreadsheet, Color coding the cells to indicate temperature. Good sort of “no code” example of the concept.
For these small test cases, however, simply using CHOLMOD (or any other sparse solver) would do the trick perfectly.
You have an invertible square matrix A, a vector b of the same dimension, and you want to find a vector x such that "A*x=b". Then you write "x=A\b", which is like "x=A^(-1)*b" but does not get to compute the full inverse matrix (which is useless).
y1
y2
y3
y4
y5
If the differential equation had a first derivative in it, you'd construct something like this, multiplied by some constant (e.g. 1/(2*dx) for an unscaled derivative): ? ? ? ? ?
-1 0 1 0 0
0 -1 0 1 0
0 0 -1 0 1
? ? ? ? ?
So the derivative at each element is defined by the difference of the next and previous elements. Multiplying the column of function values by this gives you the derivatives. This doesn't work for the first and last element, and in fact you'll usually modify these rows depending on what boundary condition is needed, so I've just left them filled in with "?".For a solver, you don't know what the y values actually are, so you construct a column that corresponds to the right side of the differential equation. For instance, if the equation was something like the trivial dy/dx = c and you were using the operator above the column would be
?
c
c
c
?
with the first and last values to be filled in based on the boundary conditions. You then left matrix divide that by the operator matrix (i.e. multiply it by the inverse of the operator matrix). That gives the solution to the equation.This is just a simple example and in practice the matrices will be larger and more complex.
A is the five-point laplacian (a symmetric matrix with five non-zero diagonals), as implemented in the "step" function in the article, let's call it L
b is the datum h
If you set-up the sparse matrix L and the vector b (with the same code that performs the iterations in the article), then you can solve Poisson equation "L*f=h" by doing "f=L\h".
The \ operator differs from the / operator in that it doesn’t compute an inverse … it solves the system of equations. Solver algorithms are more numerically stable ( in that you’re much less likely to have large errors due to wacky input data).
I'd just say that solving the system of equations is the best way to divide by a matrix — that's why I put air quotes around "divide" above. In Julia, right-dividing matrices (with `A/B`) actually does the smart adjoint-commuting thing to left-divide it and do the solve (with `(B'\A')'`).
using LinearAlgebra, SparseArrays
N = 10
D1 = sparse(Tridiagonal(ones(N-1),-2ones(N),ones(N-1)))
Id = sparse(I,N,N)
A = kron(D1,Id) + kron(Id,D1)
You just use the Kronecker product to build the matrix in the different directions. This, along with the relationship to convolutional neural networks, is described in the MIT 18.337 course notes: https://mitmath.github.io/18337/lecture14/pdes_and_convoluti...Maybe an analogy would better explain my perspective. I imagine that enriquto would greatly appreciate my latest article, reproduced in its entirety below:
# Learn how to write a JSON parser
> j = JSON.parse("[1,2]")
Fin.
I'll state my point following your json parser example. If you write an article about the implementation of several json parsers, you may still want to call JSON.parse at the end, as a sanity check that your implementation is working. The function is right there and you may as well say that!
In the present case, since the author has already set-up explicitly Poisson equation as a linear system of equations, it would make sense to call julia's built-in solver. (If only to marvel that it is much, much faster than the simple methods shown before, thus it must make some really fancy stuff inside!)
The author uses a matrix quite differently. You give it two integer coordinates i and j and it gives you the value at position (i, j) back. That's a valid use, but not quite what you'd expect in a math-oriented article.
A matrix represents a linear function taking a vector and returning a vector, written as
w = M v
Matrix multiplication corresponds to function composition.
Vectors can be indexed, and we can view them as a function i -> v[i] defined on the indexing set. We can also define basis vectors b_i, such that b_i[j] is 1 at index j=i and 0 otherwise. Any vector can be written as a weighted sum of basis vectors, with the vector components as coefficients:
v = Σ_i v[i] b_i
where Σ_i represents summation over the index i.
Matrices can be indexed with two indices, and this is closely related to vector indexing: For a matrix M, we have
M[i, j] = (M b_j)[i]
Each column of the matrix represents its output for a certain basis vector as input. By writing a vector as a sum of basis vectors and using linearity, we get the well-known matrix-vector multiplication formula:
(M v)[i] = Σ_j M[i, j] v[j]
In linear algebra, we would interpret this as a linear map. A true equation would be f([1, 2, 3]^T) = [6, 6, 6]^T (where I'm using ^T to mean "transpose to a column vector").
But here, the author means f(1, 2) = 1, i.e. the (1,2) coordinate of the matrix is 1.
f(i, j) := d_i^T * M * d_j
The RHS is using classical matrix multiplication, and the function value will be the matrix' entry at column i, row j.
> With just a few simple building block we're already edging up on real computational fluid dynamics. All this just by adding up some matrices!
Correct me if I'm wrong, but the only "real" CFD you could solve with this are incompressible potential flows [0]. Solving Navier Stokes is clearly not just "a few tweaks away" from the Laplace equation, but I would be curious which tweaks would take you to e.g. rotational flows.
It amazes me just how many key topics were so inaccessible to the majority of the class at engineering school. I base this on observations from group study sessions and the hyper-aggressive test curves.
I knew lots of people who never got the hang of div/grad/curl, or a Jacobians, or eignenvectors, or Z-transforms... These are key engineering concepts, you'd think colleges would bend over backwards to make sure these concepts are learned as succinctly as possible rather than add a curve to a test that makes a 23 out of 100 an "A" grade.
I'm digressing, and complaining, but the counter argument has always been: you're not supposed to learn everything in college, you're supposed to learn how to learn. Sure, right, but who has time to keep learning advanced calculus after college? (Well, I still study math & physics for fun, but over the course of decades, not years.) Not being able to see the world through these lenses I think means missing key engineering perspectives and relationships.
Anyway, very well written article.
> you're not supposed to learn everything in college, you're supposed to learn how to learn
But to learn how to learn, you gotta learn some things to a somewhat decent degree. I think at some point you need to have these linalg/divgradcurl things down, if only briefly. You might forget any particular topic, but if you've indexed it you should be able to pick it up again, particularly in the modern learning environment.
Just imagine coding without access to StackOverflow.
The up-side is that with a low STR (2:1), the teacher can adapt to the particular strengths and weaknesses of the students, to get the best reinforcement. The /downside/ is that the students will typically also have fewer teachers overall, and are maybe stuck with a bad one. (This is the problem of bad grad school advisors in a nutshell...) In this world, teachers are very expensive, though, so we end up with students competing for access to good teachers, by paying super-high tuitions, dedicating their early childhood to olympic-level basketweaving, etc.
In the medium-STR regime (30:1 or 100:1), we get the worst case: There's no teacher adaptation to individual students, but teachers are still the bottleneck.
The internet has something to say about extremely high STR (1MM:1). In this regime, things flip and any teacher can teach every student: Teachers are no longer scarce, and so have to compete on giving the best instruction. Instruction quality increases as a result. And on the flip side, there's no student competition, which /maybe/ causes student quality to drop.
Not maybe. Absolutely. Even paid-for online courses have a relatively high drop out rate.
But that's okay. It's the price to pay to achieve the volume needed to pay for great instruction. I can take a music theory class from an instructor who would never waste their time teaching someone like me. Even though I may not get much more than entertainment value from it. I'm effectively subsidizing the students who do learn something concrete from the course.
There might be an argument to be made that pandering to an "edutainment" crowd might reduce the quality of instruction, but a good instructor should be able to find the right balance.
If the STR is 2:1 and you've got 1000 teachers, it means you've got 2000 students. If only 5% of teachers are good (see: sturgeon's law), you've still got competition centered on the student side, as 2k students fight to get into the classes with the 50 good teachers.
The main thing distinguishing online education is the ability for students to all flock to the good teachers and completely abandon the crappy ones.
That was the beginning of my career in the PC industry!
C compilers for PCs were in their infancy, so all of the code I was writing was x86 assembly using MASM 6 on MS-DOS 5.2 (hello TSRs and config.sys).
I forget the company, but some tech house published a giant 500 page PC encyclopedia every year that listed all of the x86 CPU instructions, IO ports, interrupts, DOS interrupts, etc. The last issue I had was white with pink lines on it and weighed about 3 kilos! Then the internet showed up and that all went away.
Well, except the mentors. Mentors will always be a step-function way to learn new material.
Skipping over div/grad/curl and Gibbs-Heaviside vector calculus by going straight to differential forms and Clifford algebras (geometric calc) would save a bunch of heartache and pointless effort.
Linear algebra is essential since the whole point of differentiation is to construct linear approximations of functions...among other things.
It's not that there aren't massive lectures, tutorials are in addition to those.
Not bad value actually, despite what I said earlier. You do get to ask about whatever your mental block is, and the tutor is gonna know. But studying is time consuming, an hour is not as much time as it seems. You probably learn the most on your own, which nowadays ought to mean on the internet.
This is very analogous to the problem industrial research groups face trying to answer a certain problem, e.g. ‘how do we ensure that our team is the most likely to solve a particular problem first?’
This is why start up acquisitions are so common even among the best funded tech companies.
Previously, if you were to write a textbook or teach a tutorial, you needed to teach a bunch of things.
So in the internet age there's a bunch of fine grained "best explanations" coming from a variety of authors that beats the best that one guy can do across a range of topics.
Start ups are better than large companies not because the people are so much smarter, but because the structure enables for so much more rapid learning and search of the solution space.
Btw, 3 Blue 1 Brown's videos on linear algebra [1] are similarly awesome and of course his video on Fourier is magnificent [2]. Another awesome math explanation is on game theory by Nicky case [3].
[1] https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2x.... (you'll finally learn what a determinant is!) [2] https://www.youtube.com/watch?v=spUNpyF58BY [3] https://ncase.me/trust/
I stayed curious and learning. Better and better teaching methods became accessible thanks to the maturing internet. I started to understand ideas in engineering much better.
Alas, there is no way I can express this progress in a resume but learning and understanding satisfies my curiosity.
I was struggling with this material more like 15 years ago, but same. I wish someone had explained the LaPlacian like this when I was in Multivariable calculus:
>Find me a function f where every value everywhere is the average of the values around it.
It's so simple and easy to grasp, yet provides so much insight into what's going on when you're doing the actual calculation behind the operation, but is so easy to lose sight of when you're overwhelmed with figuring out the 'mechanics' of it and everything else that was covered in the day's lesson plan.
For people wondering why fresh college grads they interview somehow have 4.0 averages yet can’t code FizzBuzz during an interview, this is the answer.
It’s also why good hiring managers do not even bother to look at GPAs listed on CVs. They are so inflated as to be totally meaningless.
I remember in our real analysis class, the professor started with a comment (to the class) in the lines of:
"This is a demanding class. Top performing students usually spend 25-35 hours a week on the problem sets alone, and top grades are rarely awarded - some years there are zero A's. Please take the weekend to consider if you really need or want to take this class."
FWIW, this was no top University - but then again, grade inflation is not that bad in STEM, from my experience.
The truth, my criteria were: #1: university, #2: GPA, #3: keywords. Sure, I was bitten a few times (I hired an MIT master's student who was utterly helpless), but over the course of years doing this, some patterns emerge, and high-GPA absolutely correlates with good candidates.
Sure, there might be a 2.0/4.0 who is a whiz, but sorry charlie, I'm not gonna picky your resume, so apply yourself or start your own company, because a low GPA means you don't give a shit or have some other problem.
In my own anecdotal experience, I omitted my GPA entirely from my CV when looking for jobs straight out of college and got interviews at every single place I applied. It’s not nearly as important as a lot of people think.
Ironically I graduated with a 3.4, and I did feel guilty for not passing on resumes with GPAs as low as mine. But as I said, when I had many other tasks to do for work, and then had to stop them all to sort resumes (we all took turns), it was hard to justify excursions when there were so many 4.0s. It is a sad truth that new college grads almost all look the same on paper...
When I had actual engineering dept courses on these topics (frequency domain comes to mind), I grok'ed it pretty quickly. But the math lectures were basically spent doing practice problems from the book, without any sort of insight or practical application.
I just wanted to build shit in college.
When I was 12-16, I was interested in physics enough that I would study it in my free time just for fun, solving problems from the Physics Olympiad. I could solve lots of the problems with just intuition, until I stumbled upon the sliding chain problem. I spent about a week pondering over it with no results. I approached my math teacher. He admitted defeat and referred me to the physics teacher. If I remember correctly, the physics teacher avoided admitting he didn't know how to solve it and didn't give me any pointers. That was the last Physics Olympiad problem I tried to solve, after dreaming of attending the competition for years (I should mention that at that time my primary interest already were computers; physics was just a hobby). I wonder whether this could still be a problem today when anything can be found on YouTube. There's a lot of noise, too. How long does it take the average curious kid to find the signal that is 3b1b, MIT OCW, etc?
School is not about learning. It's about money. Seating as many students as possible for as long as possible to suck in as much student loan money as possible. For this you need to be a prestigious school. Of course they want to boost their grades.
These are the people who have the gall to claim a moral high ground when they find and punish "cheaters".
Sometime the prof screws up and the test is too hard where the aveage grade is 30. Sometimes some over-achieving git 'busts the curve' and scores a 95 and the next highest grade is a 60 - making it hard for the prof to justify giving A's to the top 10%
Even if teachers use a different method, the term has stuck as a synonym for "grade adjustment".
I only had a few actually do this, usually it's just a fixed amount bump given to everyone's grade.
Only 2 or 3 times did I have a teacher curve grades down.
One exam was really hard such that your new grade was sqrt(#correct/#total). Another was to make new total the value of highest correct score, e.g. everybody in class got 0-20 out of 100, new total is 20.
> these concepts are learned as succinctly
? Succinctness is *why" you didn't learn multiple interpretations of everything.
Good catch. I think that was the wrong word because I was learning s-transforms in three classes sophomore year: differential calculus, linear systems, and thermodynamics. It was the opposite of succinct because the same concept was being thrown at me in three different classes from three different perspectives.
When you take a class, you see one wrong way to do things. When you teach a class, you see fifty wrong ways to do things.
Puzzling through all the different wrongs ways to think about a problem really helps cement the core ideas... And first-year calc students are masters of creating interesting-but-wrong interpretations.
My understanding of airflow simulation (undergrad-level at best) is that the correct boundary condition is almost without exception the no-slip one: air should be stationary at the surface of each object, not just have zero flow across it.
Am I correct that the calculation mentioned above really only applies to the "dry liquid" scenario where there is no drag and zero viscosity?
http://ddg.cs.columbia.edu/SGP2014/LaplaceBeltrami.pdf
“The Swiss Army knife of geometric operators.”
I always thought that was cool since I usually think of diffusion in the context of fluid flow.
https://www.cs.cmu.edu/~kmcrane/Projects/MonteCarloGeometryP...
Can someone elaborate on that? The Wikipedia article (https://en.wikipedia.org/wiki/Biharmonic_equation) does not mention anything about quantum mechanics use cases for the biharmonic equation.
can lead you to some fun places.
I have a CS background, but no physics/aerodynamics background. What are the minimum additional steps beyond this tutorial which could produce an aerodynamically correct 2D wing simulator? (With turbulence, not a steady-state solution.) I've come back to tackle this topic intermittently but have never cracked it. To anyone with expertise here who could share an overview and links, I'd be grateful.
But that won't handle turbulence. The real "turbulence problem" is that computing actual turbulent flows requires enormous computational resources. So instead of solving the Navier-Stokes equations, related equations with lower computational cost are solved. Because of how these equations are developed, they require modeling of "unclosed" terms, and this is a likely source of inaccuracy.
If you want something relatively simple, you could take the RANS approach and use the Spalart-Allmaras model:
https://www.cfd-online.com/Wiki/Introduction_to_turbulence/R...
https://www.cfd-online.com/Wiki/Spalart-Allmaras_model
How to implement the changes to the final part of Lorena Barba's tutorial should be fairly obvious by the time you get there.
A great article, one to bookmark for sure.
What confused me is that the author is not treating the matrix as a function from vectors to vectors, as is the customary way to treat matrices as functions. Rather, they're using the matrix to represent a sparse, regular sampling of a function from vectors to scalars.
---
This article makes no sense right off the bat. Here's the first substantive passage:
"[Laplace's Equation means] Find me a function f where every value everywhere is the average of the values around it ... In this post, when we talk about a function f we mean a 2D matrix where each element is some scalar value like temperature or pressure or electric potential ... If it seems weird to call a matrix a function, just remember that all matrices map input coordinates (i,j) to output values f(i,j). Matrices are functions that are just sparsely defined. This particular matrix does satisfy Laplace's equation because each element [of the matrix] is equal to the average of its neighbors."
The values of a function are the outputs it maps its inputs to. The elements of the matrix are neither inputs nor outputs.
Take, for example, f(x) = x*x. Its matrix would be: f = [0, 1, 4, 9, 16].
Given the arguments to the function, locate the cell in the matrix and use its value as the result of the function.