From: Derek G. <fri...@gm...> - 2009-01-10 00:33:16
|
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 > Lib...@li... > https://lists.sourceforge.net/lists/listinfo/libmesh-devel |