← Back to team overview

dolfin team mailing list archive

Re: [UFC-dev] added higher mesh variable

 

On Thu, Apr 30, 2009 at 08:54:23AM -0400, Shawn Walker wrote:
>
> On Thu, 30 Apr 2009, Ola Skavhaug wrote:
>
>> Why not go for Martin's suggestion?
>>
>> Inheritance is a well known concept in C++, and it avoids using the
>> evil macros that notoriously break compilation when people forget
>> their ifndefs. Extending ufc with subclasss in a namespace, say eufc,
>> dynamic casting in experimental assemblers when needed, and finally,
>> moving functionality up the inheritance chain when settled seems to me
>> a better solution than what is happening now?
>
> Why not do it?
>
> Reasons:
>
> 1. I'm not that adept at C++ to know how to do what you are saying.  Nor  
> do I forsee myself learning this in the near future. (i.e. like all this  
> dynamic casting stuff).
>
> 2. This `eufc' is only for experimentation and I would assume it will not 
> be a permanent piece of the code.
>
> 3. The original reason for doing this, was to basically just add some  
> freaking variables!

I know, and that's exactly the point. Before we had UFC, the interface
between FFC and DOLFIN changed all the time. Now we have two form
compilers and other projects using UFC or considering using it. So we
need to keep it stable and make sure we know what we want before
making changes. Any change to ufc.h will require changes to DOLFIN, FFC,
SyFi/SFC, and all code that has ever been generated for UFC 1.1.

> Why do we have to make it so complicated?  
> Furthermore, these additions (if made to the real ufc.h) would not have  
> changed anything.  The current modules now would just not use those new  
> data structs.  It would have been completely backwards compatible.  But I 
> understand you want to keep ufc and its doc's up to date.
>
> If someone wants to set this up, be my guest (see #1).  I would certainly 
> appreciate it.  I don't know how to do it.

I talked to Martin and Ola today and they convinced me we should use
inheritance, not macros (#ifdef).

The reason is that with inheritance, we can freely extend the classes
in ufc.h and the code (DOLFIN) will still work with the official UFC
interface. With #ifdef, one would not be able to assemble forms
compiled for the official UFC interface with DOLFIN when the
UFC_EXPERIMENTAL flag is set.

Here's a summary of what needs to be done:

1. Create a file named ufce.h and place it in dolfin/fem/ as part of
DOLFIN.

2. This file defines subclasses of the UFC classes that need to be
extended. It can look something like this:

#include <ufc.h>

namespace ufce
{
  
  class cell : public ufc::cell
  {
  public:

    /// Array of coordinates for higher order vertices of the cell
    double** higher_order_coordinates;

  };

}

3. UFCCell needs to inherit from ufce::cell, not ufc::cell. That means
it is still a ufc::cell since ufce::cell is a ufc::cell.

4. In places where we assume that we have a ufce::cell and not a
ufc::cell, we make a dynamic_cast and issue an error if the cast fails
(which indicates that the form that comes in is not a ufce form but a
ufc form). A dynamic_cast of a pointer can be done like this:

  Bar* bar = dynamic_cast<Bar*>(foo);

Here, foo is a pointer to a Foo and Bar is a subclass of Foo.
If the cast fails, a zero pointer will be returned indicating that foo
is not a Bar, only a Foo.

-- 
Anders

Attachment: signature.asc
Description: Digital signature


Follow ups

References