Object and input management =========================== Using the object system ----------------------- NEML uses a factory system tied to a ParameterSet class to create objects and manage input from python or XML data files. The system is setup to incur minimal work when setting up a new object while ensuring that the input syntax for the XML files is generated automatically and will be consistent with the C++ library. All a user needs to do to include a new object in the global factory and make it available from the XML input is: 1. Inherit from :cpp:class:`neml::NEMLObject`. 2. Implement three static class methods: 1. ``static std::string type()`` 2. ``static ParameterSet parameters()`` 3. ``static std::unique_ptr initialize(ParamemterSet & params)`` 3. In the header file describing the object include ``static Register regObjectName`` where ``ObjectName`` is the name of the new class. ``type()`` must return a string type of the object, used to refer to it in the factory. This must be unique across all the NEML objects and we require it to match the class name for classes to be merged into the main NEML project. This example shows the implementation of this method for :cpp:class:`neml::SmallStrainPerfectPlasticity` .. code-block:: c++ std::string SmallStrainPerfectPlasticity::type() { return "SmallStrainPerfectPlasticity"; } ``parameters()`` returns a ParameterSet object that informs the object system what parameters the object will require and sets values for default parameters, if the object has any. The implementation for :cpp:class:`neml::SmallStrainPerfectPlasticity` is .. code-block:: c++ ParameterSet SmallStrainPerfectPlasticity::parameters() { ParameterSet pset(SmallStrainPerfectPlasticity::type()); pset.add_parameter("elastic"); pset.add_parameter("surface"); pset.add_parameter("ys"); pset.add_optional_parameter("alpha", std::make_shared(0.0)); pset.add_optional_parameter("tol", 1.0e-8); pset.add_optional_parameter("miter", 50); pset.add_optional_parameter("verbose", false); pset.add_optional_parameter("max_divide", 8); return pset; } Note that other NEML objects must be added as type ``NEMLObject`` and not their subclass type. ``initialize(ParameterSet &)`` initializes an object from a parameter set, returning it as a ``std::unique_ptr``. :cpp:class:`neml::SmallStrainPerfectPlasticity` implements it as .. code-block:: c++ std::unique_ptr SmallStrainPerfectPlasticity::initialize(ParameterSet & params) { return make_unique( params.get_object_parameter("elastic"), params.get_object_parameter("surface"), params.get_object_parameter("ys"), params.get_object_parameter("alpha"), params.get_parameter("tol"), params.get_parameter("miter"), params.get_parameter("verbose"), params.get_parameter("max_divide") ); } Finally, including the static registration class in the object header registers it automatically with the factory. XML input --------- The XML input system automatically picks up the correct parameters from the ``parameters()`` static method. For example, the following XML creates a :cpp:class:`neml::SmallStrainPerfectPlasticity` object. Notice how the parameter names match those provided in the definition of the C++ object. The input system knows how to recursively ask for parameters to define the other types of NEML objects needed. For example, this :cpp:class:`neml::SmallStrainPerfectPlasticity` requires a :cpp:class:`neml::LinearElasticModel` and the parameters all require :cpp:class:`neml::Interpolate` objects. .. code-block:: xml -100.0 100000.0 youngs 0.3 poissons 100.0 300.0 500.0 700.0 1000.0 120.0 60.0 30.0 0.1 NEMLObject ---------- .. doxygenclass:: neml::NEMLObject :members: ParameterSet ------------ .. doxygenclass:: neml::ParameterSet :members: