Boundary Conditions

Currently, TensorDiffEq contains built-in support for Dirichlet and Periodic BCs, with expanded support coming in the near future

The boundary conditions described generate additional terms in the loss function to allow for enforcement of those boundaries in the final solution. Therefore, one simple needs to describe all the boundaries in your problem, put them into a list so that TensorDiffEqs solvers can iterate through them, and allow the solution to train.

Boundary conditions have similar structure, and dont return anything once initialized. Once fed into the solver, however, the boundary conditions described by the user are enforced in the solution.

Dirichlet BCs

Dirichlet BCs enforce a function at a particular boundary. These BCs are useful to “inject” heat into a boundary, for instance, or to hold the end of a spring constant.

Initialize

Dirichlet BCs are initialized in the following fashion:

dirichletBC(domain, val, var, target)

Args:

  • domain - a domain object containing the variables in the domain

  • val - a float containing the value to be enforced at the boundary

  • var - a str indicating which variable should be enforced by the value in val

  • target - a str indicating whether the value listed in val will be targeting the upper or lower boundary on var

to create a simple dirichletBC, one could define upper and lower boundary values on the x value from the IC definition section

upper_x = dirichlectBC(Domain, val=0.0, var='x', target="upper")
lower_x = dirichlectBC(Domain, val=0.0, var='x', target="lower")

This will force the upper and lower boundary value of 0.0 on the upper and lower boundaries of x for a 1D spatio-temporal problem.

Note

Currently TensorDiffEq doesn’t support functions as Dirichlet BCs. In the near future this will be a feature and will contain a similar interface as the IC function definition. Bear with us as we add features to help you solve your problems!

Periodic BCs

Periodic BCs in TensorDiffEq allow for fine-grain control over the depth to which the derivatives at your boundaries go. Many periodic BC implementations in other PINN solvers only allow for the zero-order derivative (no derivative) as a member of the loss function in their solvers. TensorDiffEq allows for arbitrary depth and fine-grain control over which derivatives are included in the final calculations.

Initialize

periodicBC(domain, var, deriv_model)

Args:

  • domain - a domain object containing the variables in the domain

  • var - a list of str values indicating which variables should be enforced by the derivative function defined in deriv_model

  • target - a function describing which derivatives shall be enforced at the boundaries for the variables listed in var

Derivative Models

We first define a derivative model as such:

def deriv_model(u_model, x, t):
    u = u_model(tf.concat([x, t], 1))
    u_x = tf.gradients(u, x)[0]
    return u, u_x

which solves down to the first order level at the boundary, allowing for added continuity. However, we aren’t limited to only one level of derivative in the periodic BC, and can instead define an arbitrary amount, such as a 4th-order derivative:

def deriv_model(u_model, x, t):
    u = u_model(tf.concat([x, t], 1))
    u_x = tf.gradients(u, x)[0]
    u_xx = tf.gradients(u_x, x)[0]
    u_xxx = tf.gradients(u_xx, x)[0]
    u_xxxx = tf.gradients(u_xxx, x)[0]
    return u, u_x, u_xx, u_xxx, u_xxxx

A similar form can be used to define higher-order derivatives at boundaries in higher dimensions as well, such as the following to define a periodic BC on a 2D domain:

def deriv_model(u_model, x, y, t):
    u = u_model(tf.concat([x, y, t], 1))
    u_x = tf.gradients(u, x)[0]
    u_y = tf.gradients(u, y)[0]
    u_xx = tf.gradients(u_x, x)[0]
    u_yx = tf.gradients(u_y, x)[0]
    u_yy = tf.gradients(u_y, y)[0]
    u_xy = tf.gradients(u_x, y)[0]
    return u, u_x, u_y, u_xx, u_yy, u_xy, u_yx

All the items listed in the return will be included iteratively in the loss function of your PINN solver, and adding higher order derivatives adds little to no additional computational cost.

Once a derivative model function has been defined, a periodic BC can be initialized via the following:

x_periodic = periodicBC(Domain, ['x'], [deriv_model])

Args:

  • domain - a domain object containing the variables in the domain

  • val - a float containing the value to be enforced at the boundary

  • var - a str indicating which variable should be enforced by the value in val

  • target - a str indicating whether the value listed in val will be targeting the upper or lower boundary on var