Let's see... we _do_ have a similar situation in one part of our  
code.... and one solution is instead of storing data as member  
variables of a class.... store them in containers in that class....  
that way there is one interface... but any of the derived objects can  
provide whatever data they like.

For instance... if all of the data in a context is going to be Reals  
you can do this:

class ACon
{
public:
  std::map<std::string, Real> real_data;
}

Then BCon just associates Reals with names and adds them to the  
std::map... say for instance "time" like so:

real_data["time"] = current_time;

Then in BSys when you want to get "time" you do:

time = AConPtr->real_data["time"]

We've actually wrapped a fancy system around this where the derived  
classes of ACon call declareRealProperty("name") in their  
constructors... which returns a reference to the memory that is stored  
in the std::map that the derived class then uses as if it is a class  
member.  Then BSys would actually do this instead:

AConPtr->getProperty("name")

And would get back that reference automatically.... note that there  
are no virtual functions required.

Now... what do you do if you don't know what the types are that your  
derived classes are going to need to store?  You store your values in  
Parameters instead... since they are templated you can store whatever  
you like.... and this essentially lets you associate the name of a  
property with any object you like.

I don't know what to call this method... it reminds me a bit of type  
erasure.... but kind of for a different purpose.  I first started  
doing this type of thing with python.... where it makes a lot of sense  
because you can actually inject new member variables into a class  
(since essentially member variables are just stored in a dictionary  
that associates the name of the variable with it's data.... sounds  
familiar huh?).

Derek

On Jan 9, 2009, at 4:29 PM, Roy Stogner wrote:

>
> To enable a bit more modularity, automatic multithreading, etc., as
> I've mentioned before, I'd like to change the DiffSystem/FEMSystem
> interface.
>
> Right now, the library has methods like:
>
> DiffSystem::element_residual()
>
> Which, overridden by the user, can access DiffSystem member variables
> with state information (like time) and solution information (like
> elem_solution) to fill residual information (like elem_residual and
> elem_jacobian).  This is general enough that we could write structured
> finite difference methods on top of it if we wanted to.
>
> But for now, we all use the only important subclass, FEMSystem, which
> adds more member variables with FEM (or if you wanted, cell-centered
> FVM) specific information - the FE, Quadrature rule, and Elem classes,
> for example.
>
>
> That's fine, but now I'd like to move all those member variables into
> a method argument:
>
> DiffSystem::element_residual(DiffContext&)
>
> So that, in particular, different threads can work on different
> DiffContext objects at the same time without creating multiple
> systems.  We'd then move FEMSystem-specific member variables into a
> FEMContext subclass of DiffContext, and users whose FEMSystem
> subclasses add new member variables would add them to
> "CahnHilliardContext" or some such.
>
>
> People with more C++ intuition than I are already seeing the problem
> that arises?
>
> If BSys subclasses ASys, and BCon subclasses ACon, then
> BSys::method(BCon&) is not an implementation of ASys::method(ACon&),
> and for our purposes BSys::method() won't work with just an ACon&.
> Worse: if ASys is FEMSystem and BSys is UserInventedSystem, then
> there's no way for ASys to even create a BCon to pass in.
>
>
> My workaround ideas aren't great:
>
> Declare BSys::method(ACon&), and force everyone to cast to BCon?  This
> forces new users to write hideous code - either with the overhead of
> dynamic_cast, or with hackish-looking C-style pointer casts.
>
> Create a factory method ACon& ASys::factory(), have BSys reimplement
> it to return BCon (and require that any users who need
> more context do the same), and have ASys call this factory for each
> thread that needs a context?
>
>
> Anyone have any better ideas?
> ---
> Roy
>
> ------------------------------------------------------------------------------
> Check out the new SourceForge.net Marketplace.
> It is the best place to buy or sell services for
> just about anything Open Source.
> http://p.sf.net/sfu/Xq1LFB
> _______________________________________________
> Libmesh-devel mailing list
> Libmesh-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/libmesh-devel


------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Libmesh-devel mailing list
Libmesh-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libmesh-devel

Reply via email to