Self-Registration Recipe

This recipe is incomplete and out-of-date and needs to be adapted

Purpose

This recipe assumes you have completed sucessfully the SelfRegistrationRecipe.

The purpose of this recipe is to show the use of the following features of the COOLFluiD framework:

  • ConfigurationFacility

At the end of this recipe you should be able to understand how objects in COOLFluiD can be configured by the user, and havin thus their behavior changed.


!!Step 1!! Go to the "Recipes" directory. Go into the "Recipe02" directory. Edit the file "main.cxx" and you should find inside the coding result of the previous SelfRegistrationRecipe. Compile it with the same command as before.

Now add the followin class before the main() function:

[<html>] <SPAN style="color:#333333;background-color:#cccccc;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;"> class ProgramConfig : public ConfigObject { public:

ProgramConfig() : ConfigObject("ProgConfig"), _physModel(), _geoEnt() {

_physModel = "Null"; addConfigOption("PhysicalModel",

"Description of this parameter goes here.", &_physModel);

_geoEnt = "Null"; addConfigOption("GeoEnt",

"Description of this parameter goes here.", &_geoEnt);

}

CFString getPhysicalModelName() const {

return _physModel;

}

CFString getGeometricEntityName() const {

return _geoEnt;

}

private:

CFString _physModel;

CFString _geoEnt;

}; // end class ProgramConfig

int main() {

</span> [</html>]

This class derives from the class ConfigObject in the framework. It allows to have a certain functionality, that is used imediatly in the constructor. The constructor of ConfigObject is called, by passing a name "ProgConfig" which basically associates a name with this class. In the body of the constructor, two calls to functions addConfigOption() define the parameters that can be configured in this class. It assigns a key to each parameter, "PhysicalModel" and "GeoEnt". These will be used in the configuration.


!!Step 2!!

Now you need to use this new class. In the body of main() change the first entries to the following code, while the rest remains the same.

[<html>] <SPAN style="color:#333333;background-color:#cccccc;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;">

try {

ProgramConfig cfg;

cfg.configure();

PhysicalModel::setPhysicalModelImpl(cfg.getPhysicalModelName());

VolumeIntegrator::getInstance().setIntegrationForAllGeo(GAUSSLEGENDRE,ORDER1);

BaseGeometricEntityProvider&#60Cell&#62* cellProvider =

GeometricEntityFactory&#60Cell&#62::getProvider(cfg.getGeometricEntityName());

const CFluint nbStatesInCell = 3;

</span> [</html>]

The first added line creates an object instance of the class ProgramConfig, while the second orders it to configure itself. We have also changed the entries where the names of the PhysicalModel and GeometricEntity Provider were hardcoded to a call to the object cfg to get the names which now should be got through configuration.

Try to compile the program. The run it, and you should get the following result:

[<html>] <SPAN style="color:#000000;background-color:#FFFFCC;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;"> prompt:Recipe02> ./program COOLFluiD Recipe 2 starting: Configuring: ProgConfig Set PhysicalModel to: Null NoSuchValueException: GeometricEntityFactory<TYPE>::getProvider() Null not registered Aborting ... </span> [</html>]


!!Step 3!!

First we see that the PhysicalModel being setup is a "Null" physical model. That is exactly the default parameter we chose for the CFString in ProgramConfig constructor. This does not sound good. Lets fix it by actually informing the program which PhysicalModel we want by setting an enviromental variable.

[<html>] <SPAN style="color:#000000;background-color:#FFFFCC;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;"> export ProgConfig_PhysicalModel="Euler2D" </span> [</html>]

The enviromental variable shows the name of the object we want to configure and the parameter separated with a underscore. The names must always be fully qualified. Meaning that if an object was nested inside 2 objects, the whole name should be chosen, as NameObject1_NameObject2_parameter.

Try to run now the program again. The output should be:

[<html>] <SPAN style="color:#000000;background-color:#FFFFCC;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;"> COOLFluiD Recipe 2 starting: Configuring: ProgConfig Set PhysicalModel to: Euler2D NoSuchValueException: GeometricEntityFactory<TYPE>::getProvider() Null not registered Aborting ... </span> [</html>]

The program now configures correctly the PhysicalModel with the name taken from the enviromental variable. But it is still issuing a exception because the GeoEnt parameter is still "Null".


!!Step 4!!

We will now try to read it form a file. For that, edit a file name "Config.txt" and insert the following text inside:

[<html>] <SPAN style="color:#333333;background-color:#cccccc;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;"> # comments can be started by # and will be ignored ProgConfig.GeoEnt = LagrangeTriagP1P1 </span> [</html>]

Then we must change the main.cxx code to make it configure from this file. Note that the configuration via enviromental variables will not be affected, and actually will have preference over the file. As the code below shows, we set the configuration file for the object cfg to be "Config.txt". When we call configure he will read the file, configure himself from it, and then check the the enviromental variables also.

[<html>] <SPAN style="color:#333333;background-color:#cccccc;font-size:10px;border: 1px solid gray;padding:5px 5px 5px 5px;white-space: pre; display:block;">

try {

ProgramConfig cfg;

cfg.setConfigFile("Config.txt");

cfg.configure();

</span> [</html>]

After this change, compile and run, and the program should run smoothly without errors.

You may notice that in the directory were you have been working a new file has appeared. This file is called "config.log" and holds the log of the configuration phase of the program. Mind that the mode in which the file is accessed is "append", so it will hold all the logs of all the runs of the program. If you want to just see the log of one of the runs, just remove the file before running.

Congratulations!! You're done with this recipe'''


!!!See also!!! This recipe continues in DataStorageRecipe.