My recent postings have rambled at some length, about the open-source program ‘FreeFem’, the purpose of which is, to solve Partial Differential Equations, which are strictly defined, but which often won’t have exact, analytical solutions. FreeFem approximates their solutions numerically.
My own formal background doesn’t extend much beyond Calculus 2, such that I wasn’t even taught “Ordinary Differential Equations” – aka ‘ODE’s – in a classroom. But what that really means, is just, that I can’t solve one manually. I can still comprehend what problem is being defined, and, given computers that can solve those, can also feed them to my computers to solve.
Of course, ‘PDE’s are more difficult than ODEs, because PDEs are multi-variable.
Long story short, my recent postings have had two main subjects: They have asserted that real-world PDEs, like real-world ODEs, are usually more complicated, than just a form that can be converted directly into an integral. And secondly, I’ve mused over how, then, FreeFem will go about solving them anyway. That second part is speculative.
But, just to make my point, the following is a PDE, which only makes full use of 1 out of its 2 available variables, and which happens to be simple enough, to state a simple integral, but to state it implicitly. Here the FreeFem script:
// For label definition. int Bottom=1; int Right=2; int Top=3; int Left=4; // The triangulated domain Th is on the left side of its boundary. mesh Th = square(10, 10, [(x*2)-1., (y*2)-1.]); plot(Th, ps="ThRectX.eps", wait = true); // Define a function f. func f = x * y; // The finite element space defined over Th is called Vh here. fespace Vh(Th, P2); Vh u, v; // Declare u and v as piecewise P2-continuous functions. // Get the clock in seconds. real cpu=clock(); // Define a PDE, that just integrates f with respect to Y... solve SimpleXInt(u, v) = int2d(Th)( dy(u) * v // Let this be valid syntax. ) - int2d(Th)( f*v ) + on(Bottom, u=0); // The boundary condition at the start of the integral. // Plot the result... plot(u, cmm="Is this an example of the Poisson Equation? f=x*y", ps="SimpIntX.eps", value=true, wait = true); // Display the total computational time. cout << "CPU time = " << (clock()-cpu) << endl;
The way this script works hinges on a simple idea: ‘
dx(u)‘ can accurately be computed by FreeFem as ‘the derivative of (u) with respect to (x)’, and evaluates to a real number. Since it was possible just to multiply a function that also evaluates to a real number by ‘
v‘, and thus form the RHS of the equation, it should be just as easy, to write ‘
dx(u) * v‘ as the LHS. And, after having fixed some minor technicalities peculiar to computing first-order integrals, one can see that this valid syntax computes ‘
f(x,y):=x*y‘, and then integrates it once, in the direction that the Y-axis is positive.
(Updated 7/25/2021, 16h35… )