2009/2/16 A Navaei <[email protected]>: > 2009/2/16 Anders Logg <[email protected]>: >> On Mon, Feb 16, 2009 at 05:36:48PM +0000, Garth N. Wells wrote: >>> >>> >>> A Navaei wrote: >>> > 2009/2/16 Anders Logg <[email protected]>: >>> >> On Mon, Feb 16, 2009 at 04:36:21PM +0000, A Navaei wrote: >>> >>> 2009/2/15 Anders Logg <[email protected]>: >>> >>>> On Sat, Feb 14, 2009 at 06:44:05PM +0000, Garth N. Wells wrote: >>> >>>>> >>> >>>>> A Navaei wrote: >>> >>>>>> [snip] >>> >>>>>>>>> Function should not change the FunctionSpace (that's why >>> >>>>>>>>> FunctionSpace is >>> >>>>>>>>> const). FunctionSpace shouldn't depend on the data and its size >>> >>>>>>>>> should be >>> >>>>>>>>> defined when creating the FunctionSpace. >>> >>>>>>>> The same applies for FunctionSpace as its member variables are >>> >>>>>>>> private >>> >>>>>>>> and the public accessors are read-only which. Consider a sub-class >>> >>>>>>>> ImageFunctionSpace:FunctionSpace, with a constructor like: >>> >>>>>>>> >>> >>>>>>>> ImageFunctionSpace(ImageType *imagePtr) >>> >>>>>>>> >>> >>>>>>>> where imagePtr is supposed to initialise FunctionSpace::_mesh using >>> >>>>>>>> the image size, and then _dofmaps itself is initialised using >>> >>>>>>>> _mesh. >>> >>>>>>>> How would you do that considering the restrictions? >>> >>>>>>>> >>> >>>>>>> The FunctionSpace has pointers to the mesh, etc. You just need to >>> >>>>>>> create >>> >>>>>>> your mesh and pass it to the FunctionSpace constructor. What else >>> >>>>>>> you then >>> >>>>>>> do with the mesh, etc is up to you. >>> >>>>>> That can be done _outside_ of a sub-class. A sub-class of >>> >>>>>> FunctionSpace doesn't have a control over _mesh of its own parent >>> >>>>>> FunctionSpace. The following example may make this more clear: >>> >>>>>> >>> >>>>>> template <typename TImage> >>> >>>>>> class DolfinImageFunctionSpace : public dolfin::FunctionSpace >>> >>>>>> { >>> >>>>>> public: >>> >>>>>> // just some itk typedefs -- ignore >>> >>>>>> typedef TImage ImageType; >>> >>>>>> typedef typename ImageType::PixelType PixelType; >>> >>>>>> typedef typename ImageType::SizeType SizeType; >>> >>>>>> >>> >>>>>> // .. and some dolfin typedefs -- ignore >>> >>>>>> typedef typename std::tr1::shared_ptr<const dolfin::Mesh> >>> >>>>>> MeshConstPointerType; >>> >>>>>> typedef typename std::tr1::shared_ptr<const >>> >>>>>> dolfin::FiniteElement> >>> >>>>>> ElementConstPointerType; >>> >>>>>> typedef typename std::tr1::shared_ptr<const dolfin::DofMap> >>> >>>>>> DofMapConstPointerType; >>> >>>>>> >>> >>>>>> // the ctor >>> >>>>>> DolfinImageFunctionSpace(ImageType* imageData, >>> >>>>>> MeshConstPointerType >>> >>>>>> mesh, >>> >>>>>> ElementConstPointerType >>> >>>>>> element, >>> >>>>>> DofMapConstPointerType >>> >>>>>> dofmap) : >>> >>>>>> dolfin::FunctionSpace(mesh, element, dofmap) >>> >>>>>> { >>> >>>>>> SizeType imageSize = >>> >>>>>> imageData->GetBufferedRegion().GetSize(); >>> >>>>>> >>> >>>>>> // here, we whish to call some thing like: >>> >>>>>> // _mesh = UnitSquare(imageSize[0], imageSize[1]); >>> >>>>>> // but it's private and the accessor is read-only. >>> >>>>>> }; >>> >>>>>> } >>> >>>>>> >>> >>>>> This breaks the concept of a function space. A function space is >>> >>>>> defined >>> >>>>> in terms of a mesh (and other things). A function space does not >>> >>>>> define >>> >>>>> its mesh. >>> >>>>> >>> >>>>> It looks to me like the class that you're creating should be called >>> >>>>> something like >>> >>>>> >>> >>>>> DolfinImageProblem, >>> >>>>> >>> >>>>> which can create its own Mesh, FunctionSpace and other objects. >>> >>>>> >>> >>>>> Garth >>> >>>>> >>> >>>>>> -Ali >>> >>>> I think what you need to do is something like this: >>> >>>> >>> >>>> 1. Create a subclass of Function >>> >>>> >>> >>>> 2. In the constructor of your Function, call the empty Function() >>> >>>> constructor >>> >>>> >>> >>>> 3. Then, still in the constructor of your Function (not >>> >>>> FunctionSpace), create everything necessary like figuring out the >>> >>>> mesh, dofmap etc and from that create a FunctionSpace >>> >>>> >>> >>>> 4. Then use that FunctionSpace (still in the constructor of your >>> >>>> Function subclass) to create a new Function v which uses your special >>> >>>> FunctionSpace in its constructor >>> >>>> >>> >>>> 5. Finally, assign this function to the created Function: >>> >>>> >>> >>>> *this = v; >>> >>> error: no match for 'operator=' in >>> >>> '*(itk::DolfinImageFunction<itk::Image<double, 2u> >*)this = v' >>> >>> >>> >>> Assigning Function to ImageFunction is a trouble, see the full code >>> >>> here: >>> >>> >>> >>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDolfin/src/itkDolfinImageFunction.h#87 >>> >> Do you have the latest hg version? >>> >> >>> >> Function assignment should work (see recent discussion on the mailing >>> >> list on copy constructors and assignment operators for Function). >>> >> >>> >>> I don't understand the philosophy behind this tight security: why no >>> >>> protected member variables? Why is everything either public or >>> >>> private? Needless to say, the protected members were designed to allow >>> >>> class extensions, by banning it, you're making sub classing a >>> >>> unnecessarily complicated task. The above problem has it's own work >>> >>> arounds, but I don't understand why the obvious way is blocked. >>> >> The reason is simply that the constructor arguments in Function and >>> >> FunctionSpace are const. This means no one is allowed to change the >>> >> variables, not even the Function class (or FunctionSpace class) >>> >> itself. For example, it's reasonable when you create a Function on a >>> >> FunctionSpace that the Function will not change the FunctionSpace. >>> > >>> > Whether the member variables are read-only or not, and their >>> > visibility are two separate concepts - you can have any combination of >>> > these. Function and FunctionSpace do change their const variables >>> > anyway, eg, in operator= you have: >>> > >>> > // Assign vector >>> > init(); >>> > dolfin_assert(_vector); >>> > *_vector = *v._vector; >>> > >>> > Which is in contradiction with what you wrote about not even the class >>> > itself cannot change the variables. >>> > >>> >>> Anders was referring to FunctionSpace. Obviously, the vector associated >>> with a discrete Function cannot be const (and it isn't). >>> >>> > It would be rare that all classes have to have read-only inputs, where >>> > the sub-classes are setences to inherit the same properties. Now, I >>> > simply cannot have the right operator= assinging Function to >>> > ImageFunction implemented, since I cannot assign anything to the >>> > private member variables. >>> > >>> > If the visibility of the members variables is not going to change to >>> > protected, or at least a protected read/write accessor is not >>> > provided, then there will be no option but implementing everything in >>> > a third-party class faking the current ImageFunction, as it's not >>> > going to be derived from Function. >>> > >>> >>> All you need to do is create a suitable FunctionSpace before creating >>> your Function. >>> >>> Garth >> >> Yes, and you should be able to create that FunctionSpace inside the >> constructor for your Function subclass. > > Yes, I can _create_ it, but I cannot _assign_ it :) > > Now I'm trying this work around: > > DolfinImageFunction(ImageType* imageData) : > dolfin::Function() > { > ... > // Create a Function instance > FSConstPointerType V = CreateFunctionSpace(); > DolfinImageFunction v(V); > *this = v; > }; > > which requires the repsence of this ctor: > > DolfinImageFunction(boost::shared_ptr<const dolfin::FunctionSpace> V): > dolfin::Function(V) > { > }; > > This might work. > > > -Ali >
The above builds, but then I get thos runtime error: RuntimeError: *** Error: Cannot copy Functions which do not have a Vector (user-defined Functions). The error originates from 'this' instance and not from v. Just in case, here is the full code: http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDolfin/src/itkDolfinImageFunction.h#47 -Ali _______________________________________________ DOLFIN-dev mailing list [email protected] http://www.fenics.org/mailman/listinfo/dolfin-dev
