← Back to team overview

dolfin team mailing list archive

Re: (no subject)

 



Martin Sandve Alnæs wrote:
2007/7/26, Anders Logg <logg@xxxxxxxxx>:
Martin Sandve Alnæs wrote:
> 2007/7/25, Anders Logg <logg@xxxxxxxxx>:
>> Martin Sandve Alnæs wrote:
>> > 2007/7/25, Anders Logg <logg@xxxxxxxxx>:
>> >> Martin Sandve Alnæs wrote:
>> >> > 2007/7/25, Anders Logg <logg@xxxxxxxxx>:
>> >> >> Garth N. Wells wrote:
>> >> >>> Anders Logg wrote:
>> >> >>>> I think there is a very simple solution. We just change the
>> >> >>>> constructor of Function to
>> >> >>>>
>> >> >>>> Function(Mesh& mesh, GenericVector& x, const Form& form, uint
>> >> i = 1)
>> >> >>>>
>> >> >>>> and the vector member of DiscreteFunction to
>> >> >>>>
>> >> >>>>     GenericVector* x;
>> >> >>>>
>> >> >>>> Then if one needs a Function that uses a particular linear
>> algebra
>> >> >>>> backend, then just create the Function from a PETScVector,
>> >> uBlasVector
>> >> >>>> or EpetraVector. Otherwise, create it from a Vector (tied to the
>> >> >>>> default backend) or let the Function itself decide (in which
>> case it
>> >> >>>> will be a Vector).
>> >> >>>>
>> >> >>> I thought that this would be a simple solution, but there a "new
>> >> Vector"
>> >> >>> in DiscreteFunction which requires that the vector type be
>> known. If
>> >> >>> this is somehow re-written, the above approach could be used.
>> >> >>>
>> >> >>> Garth
>> >> >> This is used to create copies of the vector (when creating a sub
>> >> >> function or in the copy constructor). How about adding a factory
>> >> >> function to GenericVector? (And also to GenericFoo in general.)
>> >> >>
>> >> >>      virtual GenericVector* create() = 0;
>> >> >>
>> >> >> Then we can call this instead of new Vector() in
>> DiscreteFunction.cpp.
>> >> >>
>> >> >> /Anders
>> >> >
>> >> > I already have this in pycc::GenericVector/Foo, but I call it
>> "copy",
>> >> > which I think is a better name.
>> >>
>> >> I also thought of naming it copy(), but this is not alwats
>> appropriate.
>> >> In DiscreteFunction, one needs to create a new vector which is not a >> >> copy (but which is a copy of a slice of the vector). Having a copy()
>> >> function might be useful, but one can create a new object and then
>> copy
>> >>    the values by get/set.
>> >
>> > So you mean that A.create() returns a non-initialized matrix with
>> > nothing in common with A? I find that a bit confusing, and see no
>> > reason why A should have this ability.
>>
>> Yes, A.create() returns a new object that uses the same backend. Since
>> the Function class can do things like creating a subfunction and it has >> a copy constructor, it needs to be able to look at a given Function and >> create a new Function which uses the same linear algebra backend. (There
>> seems to be a need for this.
>
> Ok.
>
>> Otherwise, we could just let the Function
>> class use the default backend.)
>
> No good.
>
>> > And values aren't the only thing that has to be copied, copy() would
>> > copy or reuse the sparsity pattern and distribution pattern as well.
>>
>> We could have a special factory function for this and it could be named
>> copy(). So I suggest one create() and one copy().
>
> Ok.
>
> We can do it like this:
>
> class GenericTensor
> {
>  GenericTensor * create() = 0;
> }
>
> class GenericVector: public GenericTensor
> {
>  GenericVector * create() = 0;
> }
>
> This C++-feature is perhaps not so widely known, but it's useful in
> this context.
>
> Martin

I haven't seen this before. Do you mean that the function returning a
GenericVector will implement the function in GenericTensor returning
GenericTensor?

Yes. And if you have a GenericTensor* gt, gt->create() will return a
GenericTensor, while a GenericVector* gv; gv->create() returns a
GenericVector. It only works when using subclasses as return types, of
course. So if f.ex. using a smart pointer class, it wouldn't work. You
can even continue:

class MyVec: public GenericVector
{
 MyVec * create();
}

This way, we won't have to cast the pointers from create() and copy()
in code that uses f.ex. PetSCVector directly.

Do you have a reference/link explaining this feature?

It's probably in Bjarne Stroustrups book.

Martin

ok, very good. And just to confirm, the important point seems to be not to write "virtual"?

I think this looks good. Any more comments/objections to adding create() and copy() to GenericFoo in la?

Anything else we need to add to make this work for PyCC?

/Anders


Follow ups

References