dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #10997
Re: [HG DOLFIN] Added support for f.split()
2008/12/6 Johan Hake <hake@xxxxxxxxx>:
> On Saturday 06 December 2008 20:54:34 Anders Logg wrote:
>> On Sat, Dec 06, 2008 at 04:03:25PM +0100, Johan Hake wrote:
>> > On Saturday 06 December 2008 15:43:13 Anders Logg wrote:
>> > > On Sat, Dec 06, 2008 at 03:34:40PM +0100, Johan Hake wrote:
>> > > > On Saturday 06 December 2008 14:56:59 Anders Logg wrote:
>> > > > > On Sat, Dec 06, 2008 at 12:05:41PM +0100, DOLFIN wrote:
>> > > > > > One or more new changesets pushed to the primary dolfin
>> > > > > > repository. A short summary of the last three changesets is
>> > > > > > included below.
>> > > > > >
>> > > > > > changeset: 5262:0e349fbe09ce4179252652fe5c1d58725951bc3f
>> > > > > > tag: tip
>> > > > > > user: "Johan Hake <hake@xxxxxxxxx>"
>> > > > > > date: Sat Dec 06 12:05:42 2008 +0100
>> > > > > > files: demo/pde/stokes/taylor-hood/python/demo.py
>> > > > > > dolfin/function/SpecialFunctions.h
>> > > > > > dolfin/swig/dolfin_function_pre.i
>> > > > > > site-packages/dolfin/function.py description:
>> > > > > > Added support for f.split()
>> > > > > > - Renamed operator[] to f._sub instead of f.sub
>> > > > > > - f.sub(i) now returns an instantiated sub function
>> > > > > > - f.split() uses f.sub() to return a tuple of all sub functions
>> > > > > > - stoke/taylor-hood demo now runs.
>> > > > >
>> > > > > Excellent!
>> > > > >
>> > > > > It runs now but the solution looks completely crazy. The problem is
>> > > > > that the boundary conditions are not set correctly since we use V
>> > > > > and Q to set the boundary conditions for the sub systems and they
>> > > > > don't know the offsets (DofMap::offset()).
>> > > >
>> > > > The problem here is that these spaces need to be SubSpaces?
>> > >
>> > > Yes.
>> > >
>> > > > If that is the case, we could extract the subspaces after a
>> > > > MixedFunctionSpace is created and then store these in the spaces
>> > > > attribute, either as pure cpp.SubSpaces or add another python class,
>> > > > SubSpace, which is a cpp.SubSpace and stores the original ffc.element
>> > > > too, or something?
>> > >
>> > > I was thinking something like this:
>> > >
>> > > W = VectorFunctionSpace(mesh, "triangle", 2) + FunctionSpace(mesh,
>> > > "triangle", 1) V, Q = W.split()
>> >
>> > Doesn't look too nice, and it will create a non intuitive work flow.
>> > Combining two interfaces aren't easy!
>> >
>> > > The split function needs to both create SubSpaces (which will lead to
>> > > DofMaps with correct offsets) and set the element correctly, which can
>> > > be done by looking at the spaces attribute in MixedFunctionSpace.
>> > >
>> > > It's a bit weird since what we really do is
>> > >
>> > > V = VectorFunctionSpace(mesh, "triangle", 2)
>> > > Q = FunctionSpace(mesh, "triangle", 1)
>> > > W = V + Q
>> > > V, Q = W.split()
>> > >
>> > > First, we put V and Q together to create a mixed function space. Then
>> > > we split W again into V and Q. After the split V and Q know that they
>> > > are part of the bigger space (at least they know the offset into the
>> > > bigger space).
>> >
>> > Yes I see this. Instead, or in addition, of using split, we could
>> > implement W.sub(i) that returns a subspace, which is then used when
>> > setting the bc, and other relevant places.
>> >
>> > > The other option would be to let + have a side effect on V and Q but
>> > > that does not seem to be a good solution.
>> >
>> > I thought of this too. But I cannot se how we could do it with the
>> > present implementation of FunctionSpace/Subspace.
>>
>> If we can get make_subspace working as you suggest below, then it
>> would be easy to modify __add__ for FunctionSpaceBase:
>>
>> W = MixedFunctionSpace([self, other])
>> self.make_subspace(W, 0)
>> other.make_subspace(W, 1)
>> return W
>
> Yes something like that.
>
>> This would make the interface look nice but someone (you know who you
>> are) might think we are insane... :-)
>
> *laugh*
>
> I am not very happy with it either, as the __add__ operator should not do such
> a thing. What we are saying is that V and Q are individual FunctionSpaces
> before we make make the add. After we have made it they are suddenly
> subspaces of the result of an addition. Not very intuitive.
>
> One slution could be to remove the __add__ operator and instead force the user
> to instantiate the Mixed space with a constructor, e.g.
>
> W = MixedFunctionSpace(V,Q)
>
> With this it is easier to justify that we are doing somthing with V and Q.
No it isn't.
This isn't a matter of taste, it just doesn't scale outside a minimal example.
What will happen here?
W0 = MixedFunctionSpace(V0,V1) # or V0 + V1, same thing
W1 = MixedFunctionSpace(V1,V2)
W2 = MixedFunctionSpace(V2,V3)
>> > If we could just call a member function in a FunctionSpace, let say
>> > V.make_subspace(W,i), and this would then create the needed stuff in V,
>> > to make it SubSpaceable. But now SubSpace is a subclass which effectively
>> > prevents this approach.
>> >
>> > This approach is abit intrucive too. But what difference would it make
>> > for the user, i.e., if V in addition to be a FunctionSpace now also is a
>> > subspace of W?
>>
>> The only reason we need this is to be able to set boundary conditions
>> for sub systems. For that we need two things: the offset into the
>> global system vector and the DofMap for the subsystem in question.
>> There might be other ways to define the interface for DirichletBC,
>> for example:
>>
>> bc = DirichletBC(W, 0, ...)
>
>
> This is maybee the best one? The DirichletBC operates at the global vector
> from the mixed space, and then it is more intuitive to actually use the mixed
> space to set the BC.
Agree.
But we also need to assign a subfunction to a function and vice versa,
perhaps like:
u.assign(U.sub(0))
p.assign(U.sub(1))
U.sub(0).assign(u)
U.sub(1).assign(p)
--
Martin
Follow ups
References