Functions restricted to subdomains

Registered by Garth Wells

Functions restricted to subdomains currently have the syntax:
subdomain = dx(0)
V_restricted = V[subdomain]
which produces a RestrictedElement. Here the subdomain is described by a Measure object, which is technically sufficient for simple restrictions, but conceptually not so nice.

We will improve this in relation with a subdomain-language, and in concert with improved subdomain support in ffc/dolfin.

Blueprint information

Status:
Complete
Approver:
Priority:
Essential
Drafter:
Direction:
Approved
Assignee:
Definition:
Obsolete
Series goal:
None
Implementation:
Slow progress
Milestone target:
None
Started by
Martin Sandve Alnæs
Completed by
Martin Sandve Alnæs

Whiteboard

Current design iteration, will be used as basis for unit tests later:

###### Subdomain language:
# Create toplevel domain:
cell = triangle
D = Domain(cell, name='mydomain')

# Domain has some basic properties like dimensions:
assert D.name() == 'mydomain'
assert D.cell() == cell
assert D.geometric_dimension() == 2
assert D.topological_dimension() == 2

# Create numbered disjoint subdomains:
D1 = D[1]
D3 = D[3]
D2 = D[2]

# These subdomains are registered in D so they can be retrieved later:
assert D.disjoint_subdomains() == [D1, D2, D3]

# Create named possibly non-disjoint subdomain groups:
Dleft = DomainGroup((D1, D2), name='left')
Dright = DomainGroup((D2, D3), name='right')

# Named subdomains are also registered in D:
assert Dleft == D['left']
assert Dright == D['right']
assert Dleft != D['right']

# The overlap between domain groups can be specified easily:
Doverlap = DomainOverlap(Dleft, Dright, name='overlap')
assert D['overlap'] == DomainGroup((D2,), name='overlap') # A bit unsure here

###### Defining elements on subdomains:
# Elements can be defined on domain groups:
VL = VectorElement(Dleft, "CG", 1)
VR = FiniteElement(Dright, "CG", 2)
assert VL.domain() == Dleft
assert VR.domain() == Dright
assert VL.domain().disjoint_subdomains() == [D1, D2]
assert VR.domain().disjoint_subdomains() == [D2, D3]

# Elements can be combined into mixed elements:
V = VL*VR
assert V.domain() == D # This is unclear
assert V.domain().disjoint_subdomains() == [D1, D2, D3]

# The mixed element can be queried for which elements live on which disjoint subdomains:
dom2elm = V.domain2subelement()
assert dom2elm == {
D1: (VL,),
D2: (VL,VR),
D3: (VR,),
}

# I think we'll need to mirror these in ufc::dof_map:
#void ufc::dof_map::domain2subelements(std::map< std::size_t, std::vector<size_t> > & d2s) const;
# Result matching above ufl code:
#d2s[1] == vector({0,}) # VL is subelement 0
#d2s[2] == vector({0,1}) # both VL and VR
#d2s[3] == vector({1,}) # VR is subelement 1

(?)

Work Items

Work items:
[meg-simula] Extract integrals over subdomains from subdomain groups: TODO

Dependency tree

* Blueprints in grey have been implemented.

This blueprint contains Public information
Everyone can see this information.