# 4. PDE#

## 4.1. Initialization#

To initialize/construct a PDE instance, call the method `ph.pde`

,

- pde(
expression=None,interpreter=None,terms_and_signs_dict=None)[source]#A wrapper of the

`__init__`

method of`PartialDifferentialEquations`

.To make a PDE instance, you can either input

`expression`

and`interpreter`

or input

`terms_and_signs_dict`

If you input

`expression`

and`interpreter`

(recommended), the class will call a private method to parse`expression`

according to`interpreter`

and generates dictionaries of terms and signs.

- Parameters:

expressionList[str]The list of strings that represent a set of equations.

interpreterdictThe dictionary of interpreters that explain the terms in the

`expression`

.terms_and_signs_dictdictThe dictionary that represents the terms and signs of each equation directly (instead of through

`expression`

and`interpreter`

).- Returns:

pde`PartialDifferentialEquations`

The output partial differential equations instance.

For instance, if we want to solve the 2-dimensional linear port Hamitolian problem, i.e.,

for the outer 2-form \(\tilde{\alpha}\) and the outer 1-form \(\tilde{\beta}\) in the domain \(\mathcal{M}\), we make the following expression,

```
>>> expression = [
... 'da_dt = + d_b',
... 'db_dt = - cd_a'
... ]
```

where we have string terms like `'da_dt'`

, `'d_b'`

and so on connected by `'+'`

, `'-'`

and `'='`

.
Since these terms are just strings, the code needs to know
what forms they are representing. Thus, we need an interpreter,

```
>>> interpreter = {
... 'da_dt': da_dt,
... 'd_b' : d_b,
... 'db_dt': db_dt,
... 'cd_a' : cd_a
... }
```

which links the strings, i.e. the keys of `interpreter`

, to the forms, `da_dt`

, `d_b`

and so on.
Note that because here strings that are same to the variable names are used,
this interpreter is a subset of the local variable dictionary
which can be returned by the built-in function `locals`

.
Therefore, alternatively we can use

```
>>> interpreter = locals()
```

Sending `expression`

and `interpreter`

to `ph.pde`

initializes a PDE instance,

```
>>> pde = ph.pde(expression, interpreter)
```

which is an instance of `PartialDifferentialEquations`

,

classPartialDifferentialEquations(expression=None,interpreter=None,terms_and_signs_dict=None)[source]#The Partial Differential Equations class.

propertybc#The boundary condition of the PDE.

propertyderive#A wrapper all possible derivations to the PDE.

- pr(
indexing=True,figsize=(8, 6),vc=False,title=None)[source]#Print the representation of the PDE.

- Parameters:

indexingbool, optionalWhether to show indices of my terms. The default value is

`True`

.figsizeTuple[float, int], optionalThe figure size. It has no effect when the figure is over-sized. A tight configuration will be applied when it is the case. The default value is

`(8, 6)`

.vcbool, optionalWhether to show the vector calculus version of me. The default value is

`False`

.title{None, str}, optionalThe title of the figure. No title if it is

`None`

. The default value is`None`

.See also

- test_with(
test_spaces,test_method='L2',sym_repr: list = None)[source]#Test the PDE with a set of spaces to obtain a weak formulation.

- Parameters:

test_spaceslistThe list of the test spaces.

test_method{`'L2'`

, }, optionalThe test method. Currently, it can only be

`'L2'`

representing the \(L^2\)-inner product. The default value is`'L2'`

.sym_repr{List[str], None}, optionalThe symbolic representations for the test variables. When it is

`None`

, pre-set ones will be applied. The default value is`None`

.- Returns:

wf`src.wf.main.WeakFormulation`

The weak formulation instance.

propertyunknowns#Unknowns of the PDE.

We need to set the unknowns of the pde, which is done through setting the property `unknowns`

,
i.e. `PartialDifferentialEquations.unknowns`

,

```
>>> pde.unknowns = [a, b]
```

To visualize the PDE instnace just constructed, call the *print representation* method, see
`PartialDifferentialEquations.pr()`

,

```
>>> pde.pr()
<Figure size ...
```

It gives a figure of the PDE in differential forms. We can visualize the vector calculus version
if we pass the requirement to `pr`

through keyword argument `vc=True`

like

```
>>> pde.pr(vc=True)
<Figure size ...
```

This is very handy, for example, when your reference PDE is given in vector calculus, and you want to check if you have input the correct differential form version of it, especially in 2-dimensions where the transformation between vector calculus and differential form suffers from extra minus signs here and there.

## 4.2. Boundary conditions#

The boundary condition setting of a PDE can be accessed through property `PartialDifferentialEquations.bc`

.
To define boundary conditions for a PDE, we first need to identify boundary sections. We can define boundary
sections by calling the `partition`

method, for example,

```
>>> pde.bc.partition(r"\Gamma_{\alpha}", r"\Gamma_{\beta}")
```

This command defines two boundary sections whose symbolic representations are `'\Gamma_{\alpha}'`

and
`'\Gamma_{\beta}'`

.
Here they are in fact two 1-dimensional sub-manifolds (recall that in this case the computational domain is
a 2-dimensional manifold).
They are a partition of the boundary, i.e.,

where \(\partial \mathcal{M}\) is the complete boundary of the computational domain (`manifold`

).
Change the amount (\(\geq 1\)) of arguments for the `partition`

method to define a partition of
different amount of boundary sections. Since the `manifold`

itself is abstract, the boundary sections
are abstract as well; thus we can specify, for example,

when we invoke a particular implementation for the simulation in the future.

After we have defined boundary sections, we can specify boundary conditions on them by calling `define_bc`

method
of `PartialDifferentialEquations.bc`

property. For example,

```
>>> pde.bc.define_bc(
... {
... r"\Gamma_{\alpha}": ph.trace(ph.Hodge(a)), # natural boundary condition
... r"\Gamma_{\beta}": ph.trace(b), # essential boundary condition
... }
... )
```

specifies

a natural boundary condition for the outer-oriented 2-form

`a`

on`'\Gamma_{\alpha}'`

,an essential boundary condition for the outer-oriented 1-form

`b`

on`'\Gamma_{\beta}'`

.

Caution

So far, only two types, **essential** and **natural**, of boundary conditions are implemented.

Now, the `pr`

method will also list the imposed boundary conditions,

```
>>> pde.pr()
<Figure size ...
```

## 4.3. Derivations#

We can make changes to (for example, delete, replace or split a term in) the initialized PDE through property
`pde.derive`

which gives an instance of `PDEDerive`

, a wrapper of all possible derivations
to a PDE instance.

↩️ Back to Documentations.