Composite Components

What we do now

For example, if you want to add "velocity" to a model, in the model XML file, you:

...
<include>StgFEM/VelocityField.xml</include>
...

Where VelocityField.xml looks like...

...
        <struct name="components" mergeType="merge">
                <struct name="velocity">
                        <param name="Type">MeshVariable</param>
                        <param name="mesh">velocityMesh</param>
                        <param name="Rank">Vector</param>
                        <param name="DataType">Double</param>
                        <param name="VectorComponentCount">dim</param>
                        <list name="names">
                                <param>vx</param>
                                <param>vy</param>
                                <param>vz</param>
                        </list>
                </struct>
                <struct name="velocityBCs">
                        <param name="Type">CompositeVC</param>
                        <param name="Data">velocityMesh</param>
                </struct>
                <struct name="velocityICs">
                        <param name="Type">CompositeVC</param>
                        <param name="Data">velocityMesh</param>
                </struct>               
                <struct name="velocityDofLayout">
                        <param name="Type">DofLayout</param>
                        <param name="mesh">velocityMesh</param>
                        <param name="BaseVariableCount">dim</param>
                        <list name="BaseVariables">
                                <param>vx</param>
                                <param>vy</param>
                                <param>vz</param>
                        </list>
                </struct>
                <struct name="VelocityField">
                        <param name="Type">FeVariable</param>
                        <param name="FEMesh">velocityMesh</param>
                        <param name="DofLayout">velocityDofLayout</param>
                        <param name="BC">velocityBCs</param>
                        <param name="IC">velocityICs</param>
                        <param name="LinkedDofInfo">velocityLinkedDofs</param>
                </struct>
...

The problem here is

  1. You can only include this once.
  2. If you wanted another 3-component variable you have to copy, paste and change VelocityField.xml.
  3. If you include something that includes this file, you're stuck with it.

What we want to be able to do

What we want to be able to do is view what occurs above as not the inclusion of some predefined list of components, but as an abstraction that is a component (re-use, instance names, etc) that effectively does the same things.

Proposal

Following the above example, in the model file:

...
        <struct name="components" mergeType="merge">
                ...
                <struct name="VelocityField">
                        <param name="Type">DimComponentField</param>
                        <param name="mesh">velocityMesh</param>
                        <param name="DataType">double</param>
                </struct>
                ...

Which says create a field called VelocityField, that will create the necessary variable, boundary conditions and initial conditions. These subcomponents would have the auto generated names of VelocityField-variable, VelocityField-variable, VelocityField-BCs, VelocityField-ICs, VelocityField-dofLayout, and VelocityField-linkedDofLayout.

The magic then is how do we describe what we want to do here.

... create new component...

sub components { 
        { "MeshVariable", "variable" }, 
        { "CompositeVC", "BCs" },
        { "CompositeVC", "ICs" },
        { "DofLayout", "dofLayout" },
        { "FeVariable", 0 } 
};
map parameters {
        /* subcomponent name, component parameter, subcomponent parameter, function */
        { "variable", "mesh", "mesh", 0 },
        { "ICs", "mesh", "Data", 0 },
        ...
};