Partial Differential Equations: Exact Solutions Subject to Boundary Conditions
This document describes how pdsolve can automatically adjust the arbitrary functions and constants entering the solution of the partial differential equations (PDEs) such that the boundary conditions (BCs) are satisfied.
|
Two Examples Solved Automatically and Step-by-step
|
|
|
Example 1: Adjusting an Arbitrary Function _F1(...)
|
|
>
|
restart; with(PDEtools):
|
>
|
U := diff_table(u(x,t)):
|
A substance convecting through a tube at velocity c (for example, a radioactive decaying chemical dissolved in water) has its density modeled by a convection-decay type of equation
>
|
pde[1] := U[t]+c*U[x]=-lambda*U[];
|
| (1.1.1) |
where the size of indicates how fast the substance is decaying. In this case, the boundary condition is a generic function of indicating the value of the density at .
>
|
bc[1] := eval(U[], t=0) = phi(x);
|
| (1.1.2) |
|
Step-by-step Solution
|
|
The following is an exact solution for . For now, is not considered.
>
|
sol[1] := pdsolve(pde[1]);
|
| (1.1.1.1) |
Perform the following steps to find the form of the mapping of that matches when
Consider
>
|
e1 := eval(eval(sol[1], t=0), bc[1]);
|
| (1.1.1.2) |
Introduce a new variable q equal to the argument of _F1.
>
|
tr := q = -x/c;
itr := isolate(tr, x);
|
| (1.1.1.3) |
Evaluate at this value of x and then isolate _F1(q). The following mapping is obtained.
| (1.1.1.4) |
>
|
e2 := isolate((1.1.1.4), _F1(q));
|
| (1.1.1.5) |
>
|
ans_F := _F1 = unapply(rhs((1.1.1.5)), q);
|
| (1.1.1.6) |
The solution to the PDE and BC is obtained evaluating the general solution at this value of _F1.
| (1.1.1.7) |
>
|
ans[1] := simplify(eval((1.1.1.7), ans_F), exp);
|
| (1.1.1.8) |
Verify this result using pdetest.
>
|
pdetest(ans[1], [pde[1], bc[1]]);
|
| (1.1.1.9) |
|
Summary: The system of PDEs and BCs is
>
|
sys[1] := [pde[1], bc[1]];
|
| (1.1.3) |
The following is the solution computed by pdsolve automatically by performing the steps explained in the Step-by-step Solution section above.
| (1.1.4) |
The approach used in this example serves also to address nonlinear equations of the form
|
|
Example 2: Periodic Boundary Conditions
|
|
Consider the heat equation that models the temperature
>
|
pde[2] := U[t]=kappa*U[x,x];
|
| (1.2.1) |
where is any constant of proportionality.
Assume that the boundary conditions at and are as follows:
>
|
bc[2] := u(0, t) =0, u(L, t) = 0;
|
| (1.2.2) |
|
Step-by-step Solution
|
|
Similar to Example 1, the following is a solution for . For now, is not considered.
>
|
sol[2] := pdsolve(pde[2], build);
|
| (1.2.1.1) |
This time, pdsolve computes a complete (that is, not the most general) solution using separation of variables. The solution appears in terms of arbitrary constants and the separation variable .
The integration constants can be redefined to consider
>
|
zz := _C1=_C1/_C3,_C2=_C2/_C3;
|
| (1.2.1.2) |
Now, evaluate the solution at and and impose the given boundary conditions to build a system (e1 and e2, so two equations) to be solved for these three constants.
>
|
e1 := eval(eval(eval(sol[2], x=0), bc[2][1]), {zz});
|
| (1.2.1.3) |
>
|
e2 := eval(eval(eval(sol[2], x=L), bc[2][2]), {zz});
|
| (1.2.1.4) |
Solve for the constants.
>
|
_EnvAllSolutions := true;
|
| (1.2.1.5) |
>
|
solve({e1,e2}, {_C1, _C2, _c[1]});
|
| (1.2.1.6) |
The first solution above leads to a solution of no interest: . The second solution above is the one we want.
>
|
ans[2] := eval(sol[2], (1.2.1.6)[2]);
|
| (1.2.1.7) |
Here pdetest verifies the answer for pde[2] and the first boundary condition, but fails with the second one.
>
|
pdetest(ans[2], [pde[2], bc[2]]);
|
| (1.2.1.8) |
However, the answer computed is correct. The second boundary condition can be constructed by evaluating the answer at . This task can be performed within pdetest.
>
|
simplify(eval(ans[2], x=L)) assuming L::real;
|
| (1.2.1.9) |
|
Summary: The system with periodic boundary conditions is
>
|
sys[2] := [pde[2], bc[2]];
|
| (1.2.3) |
The solution computed by pdsolve automatically by performing the steps summarized in the Step-by-step Solution section above. The steps are
| (1.2.4) |
>
|
pdetest((1.2.4), sys[2]);
|
| (1.2.5) |
|
|
|
Notes on this PDE and Initial Values / Boundary Conditions Problem
|
|
Given a problem with PDEs and some BCs, note the following:
•
|
Depending on how you write a general PDE solution, it becomes possible or nearly impossible to adjust it to match the BCs.
|
•
|
Certain particular PDE solutions are frequently easier to adjust than general solutions.
|
•
|
Some combinations, classified in the literature, of "certain types of PDEs" with "certain type of BCs" can be solved systematically by writing the PDE solution in a "certain special form."
|
•
|
By passing PDEs alone to pdsolve, it is not possible to predict the form of the PDE solution. On the other hand, pdsolve accepts a HINT argument so that solutions of a "certain type" can be requested to "some point."
|
|
|
Three Textbook Examples
|
|
A bar loses heat across its lateral boundary at a rate proportional to the temperature and its BCs state that the temperature at the two ends of the bar are equal to 1.
This problem is modeled by the following equation.
>
|
sys[3] := [diff(u(x,t), t) = k*diff(u(x,t), x, x) - a*u(x,t), u(0, t) = 1, u(1, t) = 1];
|
| (3.1) |
| (3.2) |
>
|
pdetest((3.2), sys[3]);
|
| (3.3) |
The following is a textbook example where the solution is computed by constructing an infinite series and then reversed using the boundary conditions to compute a closed formula for the coefficients of the series. The three boundary conditions specify the value of at two points (values of ) and at as a generic function .
>
|
sys[4] := [diff(u(x, t), t) = k*diff(u(x, t), x, x), u(0, t) = 0, u(lambda, t) = 0, u(x,0) = f(x)];
|
| (3.4) |
| (3.5) |
The following is the wave equation with conditions at for and its time derivative , in terms of the arbitrary functions and .
>
|
sys[5] := [diff(u(x,t), x, x) - (1/c^2)*diff(u(x,t), t, t) = 0, u(x,0) = f(x), D[2](u)(x, 0) = g(x)];
|
| (3.6) |
| (3.7) |
>
|
pdetest((3.7), sys[5]);
|
| (3.8) |
|
|
More Examples
|
|
Set infolevel = 2 to receive information on the method used.
>
|
infolevel[pdsolve] := 2;
|
| (4.1) |
>
|
pde[1] := diff(u(x,t),`$`(x,2))-diff(u(x,t),t,t)/c^2 = 0;
iv[1] := (u(x,0) = f(x), D[2](u)(x,0) = g(x));
pdsolve([pde[1], iv[1]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
<- trying "linear_in_xt" successful
<- methods for class "_Fn" for 2nd order PDEs successful
| |
| (4.2) |
>
|
pde[2] := (diff(u(x,t),t) = k*diff(u(x,t), x,x));
iv[2] := u(x,0) = x;
pdsolve([pde[2], iv[2]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
-> trying "BC_equal_0"
* trying methods for class "Wave" for 2nd order PDEs
-> trying "Cauchy"
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Heat" for 2nd order PDEs
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Laplace" for 2nd order PDEs
-> trying a Laplace transformation
* trying methods for class "Fourier" for 2nd order PDEs
-> trying a fourier transformation
<- fourier transformation successful
<- methods for class "Fourier" for 2nd order PDEs successful
| |
| (4.3) |
>
|
with(inttrans, fourier, invfourier);
|
| (4.4) |
>
|
iv[2.1] := u(x,0) = phi(x);
ans[2.1] := pdsolve([pde[2], iv[2.1]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
-> trying "BC_equal_0"
* trying methods for class "Wave" for 2nd order PDEs
-> trying "Cauchy"
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Heat" for 2nd order PDEs
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Laplace" for 2nd order PDEs
-> trying a Laplace transformation
* trying methods for class "Fourier" for 2nd order PDEs
-> trying a fourier transformation
<- fourier transformation successful
<- methods for class "Fourier" for 2nd order PDEs successful
| |
| (4.5) |
>
|
eval(ans[2.1], phi(x) = x^7);
|
| (4.6) |
>
|
pdetest((4.6), [pde[2], eval(iv[2.1], phi(x) = x^7)]);
|
| (4.7) |
>
|
convert(ans[2.1], Int);
|
| (4.8) |
>
|
pde[3] := (diff(u(x,t),t) = k*diff(u(x,t),`$`(x,2)));
iv[3] := u(x,0) = mu, u(0,t) = lambda;
pdsolve([pde[3], iv[3]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
-> trying "BC_equal_0"
* trying methods for class "Wave" for 2nd order PDEs
-> trying "Cauchy"
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Heat" for 2nd order PDEs
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
* trying methods for class "Laplace" for 2nd order PDEs
-> trying a Laplace transformation
<- Laplace transformation successful
<- methods for class "Laplace" for 2nd order PDEs successful
| |
| (4.9) |
>
|
pde[4] := (diff(u(x,t),x,x)-diff(u(x,t),t,t)/c^2 = 0);
iv[4] := u(x,0) = f(x), D[2](u)(x,0) = g(x), u(0,t) = 0;
pdsolve([pde[4], iv[4]]) assuming x > 0, t > 0;
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
-> trying "BC_equal_0"
* trying methods for class "Wave" for 2nd order PDEs
-> trying "Cauchy"
-> trying "SemiInfiniteDomain"
<- trying "SemiInfiniteDomain" successful
<- methods for class "Wave" for 2nd order PDEs successful
| |
| (4.10) |
>
|
pde[5] := diff(u(x,t),t,t)-c^2*diff(u(x,t),x,x) = f(x,t);
iv[5] := u(0,t) = 0, D[1](u)(0,t) = 0;
pdsolve([pde[5], iv[5]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
* trying methods for class "_Fn" for 2nd order PDEs
-> trying "linear_in_xt"
-> trying "BC_equal_0"
* trying methods for class "Wave" for 2nd order PDEs
-> trying "Cauchy"
-> trying "SemiInfiniteDomain"
-> trying "WithSourceTerm"
<- trying "WithSourceTerm" successful
<- methods for class "Wave" for 2nd order PDEs successful
| |
| (4.11) |
>
|
pde[6] := diff(u(x,t),t) = u(x,t)*diff(u(x,t),x,x);
iv[6] := u(0, t) = 0, u(l, t) = 0;
pdsolve([pde[6], iv[6]]);
|
* trying methods for class "_Cn_cn" for 2nd order PDEs
-> trying _Cn_cn
<- trying _Cn_cn successful
<- methods for class "_Cn_cn" for 2nd order PDEs successful
| |
| (4.12) |
>
|
pdetest((4.12), [pde[6], iv[6]]);
|
| (4.13) |
|
Return to Index of Example Worksheets
|