Handling units and dimensional analysis

In this tutorial, we explore a bit more the role of units in SAMSON by developing an app that performs energy conversions. We refer you to the SDK documentation for an extensive description of the units mechanism in SAMSON.

Setting up the SAMSON Element and its interface

Use the SAMSON Element Generator to create a new SAMSON Element called EnergyConverter, containing an app called SEEnergyConverterApp. 

Modify the user interface SEEnergyConverterAppGUI.ui to include two labels, two combo boxes (QComboBox class) and two double spin boxes (QDoubleSpinBox class):

 

Use the following widget names in the inspector, so that you can copy and paste code later in this tutorial:

 

Note how two horizontal layouts are used to align widgets in the interface. One good strategy is to create the first horizontal layout and its contents (e.g. the origin part of the interface), then copy it and rename widgets.

Now, enter the following entries in each combo box:

These are the different units supported by our app to perform conversions.

And change the maximum values allows by the double spin boxes:

Finally, add a slot called onSourceChanged(double) to the interface:

 

and connect the valueChanged(double) signal of the source spin box to this slot:

 

We may now modify the code of the app.

 

Converting energies

Modify the getName function in the SEEnergyConverterAppGUI.cpp file to return a user-friendly name to our app (e.g. Energy Converter).

For a clean organization, we separate the functionality of the app from its interface. As a result, the SEEnergyConverterAppGUI class is going to delegate the actual energy conversion work to the app.

Add the declaration of the slot in the SEEnergyConverterAppGUI.hpp file:

 

In the SEEnergyConverterAppGUI.cpp file, delegate the conversion to the app, and use the result to modify the contents of the destination box:

void SEEnergyConverterAppGUI::onSourceChanged(double) {
 
	ui.doubleSpinBoxDestination->setValue(getApp()->convert(ui.doubleSpinBoxSource->value(),
		ui.comboBoxSource->currentIndex(),
		ui.comboBoxDestination->currentIndex()));
 
}

We may now code the convert function in the app. We add the function declaration in the SEEnergyConverterApp.hpp file:

	double convert(double sourceEnergy, int sourceUnit, int destinationUnit);

we include the header SBQuantity.hpp at the beginning of the SEEnergyConverterApp.cpp file:

#include "SEEnergyConverterApp.hpp"
#include "SEEnergyConverterAppGUI.hpp"
#include "SBQuantity.hpp"

and we define this function at the end of the SEEnergyConverterApp.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double SEEnergyConverterApp::convert(double sourceEnergy, int sourceUnit, int destinationUnit) {
 
	SBQuantity::energy source;
 
	if (sourceUnit == 0) source = SBQuantity::eV(sourceEnergy);
	if (sourceUnit == 1) source = SBQuantity::Eh(sourceEnergy);
	if (sourceUnit == 2) source = SBQuantity::kcalPerMol(sourceEnergy);
	if (sourceUnit == 3) source = SBQuantity::zJ(sourceEnergy);
 
	if (destinationUnit == 0) return (SBQuantity::eV(source)).getValue();
	if (destinationUnit == 1) return (SBQuantity::Eh(source)).getValue();
	if (destinationUnit == 2) return (SBQuantity::kcalPerMol(source)).getValue();
	if (destinationUnit == 3) return (SBQuantity::zJ(source)).getValue();
 
	return 0.0;
 
}

That’s it! Line 3 declares a physical quantity with energy units (zeptoJoules by default in SAMSON). Lines 5 to 8 convert from the source energy to zeptoJoules. Lines 10 to 13 convert from zeptoJoules to the destination unit, and extract the value as a double from the result.

The user may then perform conversions:

 

 

 

Comments are closed.