5. Verification of the Type Library
To verify the functionality of the TL, dedicated C++ units were created for each subnamespace. In this section, we will focus on the verification of the Geometry_SI namespace as an example.
Let′s consider the operations with the Area class within the Geometry_SI namespace:
Area area(100); //[square metre == m2 l=0]
AreaX areax(10); //[square metre == m2 l=x]
AreaY areay(10); //[square metre == m2 l=y]
AreaZ areaz(10); //[square metre == m2 l=z]
area = length0 * length0; areax = lengthy * lengthz;
areay = lengthx * lengthz; areaz = lengthx * lengthy;
double k = 10;
areaz *= k; areay /= k;
In the above code, we create instances of the Area class, along with AreaX, AreaY, and AreaZ classes, representing areas with different orientations.
We perform various operations to verify the correct behavior of the TL:
By performing these verification operations, we can validate the proper implementation of the Geometry_SI namespace within the TL;
In the second verification, we will examine operations involving the Curvature class within the Geometry_SI namespace.
Curvature curvarure(1); //[reciprocal metre == 1/m l=0]
CurvatureX curvarurex(1);//[reciprocal metre == 1/m l=x]
CurvatureY curvarurey(2);//[reciprocal metre == 1/m l=y]
CurvatureZ curvarurez(3);//[reciprocal metre == 1/m l=z]
// curvaturex = length0 / lengthx; error
curvarurex = 1.0 / lengthx; lengthx = 1.0 * lengthx;
In the provided code, we create instances of the Curvature class, along with CurvatureX, CurvatureY, and CurvatureZ classes, representing curvatures with different orientations.
We perform the following operations to verify the behavior of the TL.
Initially, we attempt to assign the result of length0 / lengthx to the curvaturex variable. However, this operation is invalid because the TL enforces the homogeneity of dimensions and orientations for valid mathematical operations. Since length0 has a dimension of [L^0], it cannot be divided by lengthx with a dimension of [L^x], resulting in an error.
Next, we assign the inverse of lengthx (1.0 / lengthx) to the curvaturex variable, demonstrating the ability of the TL to handle dimensionally consistent operations.
Finally, we perform a valid operation where lengthx is multiplied by 1.0, ensuring that the TL correctly handles scalar multiplication with a dimensioned quantity.
By verifying these operations and ensuring the expected outcomes, we can confirm the proper implementation of the Curvature class and its orientation-specific counterparts within the Geometry_SI namespace of the TL.
Now let′s proceed with the verification of trigonometric functions within the TL:
double lcosd = cos(1.25), dlx=0.5 , dly=0.6, dlz=0.7, dl=0.8;
PlaneAngleX planeAnglex(0.5);
PlaneAngleY planeAngley(0.4);
PlaneAngleZ planeAnglez(0.3);
Dimensionless lcosx = cos(planeAnglex);
Dimensionless lcosy = cos(planeAngley);
Dimensionless lcosz = cos(planeAnglez);
double lsind = sin(1.25);
DimensionlessX lsinx = sin(planeAnglex);
DimensionlessY lsiny = sin(planeAngley);
DimensionlessZ lsinz = sin(planeAnglez);
double ltan = tan(1.25);
DimensionlessX ltanx = tan(planeAnglex);
DimensionlessY ltany = tan(planeAngley);
DimensionlessZ ltanz = tan(planeAnglez);
double acosd = acos(0.5);
PlaneAngleX acosx = acos(dlx);
PlaneAngleY acosy = acos(dly);
PlaneAngleZ acosz = acos(dlz);
double asind = asin(0.5);
PlaneAngleX asinxd = asinx(dl);
PlaneAngleY asinyd = asiny(dl);
PlaneAngleZ asinzd = asinz(dl);
// double d0 = sin(planeAngle); errors!!! OK
// double dx = sin(planeAnglex);
// double dy = sin(planeAngley);
// double dz = sin(planeAnglez);
The provided code snippet focused on the verification of specific classes within the Geometry_SI namespace. However, similar checks were conducted for all other classes and operations within the TL to ensure their correctness and adherence to the defined rules and principles.
SI defines some set of prefixes of physical values. The provided code defines a list of prefixes used in the SI to denote physical values. Each prefix is associated with a name, symbol, and a corresponding decimal factor:
const PNSD_SI prefixList[24] = {
{"quetta","Q", 1e30 }, {"ronna", "R", 1e27}, {"yotta", "Y", 1e24},
{"zetta", "Z", 1e21 }, {"exa", "E", 1e18}, {"peta", "P", 1e15 }, {"tera", "T", 1e12 },
{"giga", "G", 1e9 }, {"mega", "M", 1e6 }, {"kilo", "k", 1e3 }, {"hecto", "h", 1e2},
{"deca", "da", 10 }, {"deci", "d", 1e-1 }, {"centi", "c", 1e-2 },
{"milli", "m", 1e-3 }, {"micro", "u", 1e-6 }, {"nano", "n", 1e-9 },
{"pico", "p", 1e-12 }, {"femto", "f", 1e-15}, {"atto", "a", 1e-18},
{"zepto", "z", 1e-21}, {"yocto", "y", 1e-24}, {"ronto", "r", 1e-27}, {"quecto", "q", 1e-30} };
In the following code example, you can observe the utilization of prefixes for initializing physical quantities:
Mass m(15., prefix::micro), m2(20.,nano), m3(1);
Current currentI1(2.), currentI2(2., prefix::nano), currentI3(2., prefix::kilo);
Volume w0(23, prefix::milli), w;
Current i1(100);
Based on the provided code, the following interpretations can be made:
For mass (m), the value is 15 * 10-6 kg (15 milli grams);
For currentI1, the value is 2 A (amperes);
For currentI2, the value is 2 * 10-9 A (2 nano amperes);
For currentI3, the value is 2000 A (2 kilo amperes).
It′s important to note that the code example assumes the availability of appropriate class definitions for Mass, Current, and Volume, which handle the incorporation of prefixes for physical quantities.
In the following code snippet, we can observe the configuration and utilization of print settings for physical quantities:
i1.setPrintPrefixSymbol();
i1.setPrintQuantitySymbol();
cout << "i1=" << i1;
currentI2.setPrintPrefixName();
currentI2.setPrintQuantityName();
currentI2.setPrintDimensionSymbol();
cout << "i2=" << currentI2 << endl;
currentI2 *= 2;
cout << "i2=" << currentI2 << endl;
currentI2 = currentI2 * 2.1 + i1;
cout << "i2=" << currentI2 << endl;
Code sets the print options:
For i1 to display the prefix symbol and the quantity symbol. Then, it prints the value of i1;
For currentI2 to show the prefix name, quantity name, and dimension symbol. Afterward, it prints the value of currentI2;
Multiplies currentI2 by 2 and prints the updated value;
Performs calculations on currentI2, multiplying it by 2.1 and adding i1. Finally, it prints the final value of currentI2.
In the following
Figure 3, you can observe the output of physical quantities with different settings: printing prefixes (without prefix, name, symbol), printing quantities (without quantity, name, symbol), and printing dimensions (without dimension and dimension vector).
In the above figure:
i1 = 100 A (or 1 hA or 1 hecto A);
i2 = 2 nA, vector [0, 0, 0, 1, 0, 0, 0];
edf = 1.2 coulomb per square meter;
r1 = 1 kΩ, vector [-3, 2, 1, -2, 0, 0, 0].
This comprehensive output process ensures the reliability verification of the CPS embedded software.
The proposed TL was developed with the assistance of Microsoft Visual Studio Community 2022 Version 17.1.2. This widely-used development environment played a crucial role in the elaboration and creation of the TL, ensuring compatibility and leveraging the powerful features and tools provided by Visual Studio for efficient development and implementation.
The thorough verification process ensures the reliability, accuracy, and effectiveness of the TL implementation across diverse subject areas and namespaces. This process instills confidence in the TL′s functionality and usability, making it a dependable tool for software development and related tasks.