For polymorphic classes, use the non-virtual-interface idiom. Down the hierarchy, virtual functions should almost always be private — protected only in the case when a derived class uses the class’s implementation.
All information available at compile time (in particular, the complete layout of the simulated system) should be processed as such, with the help of template metaprogramming.
Interactions should not bother with shifting frequencies as in C++QEDv1, because these frequencies appear at so many places that it is hardly possible to track them all. Instead, the shift of frequencies, when required at all, should be performed on the highest level, that is, in scripts like 1particle1mode.
The basic data structures should be built on Blitz++ — memory block of doubles, state vectors, complex matrices, etc.
All non-trivial numerics should be performed by GSL with bindings developed in utils. Alternative implementations are possible.
Basic linear algebra should be tackled using the Blitz++ operators, while more involved ones using FLENS/LAPACK.
Rely heavily on STL, TR1, Boost both in design and implementation, however, use Boost instead of TR1: TR1 support for gcc appears scarce, and what is implemented doesn’t interoperate well with other parts of Boost. (E.g. boost::lambda and tr1::function)
Elements should declare their parameter structs in their own namespaces, and split them into separate header & implementation files. Eg. ParsParticle -> particle::Pars.
In object hierarchies make the objects noncopyable, but allow them to be cloneable. Then they can be conveniently manipulated by Boost.PointerContainers.