MastHEad

 


Units Signatures


 

This page briefly describes Units Signatures and how they are used in Kornucopia. Units Signatures are one of the key technology components behind the Kornucopia Units Engine.  While you, the user, never directly interact with these Units Signatures per say, they are used extensively by Kornucopia within its internal tracking and calculations related to Units. The purpose of this page is to briefly describe what they are and how they work so that you can better understand how Kornucopia robustly handles Units.

Listed below are the Kornucopia Units Signature categories:

Primary Signatures and their Principal Unit

    1. length: m (meter)

    2. mass: kg (kilogram)

    3. current: A (ampere)

    4. substance: mol (mole)

    5. luminousIntensity: cd (candela)

    6. currency: currency (generic financial currency for money)

    7. item: item (for tracking "items" or "things". This is a very generic type of unit signature) Added in Kornucopia V5.2-01

    8. time: s (second)

    9. absTemperature: K (Kelvin)

Additional Signatures and their Principal Unit

    1. celsius: degC (Celsius)

    2. fahrenheit: degF (Fahrenheit)

    3. angle: rad (radian)

    4. frequency: Hz (Hertz)

    5. percent: % (percent)

    6. microStrain: uStrain (microStrain) Added in Kornucopia V5.2-01

Each of the Units Signatures above has an associated Principal Unit. When Kornucopia stores and tracks any entity of data type k_units or a Kornucopia compatible data type, it ultimately internally relates any Unit being used as some combination of these Units Signatures and their Principal Units. It is noted that an entity with no units is dimensionless; Kornucopia tracks this also. It is further noted that Kornucopia gives special attention to Units for Celsius or Fahrenheit temperatures, as well as Units related to angle, frequency, percent and microStrain.

Kornucopia's Unit Signatures are divided into two groups, Primary Signatures and Additional Signatures.

Primary Signatures

The Primary Signatures are truly fundamental independent quantities, meaning one Primary Signature is not derivable from any of the other Primary Signatures.  A few examples of how a Unit is represented and tracked internally by Kornucopia's Unit Signatures are listed below.

When Kornucopia performs math operations such as addition, subtraction, multiplication, division, raise to a power, etc., the software internally checks and utilizes the Units Signature information to ensure an accurate and valid calculation, from a Units perspective. This allows you to freely use mixed units in your calculation, such as using the Unit of N and lbf in the same calculation. Kornucopia will handle all needed conversions and Units compatibility checking for you. The Units returned in all math operations (and other math related calculations) are controlled by the active Units Preference (see Units Library and Units Preferences and/or k_unitsPreferenceActivate).  Moreover, when you attempt to perform an invalid Units calculation, such as 5*N + 3*kg, Kornucopia issues an error stating there is an incompatible units error because two units do not resolve to the same primary units signature.  

Additional Tracking

A unique feature of Kornucopia's Units Engine is that it does additional special units-related tracking of Celsius and Fahrenheit temperature Units, as well as Units related to angle, frequency, percent and microStrain. This additional tracking is needed to help ensure that calculations related to these items are done correctly and robustly.

Celsius and Fahrenheit

The meaning and conversion of temperatures using Units of Celsius and Fahrenheit can be problematic due to their potentially affine nature.  

The problem: When you define a variable, say T1 = 100*degC, and then you need or want to convert this temperature to either Fahrenheit, Kelvin, or Rankine, the conversion is NOT clear. From your simple variable definition, there is no information clearly stating if the T1 temperature is a change in temperature or not.  So the method of conversion, affine or non-affine, is not clear. This issue occurs whenever you have Celsius or Fahrenheit temperature Units.

The solution: Kornucopia provides a clear and flexible solution to this problem through the optional ADV argument 'affine' that can be used with the function k_unitsConvert or the k_units data type method convert. It is noted that if you attempt to perform a Unit's conversion starting with or converting to a Unit of Celsius or Fahrenheit and you do not specify the ADV setting of 'affine', then an appropriate error message will be returned instructing you to add this to your command.

Additional information and examples related to working with temperature Units and the use of the 'affine' ADV option are found on the help page Temperature and Frequency.

Frequency, angular frequency, and angles

Kornucopia performs additional internal tracking of Units related to frequency, angular frequency, and angles due to potential difficulties with these types of quantities. This additional tracking allows Kornucopia to automatically convert, in many cases (but not all cases) between Units of frequency (containing some form of a hertz Unit such as Hz, kHz, MHz, etc.) and Units like rpm (revolutions per minute), rad/s, 1/s, etc. The additional tracking enables Kornucopia to tell the difference between 1/s and rad/s (where most software that tracks units cannot do this). This also carries through to enable seamless use of deg (as in angular degree), rad, and rev (as in revolution) in calculations.

Additional information related to working with Units of Frequency, angular frequency, and angles is found on the help page Temperature and Frequency.

Percent (%) and microStrain (uStrain)

Kornucopia's additional internal tracking and logic allows you to use the Unit of percent (%) and microStrain (uStrain) with dimensionless quantities. The ultimate goal of this extra tracking is:

  1. To allow the % Unit or the uStrain Unit to "smartly" stay with variables and entities when appropriate and then for it to disappear when appropriate (while applying the appropriate factor of 0.01 for % or 1e-6 for uStrain).

  2. That all calculations with and without % Units process the factor of 0.01 automatically (internally) so that you, the user, are NOT placing factors of  0.01 (or 100) all over your calculations.

  3. That all calculations with and without uStrain Units process the factor of 1e-6 automatically (internally) so that you, the user, are NOT placing factors of  1e-6 (or 1e6) all over your calculations.

The Unit of percent can be associated to dimensionless quantities such as, for example, a ratio or a variable representing strain.  The percent Unit might be associated to an entity because that Unit was in a text file that was imported, or perhaps you did a Unit conversion of an entity to the Unit of percent (%). Regardless of how the percent Unit becomes associated with an entity, the Unit of percent will stay with the entity until some math operation that multiplies the entity by other quantities having some form of Units other than purely dimensionless, or until you issue a Units conversion command the converts the entity to something without percent. It is noted that a purely dimensionless entity has zero powers for all of its Units Signatures.  The same comments are valid for uStrain, although you would typically only use this type of Unit for strain and not other dimensionless quantities.

The simple example below working with strain, modulus (E), and stress demonstrates the general concept of how Kornucopia allows you to naturally and easily work with percent (%) and microStrain (uStrain).

 

% Activate a Units Preference and define
% a handy units variable of MPa
k_unitsPreferenceActivate('mm_N_s')
k_unitsVariables('MPa, uStrain')

% Given
strain = 2000*uStrain
E = 100*MPa

% Calculate stress
stress = E*strain

% Convert strain to Units of percent
strain = strain.convert('%')

% Recalculate stress
stress = E*strain

% Scale strain by purely dimensionless value
strain = 3*strain

% Convert strain back to uStrain Units
strain = strain.convert('uStrain')

 
% Subtract 1000*uStrain, but via a dimensionless #
strain = strain - 0.001