It would be great to have the simple syntax assign(foo, bar),
but for efficiency we need to be able to cache the mappings
between dofmaps. At least that's the rationale behind the
FunctionAssigner class.
An alternative could be a similar class to represent just the mapping
instead,
# Fantastic class name, better suggestions? :)
map0 = DofMapToDofMapMapping([V,V], VV)
map1 = DofMapToDofMapMapping(VV, [V,V])
map2 = DofMapToDofMapMapping(V, V.sub(1))
and then passing that optionally to an assign function
assign([u0, u1], U, map0)
assign(U, [u0, u1], map1)
assign(u0, u.sub(1), map2)
while if omitted, assign would create the mapping each time
# pseudocode
def assign(dest, src, mapping=None):
if mapping is None:
mapping = DofMapToDofMapMapping(get "space" of dest, get
"space" of src)
....
It could even return the mapping, so you could do
mapping = None
while t < T:
mapping = assign(u, v, mapping)
and keep efficiency.
Martin
On 24 September 2013 10:27, Anders Logg <[email protected]> wrote:
> Is it possible to solve this without introducing the design pattern
> with a class FunctionAssigner? We have been careful to avoid this in
> other places.
>
> --
> Anders
>
>
>
> On Mon, Sep 23, 2013 at 07:20:03PM +0200, Johan Hake wrote:
> > I am working on sub-function assignment. To facilitate caching of dof
> indices
> > for a particular assignment combination I suggest introducing a
> > FunctionAssigner class which caches the necessary indices (dofs) for the
> whole
> > domain.
> >
> > Something like:
> >
> > mesh = UnitSquareMesh(10,10)
> > V = FunctionSpace(mesh, "CG", 1)
> > VV = V*V
> >
> > # Assign two scalar functions to the components of a mixed function
> > assigner0 = FunctionAssigner([V, V], VV)
> >
> > # Assign components of a mixed function to scalar Functions
> > assigner1 = FunctionAssigner(VV, [V, V])
> >
> > # Assign a scalar function to a component of a mixed function
> > assigner2 = FunctionAssigner(V, VV.sub(1))
> >
> > u0, u1 = Function(V), Function(V)
> > U = Function(VV)
> >
> > Then in some time loop:
> >
> > while t < tstop:
> > ...
> > assigner0.assign([u0, u1], U)
> > ...
> > assigner1.assign(U, [u0, u1])
> > ...
> > assigner2.assign(u0, U.sub(1))
> >
> > In C++ the equivalent to a list of Foo will be a std::vector of shared
> Foos.
> >
> > Comments?
> >
> > By using sub spaces and sub functions we avoid using indices in the
> interface,
> > which I think is neat. However, there are some limitations with the
> present
> > interface:
> >
> > 1) The FunctionAssigner needs to have access to the local ownership
> range of a
> > sub dofmap, but that is not possible as it is set to 0,0 during
> construction.
> > Could we add a proper local ownership range to a sub dofmap?
> > 2) The FunctionAssigner need to be able to access the private _vector of
> a
> > parent Function during the assignment, as calling subfunc.vector()
> raises an
> > error. This can be fixed by a friend statement. Is that acceptable?
> >
> > Johan
>
> > _______________________________________________
> > fenics mailing list
> > [email protected]
> > http://fenicsproject.org/mailman/listinfo/fenics
>
> _______________________________________________
> fenics mailing list
> [email protected]
> http://fenicsproject.org/mailman/listinfo/fenics
>
_______________________________________________
fenics mailing list
[email protected]
http://fenicsproject.org/mailman/listinfo/fenics