This page was generated from unit-1.5-subdomains/subdomains.ipynb.

1.5 Spaces and forms on subdomains

In NGSolve, finite element spaces can be defined on subdomains. This is useful for multiphysics problems like fluid-structure interaction.

In addition, bilinear or linear forms can be defined as integrals over regions. Regions are parts of the domain. They may be subdomains, or parts of the domain boundary, or parts of subdomain interfaces.

In this tutorial, you will learn about

  • defining finite element spaces on Regions,

  • Compressing such spaces,

  • integrating on Regionss, and

  • set operations on Region objects via Mask.

[1]:
from ngsolve import *
from ngsolve.webgui import Draw
from netgen.geom2d import *

Naming subdomains and boundaries

We define a geometry with multiple regions and assign names to these regions below:

[2]:
geo = SplineGeometry()
geo.AddRectangle((0,0), (2,2),
                 bcs=["b","r","t","l"],
                 leftdomain=1)
geo.AddRectangle((1,0.9), (1.3,1.4),
                 bcs=["b2","r2","t2","l2"],
                 leftdomain=2, rightdomain=1)
geo.SetMaterial (1, "outer")
geo.SetMaterial (2, "inner")
mesh = Mesh(geo.GenerateMesh(maxh=0.1))
 Generate Mesh from spline geometry
 Boundary mesh done, np = 96
 CalcLocalH: 96 Points 0 Elements 0 Surface Elements
 Meshing domain 1 / 2
 load internal triangle rules
 Surface meshing done
 Meshing domain 2 / 2
 Surface meshing done
 Edgeswapping, topological
 Smoothing
 Split improve
 Combine improve
 Smoothing
 Edgeswapping, metric
 Smoothing
 Split improve
 Combine improve
 Smoothing
 Edgeswapping, metric
 Smoothing
 Split improve
 Combine improve
 Smoothing
 Update mesh topology
 Update clusters
  • These statements define two rectangular subdomain regions named “inner”, “outer”. (Note how the ordering in SetMaterial is 1-based, not 0-based.)

  • The bottom, right, top and left parts of the outer rectangle’s boundaries define boundary regions, respectively labeled “b”, “r”, “t”, “l”.

  • Similarly, the bottom, right, top and left parts of the inner rectangle’s boundaries are regions named “b2”, “r2”, “t2”, “l2”.

  • When you select the Mesh tab in the Netgen window’s Graphical User Interface (GUI) and double click on a point, the two subdomains are rendered in different colors. (You should also see the subdomain outlines in the Netgen window when you select the Geometry tab.)

A finite element space on a subdomain

[3]:
fes1 = H1(mesh, definedon="inner")
u1 = GridFunction(fes1, "u1")
u1.Set(x*y)
Draw(u1)
setvalues element 878/878
[3]:
BaseWebGuiScene

Note how \(u_1\) is displayed only in the inner region in the Netgen GUI.

Do not be confused with ndof for spaces on subdomains:

[4]:
fes = H1(mesh)
fes1.ndof, fes.ndof
[4]:
(480, 480)

Although ndofs are the same for spaces on one subdomain and the whole domain, FreeDofs show that the real number of degrees of freedom for the subdomain space is much smaller:

[5]:
print(fes1.FreeDofs())
0: 00001111000000000000000000000000000000000000000000
50: 00000000000000000000000000000000001111111111110000
100: 00000000000000000000000000000000000000000000000000
150: 00000000000000000000000000000000000000000000000000
200: 00000000000000000000000000000000000000000000000000
250: 00000000000000000000000000000000000000000000000000
300: 00000000000000000000000000000000000000000000000000
350: 00000000000000000000000000000000000000000000000000
400: 00000000000000000000000000000000000000000000000000
450: 000000000000000000000001111111

One can also glean this information by examining CouplingType of each degrees of freedom of the space, which reveals that there are many unknowns of type COUPLING_TYPE.UNUSED_DOF.

[6]:
for i in range(fes1.ndof):
    print(fes1.CouplingType(i))
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.UNUSED_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF
COUPLING_TYPE.WIREBASKET_DOF

It is possible to remove these dofs (thus making GridFunction vectors smaller) as follows.

[7]:
fescomp = Compress(fes1)
print(fescomp.ndof)
23

Integrating on regions

You have already seen how boundary regions are used in setting Dirichlet boundary conditions.

[8]:
fes = H1(mesh, order=3, dirichlet="b|l|r")

u, v = fes.TnT()
gfu = GridFunction(fes)

Such boundary regions or subdomains can also serve as domains of integration.

[9]:
f = LinearForm(fes)
f += u1 * v * dx(definedon=mesh.Materials("inner"))
f += 0.1 * v * ds(definedon=mesh.Boundaries("t"))
f.Assemble()
[9]:
<ngsolve.comp.LinearForm at 0x7fa18b18b2b0>
assemble VOL element 878/878
assemble BND element 96/96

Here the functional \(f\) is defined as a sum of two integrals, one over the inner subdomain, and another over the top boundary:

\[f(v) = \int_{\Omega_{inner}} u_1 v \; dx + \int_{\Gamma_{top}} \frac{v}{10}\; ds\]

The python objects dx and ds represent volume and boundary integration, respectively. They admit a keyword argument definedon that is either a Region or a str, as can be seen from the documentation: look for definedon: Optional[Union[ngsolve.comp.Region, str]] in the help output below.

[10]:
help(dx)
Help on DifferentialSymbol in module ngsolve.comp object:

