The topology module defines the topology objects, notably the StructuredTopology. Maintaining strict separation of topological and geometrical information, the topology represents a set of elements and their interconnectivity, boundaries, refinements, subtopologies etc, but not their positioning in physical space. The dimension of the topology represents the dimension of its elements, not that of the the space they are embedded in.

The primary role of topologies is to form a domain for nutils.function objects, like the geometry function and function bases for analysis, as well as provide tools for their construction. It also offers methods for integration and sampling, thus providing a high level interface to operations otherwise written out in element loops. For lower level operations topologies can be used as nutils.element iterators.

class nutils.topology.Topology(references, transforms, opposites)

Bases: nutils.types.Singleton

topology base class


string representation

basis(self, name, *args, **kwargs)

Create a basis.

sample(self, ischeme, degree)

Create sample.

integrate_elementwise(self, funcs, *, asfunction=False, **kwargs)

element-wise integration

integrate(self, funcs, ischeme='gauss', degree=None, edit=None, *, arguments=None, title='integrate')

integrate functions

integral(self, func, ischeme='gauss', degree=None, edit=None)
projection(self, fun, onto, geometry, **kwargs)

project and return as function

project(self, fun, onto, geometry, ischeme='gauss', degree=None, droptol=1e-12, exact_boundaries=False, constrain=None, verify=None, ptype='lsqr', edit=None, *, arguments=None, **solverargs)

L2 projection of function onto function space

refined_by(self, refine)

create refined space by refining dofs in existing one

refine(self, n)

refine entire topology n times

trim(self, levelset, maxrefine, ndivisions=8, name='trimmed', leveltopo=None, *, arguments=None)

trim element along levelset

subset(self, topo, newboundary=None, strict=False)


locate(self, geom, coords, *, ischeme='vertex', scale=1, tol=None, eps=0, maxiter=100, arguments=None)

Create a sample based on physical coordinates.

In a finite element application, functions are commonly evaluated in points that are defined on the topology. The reverse, finding a point on the topology based on a function value, is often a nonlinear process and as such involves Newton iterations. The locate function facilitates this search process and produces a nutils.sample.Sample instance that can be used for the subsequent evaluation of any function in the given physical points.


>>> from . import mesh
>>> domain, geom = mesh.unitsquare(nelems=3, etype='mixed')
>>> sample = domain.locate(geom, [[.9, .4]])
>>> sample.eval(geom).tolist()
[[0.9, 0.4]]

Locate has a long list of arguments that can be used to steer the nonlinear search process, but the default values should be fine for reasonably standard situations.

  • geom (1-dimensional nutils.function.Array) – Geometry function of length ndims.

  • coords (2-dimensional float array) – Array of coordinates with ndims columns.

  • tol (float) – Maximum allowed distance between original and located coordinate.

  • ischeme (str (default: “vertex”)) – Sample points used to determine bounding boxes.

  • scale (float (default: 1)) – Bounding box amplification factor, useful when element shapes are distorted. Setting this to >1 can increase computational effort but is otherwise harmless.

  • eps (float (default: 0)) – Epsilon radius around element within which a point is considered to be inside.

  • maxiter (int (default: 100)) – Maximum allowed number of Newton iterations.

  • arguments (dict (default: None)) – Arguments for function evaluation.



Return type



Topology: The boundary of this topology.

basis_discont(self, degree)

discontinuous shape functions

basis_lagrange(self, degree)

lagrange shape functions

basis_bernstein(self, degree)

bernstein shape functions

basis_std(self, degree)

bernstein shape functions

class nutils.topology.WithGroupsTopology(basetopo, vgroups={}, bgroups={}, igroups={}, pgroups={})

Bases: nutils.topology.Topology

item topology

class nutils.topology.OppositeTopology(basetopo)

Bases: nutils.topology.Topology

opposite topology

class nutils.topology.EmptyTopology(ndims)

Bases: nutils.topology.Topology

empty topology

class nutils.topology.Point(trans, opposite=None)

Bases: nutils.topology.Topology


class nutils.topology.StructuredTopology(root, axes, nrefine=0, bnames='left', 'right', 'bottom', 'top', 'front', 'back')

Bases: nutils.topology.Topology

structured topology

__init__(self, root, axes, nrefine=0, bnames='left', 'right', 'bottom', 'top', 'front', 'back')


basis_spline(self, degree, removedofs=None, knotvalues=None, knotmultiplicities=None, continuity=- 1, periodic=None)

spline basis

property refined

refine non-uniformly


string representation

class nutils.topology.ConnectedTopology(references, transforms, opposites, connectivity)

Bases: nutils.topology.Topology

unstructured topology with connectivity

class nutils.topology.SimplexTopology(simplices, transforms, opposites)

Bases: nutils.topology.Topology

simpex topology


bubble from vertices

class nutils.topology.UnionTopology(topos, names=())

Bases: nutils.topology.Topology

grouped topology

class nutils.topology.DisjointUnionTopology(topos, names=())

Bases: nutils.topology.Topology

grouped topology

class nutils.topology.SubsetTopology(basetopo, refs, newboundary=None)

Bases: nutils.topology.Topology


class nutils.topology.RefinedTopology(basetopo)

Bases: nutils.topology.Topology


class nutils.topology.HierarchicalTopology(basetopo, indices_per_level)

Bases: nutils.topology.Topology

collection of nested topology elments

__init__(self, basetopo, indices_per_level)



boundary elements

basis(self, name, *args, truncation_tolerance=1e-15, **kwargs)

Create hierarchical basis.

A hierarchical basis is constructed from bases on different levels of uniform refinement. Two different types of hierarchical bases are supported:

1. Classical – Starting from the set of all basis functions originating from all levels of uniform refinement, only those basis functions are selected for which at least one supporting element is part of the hierarchical topology.

2. Truncated – Like classical, but with basis functions modified such that the area of support is reduced. An additional effect of this procedure is that it restores partition of unity. The spanned function space remains unchanged.

Truncation is based on linear combinations of basis functions, where fine level basis functions are used to reduce the support of coarser level basis functions. See Giannelli et al. 2012 for more information on truncated hierarchical refinement.

  • name (str) – Type of basis function as provided by the base topology, with prefix h- (h-std, h-spline) for a classical hierarchical basis and prefix th- (th-std, th-spline) for a truncated hierarchical basis.

  • truncation_tolerance (float (default 1e-15)) – In order to benefit from the extra sparsity resulting from truncation, vanishing polynomials need to be actively identified and removed from the basis. The trunctation_tolerance offers control over this threshold.



Return type


class nutils.topology.ProductTopology(topo1, topo2)

Bases: nutils.topology.Topology

product topology

class nutils.topology.RevolutionTopology

Bases: nutils.topology.Topology

topology consisting of a single revolution element

class nutils.topology.MultipatchTopology(patches)

Bases: nutils.topology.Topology

multipatch topology

static build_boundarydata(connectivity)

build boundary data based on connectivity

__init__(self, patches)


basis_spline(self, degree, patchcontinuous=True, knotvalues=None, knotmultiplicities=None, *, continuity=- 1)

spline from vertices

Create a spline basis with degree degree per patch. If patchcontinuous` is true the basis is $C^0$-continuous at patch interfaces.


degree zero patchwise discontinuous basis


Return a topology with all element interfaces. The patch interfaces are accessible via the group 'interpatch' and the interfaces inside a patch via 'intrapatch'.