kinnala / scikit-fem

Simple finite element assemblers
https://scikit-fem.readthedocs.io
BSD 3-Clause "New" or "Revised" License
499 stars 79 forks source link

optional subset of elements in InteriorBasis #161

Closed gdmcbain closed 5 years ago

gdmcbain commented 5 years ago

It is already possible to solve a PDE in a subdomain #159 but:

I'm surprised that InteriorBasis.init does not have an optional argument for specifying the set of elements.

This would be consistent with the optional facets argument of FacetBasis.

kinnala commented 5 years ago

A preliminary version is now available in https://github.com/kinnala/scikit-fem/tree/subdomain-assembly.

But after starting to modify ex26 to conform to this, I became unsure whether this is something that is actually wanted there.

If you set now the argument 'elements' to something other than None, you still get a matrix with same size as the original assembly but just DOF's related to other elements ignored in the assembly phase (rows and columns are zero).

gdmcbain commented 5 years ago

Right. I think that this is correct behaviour for an elements keyword-argument to InteriorBasis that is consistent with the existing facets keyword-argument of FacetBasis. If the interior or facet basis passed to asm is restricted to a subdomain of elements or subboundary of facets, it should still return a sparse matrix of the same (square) shape, just with different .nnz. This is just the same as, say in ex26,

asm(laplace, FacetBasis(mesh, basis.elem, facets=mesh.boundaries['convection']))

is (683, 683) with nnz==624 while

asm(laplace, FacetBasis(mesh, basis.elem, facets=mesh.boundaries['convection'][:9]))

is (683, 683) with nnz==75. (Not that the latter matrix has much physical significance.)

I think that #166 does correctly fix the concern from #159:

Later it did occur to me that there was a bit of wasted assembly which could be avoided with such an optional argument.

I find that on branch subdomain-assembly, I can get the same correct solution for the temperature field in ex26 with

wire_basis = InteriorBasis(mesh, basis.elem, elements=mesh.subdomains['wire'])
L = asm(laplace, wire_basis)
f = asm(unit_load, wire_basis)
gdmcbain commented 5 years ago

But after starting to modify ex26 to conform to this, I became unsure whether this is something that is actually wanted there.

If you set now the argument 'elements' to something other than None, you still get a matrix with same size as the original assembly but just DOF's related to other elements ignored in the assembly phase (rows and columns are zero).

As to what's ‘actually wanted’, I'm not exactly sure yet as the work on coupling subdomains #163 remains nebulous. (More on that shortly.) I mean, I don't think I've decided or worked out exactly how to set up a problem with multiple subdomains or domains.

I believe the changes in #166 are exactly what's wanted to do ex26 properly, but ex26 is very much a toy. I can certainly imagine domain-decomposition style approaches in which problems are to be solved (or at least assembled) in subdomains, and then coupled again #163, but whether ex26 is usefully indicative of them remains to be seen.

I plan to construct two more examples for #163 that should (begin to) elucidate this.

The second example is certainly justified as I'd use something based on it in real applications for sure. The first one less so as it's not clear what advantage it has over the monolithic solution in ex17. Maybe required for problems with ‘contact resistance’ in which there is a jump-discontinuity in the solution across the interface.

There are lots of other ways to do both problems. If one of those turns out to be better and then ex26 isn't demonstrating one of the substeps, then it can be jettisoned.

The changes in #166 are still correct and at the very least pretty harmless. They only very slightly increase the code-complexity and do eliminate the asymmetry with the facets in FacetBasis.