Hi All,
I have a general design question that I'm hoping some of you can help me with. For illustration, let's say I'm solving a solid mechanics problem where the user is allowed to choose between two materials, each represented by a different class: MaterialOne and MaterialTwo. These two classes are derived from a common base class MaterialBase. The two materials have totally different input parameters, however, and therefore their parameters must be defined by the derived class and not the parent class. One material might be a linear elastic model with two parameters, and the other an elastoplastic material with five parameters. Ultimately, I would like to be able to parse a parameter file where the user first specifies which of the materials to use, and then provides the necessary input parameters for that specific material. That is, the parameter file might look like:
set material_type = One
subsection MaterialOne
set property_specific_to_One = 1.0
end
The main issue I see here is that a ParameterHandler needs all parameters to be declared upfront, before it attempts to parse the input file. That is, we should declare all possible parameters for both MaterialOne and MaterialTwo, even if MaterialTwo will never be encountered. For this simple example that's not really a big deal. I'm thinking ahead, however, to the more complex case where we have, say, 10 possible material types, as well as a heterogeneous body where the mesh is broken into 10 different material IDs. This "speculative declaration" approach then doesn't seem like the most elegant solution.
I was wondering if anyone has encountered a similar problem, or has suggestions for an alternative approach? If not, I will pursue the simple solution. Perhaps declaring a large number of unused parameters will not actually matter very much. It is also probably the easiest to implement.
As background, each subclass has a function to declare the necessary parameters, and then parse them after the parameter file is read:
MaterialOne.declare_parameters(ParameterHandler &prm) { ... }
MaterialOne.parse_parameters(ParameterHandler &prm) { ... }
MaterialTwo.declare_parameters(ParameterHandler &prm) { ... }
MaterialTwo.parse_parameters(ParameterHandler &prm) { ... }
Similarly, the main solver class does the same:
SolidMechanicsProblem.declare_parameters(ParameterHandler &prm) { ... }
SolidMechanicsProblem.parse_parameters(ParameterHandler &prm) { ... }
In the current approach, the main solver class would call the necessary material classes in a hierarchical way:
SolidMechanicsProblem::declare_parameters (ParameterHandler &prm)
{
// declare all possible material model parameters here
MaterialOne::declare_parameters(prm);
MaterialTwo::declare_parameters(prm);
// ... declare a list of potential material types here: One or Two
}
Thanks up front for any suggestions you may have,
Josh