Martin Sandve Alnæs wrote:
> 2007/7/25, Anders Logg <[EMAIL PROTECTED]>:
>> Martin Sandve Alnæs wrote:
>> > 2007/7/25, Anders Logg <[EMAIL PROTECTED]>:
>> >> 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. Otherwise, we could just let the Function 
class use the default backend.)

Anyway, to make this possible, a vector must know it's type. Either a 
vector must have an enum or something that one can check to see which 
representation it has and then we also need to have a bunch of factories 
(quite a few), or we just let the factory function be part of the class 
itself and then we just need to add a single function create().

> 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().

/Anders


> 
>> > For eventual other situations which require type-independent
>> > construction of GenericFoo without an object to copy, we can have a
>> > factory design:
>> >
>> > class GenericFooFactory
>> > {
>> > public:
>> >   GenericFoo * create_foo(...) const = 0;
>> >   ...
>> > };
>> >
>> > This is implemented for each backend, and create_foo can be defined
>> > with several different argument lists.
>> >
>> > Martin
>>
>> Why not place it as a member function in GenericFoo? Then we avoid
>> having a number of additional classes (PETScVectorFactor,
>> PETScMatrixFactory, uBlasVectorFactory, ...).
> 
> Because then you need a GenericFoo object to create a GenericFoo
> object, and that's not always the case? It gives me a feeling that the
> new returned object has something in common with the object that
> created it.
> 
> A = dummy_matrix.create()
> b = dummy_vector.create()
>  vs
> A = factory.create_matrix()
> b = factory.create_vector()
> 
> or
> GenericMatrix * matrix()
> {
>  return factory.create_matrix();
> }
> A = matrix()
> 
> 
> Either dummy_matrix and dummy_vector must be created at some point, or
> the factory.
> 
> I don't have any very concrete reasons at the moment, it just doesn't
> feel right to me. However, looking up on the factory design pattern
> might provide some reasons.
> 
> Martin
_______________________________________________
DOLFIN-dev mailing list
[email protected]
http://www.fenics.org/mailman/listinfo/dolfin-dev

Reply via email to