class DifferentialSymbol(pybind11_builtins.pybind11_object)
 |  Method resolution order:
 |      DifferentialSymbol
 |      pybind11_builtins.pybind11_object
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __call__(...)
 |      __call__(self: ngsolve.comp.DifferentialSymbol, definedon: Optional[Union[ngsolve.comp.Region, str]] = None, element_boundary: bool = False, element_vb: ngsolve.comp.VorB = <VorB.VOL: 0>, skeleton: bool = False, bonus_intorder: int = 0, intrules: Dict[ngsolve.fem.ET, ngsolve.fem.IntegrationRule] = {}, deformation: ngsolve.comp.GridFunction = None, definedonelements: pyngcore.BitArray = None) -> ngsolve.comp.DifferentialSymbol
 |
 |  __init__(...)
 |      __init__(self: ngsolve.comp.DifferentialSymbol, arg0: ngsolve.comp.VorB) -> None
 |
 |  ----------------------------------------------------------------------
 |  Static methods inherited from pybind11_builtins.pybind11_object:
 |
 |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type
 |      Create and return a new object.  See help(type) for accurate signature.

Thus - dx(definedon=mesh.Materials("inner")) may be replaced by dx('inner'),

and similarly,

  • ds(definedon=mesh.Boundaries("t") may be replaced by ds('t').

[11]:
f = LinearForm(fes)
f += u1*v*dx('inner') + 0.1*v*ds('t')
f.Assemble()
assemble VOL element 878/878
[11]:
<ngsolve.comp.LinearForm at 0x7fa18b18b5f0>
assemble BND element 96/96
[12]:
a = BilinearForm(fes)
a += grad(u)*grad(v)*dx
a.Assemble()

# Solve the problem:
gfu.vec.data = a.mat.Inverse(fes.FreeDofs()) * f.vec
Draw (gfu)
assemble VOL element 878/878
call pardiso ... done
[12]:
BaseWebGuiScene

More about Region objects

[13]:
mesh.GetMaterials()    # list all subdomains
[13]:
('outer', 'inner')
[14]:
mesh.GetBoundaries()   # list boundary/interface regions
[14]:
('b', 'r', 't', 'l', 'b2', 'r2', 't2', 'l2')
[15]:
mesh.Materials("inner") # look at object's type
[15]:
<ngsolve.comp.Region at 0x7fa18b18bc30>
[16]:
mesh.Boundaries("t")    # same type!
[16]:
<ngsolve.comp.Region at 0x7fa18b18be70>

Operations with Regions

Print region information:

[17]:
print(mesh.Materials("inner").Mask())
print(mesh.Materials("[a-z]*").Mask())  # can use regexp
print(mesh.Boundaries('t|l').Mask())
0: 01
0: 11
0: 00110000

Add regions:

[18]:
io = mesh.Materials("inner") + mesh.Materials("outer")
print(io.Mask())
0: 11

Take complement of a region:

[19]:
c = ~mesh.Materials("inner")
print(c.Mask())
0: 10

Subtract regions:

[20]:
diff = mesh.Materials("inner|outer") - mesh.Materials("outer")
print(diff.Mask())
0: 01

Set a piecewise constant CoefficientFunction using the subdomains:

[21]:
domain_values = {'inner': 3.7,  'outer': 1}
values_list = [domain_values[mat]
               for mat in mesh.GetMaterials()]
cf = CoefficientFunction(values_list)
Draw(cf, mesh, 'piecewise')
[21]:
BaseWebGuiScene

Coefficients on boundary regions are given similarly using mesh.GetBoundaries().

Extra exercises to try out

Let’s make a linear function that equals 2 at the bottom right vertex of current domain (0,2) x (0,2) and equals zero at the remaining vertices.

[22]:
bdry_values = {'b': x, 'r': 2-y}
values_list = [bdry_values[bc]
               if bc in bdry_values.keys() else 0
               for bc in mesh.GetBoundaries()]
cf = CoefficientFunction(values_list)
Draw(cf, mesh, 'piecewise')
[22]:
BaseWebGuiScene

Pitfall!

Look at the GUI output. This is not the function we wanted!

What happened here? The object cf has no information on boundary regions, so it cannot associate the list of values to boundary regions. By default, the list of values are assumed to be subdomain values.

To associate these values to boundary regions, we use a GridFunction and Set, which also lets us view an extension of these boundary values into the domain.

[23]:
g = GridFunction(H1(mesh), name='bdry')
g.Set(cf, definedon=~mesh.Boundaries(''))
Draw(g, max=2, min=0)
setvalues element 96/96
[23]:
BaseWebGuiScene

If you think that specifying the whole boundary using

~mesh.Boundaries('')

is convoluted, then you may use

g.Set(cf, definedon=mesh.Boundaries('b|r')).
[24]:
g.Set(cf, definedon=mesh.Boundaries('b|r'))
Draw(g, max=2, min=0)
setvalues element 96/96
[24]:
BaseWebGuiScene

What happens if you Set using b and then on r?

[25]:
g.Set(cf, definedon=mesh.Boundaries('b'))
g.Set(cf, definedon=mesh.Boundaries('r'))
Draw(g, max=2, min=0)
setvalues element 96/96
setvalues element 96/96
[25]:
BaseWebGuiScene

Pitfall!

Do you see an unexpected behavior in the GUI?

If so, realize that each Set begins by zeroing the grid function - so any previous values are lost!

What happens if you use

g.Set(cf, BND)

instead?

Pitfall!

[26]:
g = GridFunction(H1(mesh))
g.Set(cf, BND)
Draw(g, max=2, min=0)
setvalues element 96/96
[26]:
BaseWebGuiScene

We do not obtain the previous result because the keyword BND directs Set to only set the data in boundary regions marked as dirichlet.

[27]:
g = GridFunction(H1(mesh, dirichlet='b|r'))
g.Set(cf, BND)
Draw(g, max=2, min=0)
setvalues element 96/96
[27]:
BaseWebGuiScene