Metadata and Metaforcefields

With the paper now out of the way, I have been concentrating on cleaning up parts of Sire that I am not happy with. The first thing to change was the forcefields. While designing the forcefields I used separate code for each pair-pair forcefield, despite each one using the same basic ideas (so I had seperate LJFF, CoulombFF and CLJFF, each with their own class for intermolecular all molecules - InterLJFF, InterCoulombFF and InterCLJFF, each with own intermolecular grouped FF, InterGroupLJFF, InterGroupCoulombFF and InterGroupCLJFF). There was no point trying to unify this code while I was still designing the forcefield, as I couldn't pinpoint what should be common, and what should be separate. However, now that I've been designing the intramolecular forcefields, the effort required to write Intra??FF and IntraGroup??FF versions of each two-body forcefield has forced me to work out how to unify the codebase. However, now, I have working forcefields so I have been able to work out how to combine things together efficiently. The key is not to try to make the combination at runtime, but to do so at compile time (when it is much more efficient). I have thus created template metaforcefield classes for any two-body forcefields; Inter2BodyFF, InterGroup2BodyFF, Intra2BodyFF and IntraGroup2BodyFF. These template classes each inherit from a supplied base class, e.g. CLJFF, which is the base class for all CLJ forcefields. Each base FF class provides a Molecule class, and functions which calculate the energy between these molecules, and within a molecule. The forcefield metaclasses then use these low-level functions to calculate the energy. This means that adding a new two-body forcefield is now much easier - you just create a new base class (e.g. LJFF, CoulombFF, MorseFF), and then use the metaforcefield classes to create all of the inter- and intra- versions.

In creating the meta forcefields, I have also revisited the use of properties to supply forcefield parameters. I've really engaged with properties, and am now using them for pretty much everything. With this in mind, I've rewritten the Property base class so that it is now much easier to make any virtual class hierarchy into a Property. I now plan to make everything in Sire into a Property. I have now also created a Properties class, which can hold a collection of Property objects. Each property is organised by key, but most usefully, each property can also have a piece of metadata attached to it. The metadata is itself also a Property, which itself can have some metametadata attached (ad infinitum!). AND as Properties can also be a Property, this means that everything can be nested as much as you like. I will switch Molecule over so that it uses properties for everything (including coordinates and bonding). This means that you can give a Molecule several different sets of coordinates and bonding (including coordinates that could have more than 3 dimensions!). This will provide an extreme level of flexibility, with different forcefields potentially having different coordinate representations of the molecule (or allowing the user to change coordinates between different sets, perhaps as part of an MC move?). AND, now that Qt 4.3 has a streaming XML class, I've just about sorted out a way of streaming all of the properties and metadata into a clean and friendly XML file. This should allow me to have a nice, friendly and flexible XML file format that I can use for Molecules, Simulations, restart files, log files etc. Things are moving on!