Skip to content

Commit

Permalink
Read unit definitions for FMI2
Browse files Browse the repository at this point in the history
  • Loading branch information
robbr48 committed Oct 30, 2024
1 parent faa672a commit 6ae92c0
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/fmi4c.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ FMI4C_DLLAPI fmi2Status fmi2_exitInitializationMode(fmiHandle* fmu);
FMI4C_DLLAPI fmi2Status fmi2_terminate(fmiHandle* fmu);
FMI4C_DLLAPI fmi2Status fmi2_reset(fmiHandle* fmu);

FMI4C_DLLAPI int fmi2_getNumberOfUnits(fmiHandle *fmu);
FMI4C_DLLAPI fmi2UnitHandle *fmi2_getUnitByIndex(fmiHandle *fmu, int i);
FMI4C_DLLAPI const char* fmi2_getUnitName(fmi2UnitHandle *unit);
FMI4C_DLLAPI bool fmi2_hasBaseUnit(fmi2UnitHandle *unit);
FMI4C_DLLAPI void fmi2_getBaseUnit(fmi2UnitHandle *unit, double *factor, double *offset, int *kg, int *m, int *s, int *A, int *K, int *mol, int *cd, int *rad);
FMI4C_DLLAPI int fmi2_getNumberOfDisplayUnits(fmi2UnitHandle *unit);
FMI4C_DLLAPI void fmi2_getDisplayUnitByIndex(fmi2UnitHandle *unit, int id, const char **name, double *factor, double *offset);

FMI4C_DLLAPI fmi2Status fmi2_getReal(fmiHandle* fmu, const fmi2ValueReference valueReferences[], size_t nValueReferences, fmi2Real values[]);
FMI4C_DLLAPI fmi2Status fmi2_getInteger(fmiHandle* fmu, const fmi2ValueReference valueReferences[], size_t nValueReferences, fmi2Integer values[]);
FMI4C_DLLAPI fmi2Status fmi2_getBoolean(fmiHandle* fmu, const fmi2ValueReference valueReferences[], size_t nValueReferences, fmi2Boolean values[]);
Expand Down
1 change: 1 addition & 0 deletions include/fmi4c_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ typedef struct fmiHandle fmiHandle;
typedef struct fmi1VariableHandle fmi1VariableHandle;
typedef struct fmi1BaseUnitHandle fmi1BaseUnitHandle;
typedef struct fmi2VariableHandle fmi2VariableHandle;
typedef struct fmi2UnitHandle fmi2UnitHandle;
typedef struct fmi3VariableHandle fmi3VariableHandle;
typedef struct fmi3UnitHandle fmi3UnitHandle;

Expand Down
133 changes: 133 additions & 0 deletions src/fmi4c.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,75 @@ bool parseModelDescriptionFmi2(fmiHandle *fmu)
parseBooleanAttributeEzXml(modelExchangeElement, "providesDirectionalDerivative", &fmu->fmi2.me.providesDirectionalDerivative);
}

ezxml_t unitDefinitionsElement = ezxml_child(rootElement, "UnitDefinitions");
if(unitDefinitionsElement) {
//First count number of units
fmu->fmi2.numberOfUnits = 0;
for(ezxml_t unitElement = unitDefinitionsElement->child; unitElement; unitElement = unitElement->next) {
if(!strcmp(unitElement->name, "Unit")) {
++fmu->fmi2.numberOfUnits;
}
}
if(fmu->fmi2.numberOfUnits > 0) {
fmu->fmi2.units = malloc(fmu->fmi2.numberOfUnits*sizeof(fmi2UnitHandle));
}
int i=0;
for(ezxml_t unitElement = unitDefinitionsElement->child; unitElement; unitElement = unitElement->next) {
if(strcmp(unitElement->name, "Unit")) {
continue; //Wrong element name
}
fmi2UnitHandle unit;
unit.baseUnit = NULL;
unit.displayUnits = NULL;
parseStringAttributeEzXml(unitElement, "name", &unit.name);
unit.numberOfDisplayUnits = 0;
for(ezxml_t unitSubElement = unitElement->child; unitSubElement; unitSubElement = unitSubElement->next) {
if(!strcmp(unitSubElement->name, "BaseUnit")) {
unit.baseUnit = malloc(sizeof(fmi2BaseUnitHandle));
unit.baseUnit->kg = 0;
unit.baseUnit->m = 0;
unit.baseUnit->s = 0;
unit.baseUnit->A = 0;
unit.baseUnit->K = 0;
unit.baseUnit->mol = 0;
unit.baseUnit->cd = 0;
unit.baseUnit->rad = 0;
unit.baseUnit->factor = 1;
unit.baseUnit->offset = 0;
parseInt32AttributeEzXml(unitSubElement, "kg", &unit.baseUnit->kg);
parseInt32AttributeEzXml(unitSubElement, "m", &unit.baseUnit->m);
parseInt32AttributeEzXml(unitSubElement, "s", &unit.baseUnit->s);
parseInt32AttributeEzXml(unitSubElement, "A", &unit.baseUnit->A);
parseInt32AttributeEzXml(unitSubElement, "K", &unit.baseUnit->K);
parseInt32AttributeEzXml(unitSubElement, "mol", &unit.baseUnit->mol);
parseInt32AttributeEzXml(unitSubElement, "cd", &unit.baseUnit->cd);
parseInt32AttributeEzXml(unitSubElement, "rad", &unit.baseUnit->rad);
parseFloat64AttributeEzXml(unitSubElement, "factor", &unit.baseUnit->factor);
parseFloat64AttributeEzXml(unitSubElement, "offset", &unit.baseUnit->offset);
}
else if(!strcmp(unitSubElement->name, "DisplayUnit")) {
++unit.numberOfDisplayUnits; //Just count them for now, so we can allocate memory before loading them
}
}
if(unit.numberOfDisplayUnits > 0) {
unit.displayUnits = malloc(unit.numberOfDisplayUnits*sizeof(fmi2DisplayUnitHandle));
}
int j=0;
for(ezxml_t unitSubElement = unitElement->child; unitSubElement; unitSubElement = unitSubElement->next) {
if(!strcmp(unitSubElement->name, "DisplayUnit")) {
unit.displayUnits[j].factor = 1;
unit.displayUnits[j].offset = 0;
parseStringAttributeEzXml(unitSubElement, "name", &unit.displayUnits[j].name);
parseFloat64AttributeEzXml(unitSubElement, "factor", &unit.displayUnits[j].factor);
parseFloat64AttributeEzXml(unitSubElement, "offset", &unit.displayUnits[j].offset);
}
++j;
}
fmu->fmi2.units[i] = unit;
++i;
}
}

ezxml_t defaultExperimentElement = ezxml_child(rootElement, "DefaultExperiment");
if(defaultExperimentElement) {
fmu->fmi2.defaultStartTimeDefined = parseFloat64AttributeEzXml(defaultExperimentElement, "startTime", &fmu->fmi2.defaultStartTime);
Expand Down Expand Up @@ -2507,6 +2576,70 @@ fmi2Status fmi2_reset(fmiHandle *fmu)
return fmu->fmi2.reset(fmu->fmi2.component);
}

int fmi2_getNumberOfUnits(fmiHandle *fmu)
{
return fmu->fmi2.numberOfUnits;
}

fmi2UnitHandle *fmi2_getUnitByIndex(fmiHandle *fmu, int i)
{
return &fmu->fmi2.units[i];
}

const char* fmi2_getUnitName(fmi2UnitHandle *unit)
{
return unit->name;
}

bool fmi2_hasBaseUnit(fmi2UnitHandle *unit)
{
return (unit->baseUnit != NULL);
}

void fmi2_getBaseUnit(fmi2UnitHandle *unit, double *factor, double *offset, int *kg, int *m, int *s, int *A, int *K, int *mol, int *cd, int *rad)
{
if(unit->baseUnit != NULL) {
*factor = unit->baseUnit->factor;
*offset = unit->baseUnit->offset;
*kg = unit->baseUnit->kg;
*m= unit->baseUnit->m;
*s= unit->baseUnit->s;
*A= unit->baseUnit->A;
*K= unit->baseUnit->K;
*mol= unit->baseUnit->mol;
*cd= unit->baseUnit->cd;
*rad= unit->baseUnit->rad;
}
}

double fmi2GetBaseUnitFactor(fmi2UnitHandle *unit)
{
if(unit->baseUnit != NULL) {
return unit->baseUnit->factor;
}
return 0;
}

double fmi2GetBaseUnitOffset(fmi2UnitHandle *unit)
{
if(unit->baseUnit != NULL) {
return unit->baseUnit->offset;
}
return 0;
}

int fmi2_getNumberOfDisplayUnits(fmi2UnitHandle *unit)
{
return unit->numberOfDisplayUnits;
}

void fmi2_getDisplayUnitByIndex(fmi2UnitHandle *unit, int id, const char **name, double *factor, double *offset)
{
*name = unit->displayUnits[id].name;
*factor = unit->displayUnits[id].factor;
*offset = unit->displayUnits[id].offset;
}

int fmi3_getNumberOfVariables(fmiHandle *fmu)
{
TRACEFUNC
Expand Down
29 changes: 29 additions & 0 deletions src/fmi4c_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,32 @@ typedef struct {
fmi2ValueReference derivative;
} fmi2VariableHandle;

typedef struct {
int kg;
int m;
int s;
int A;
int K;
int mol;
int cd;
int rad;
double factor;
double offset;
} fmi2BaseUnitHandle;

typedef struct {
const char* name;
double factor;
double offset;
} fmi2DisplayUnitHandle;

typedef struct {
const char* name;
fmi2BaseUnitHandle *baseUnit;
fmi2DisplayUnitHandle *displayUnits;
size_t numberOfDisplayUnits;
} fmi2UnitHandle;

typedef struct {
fmi3DataType datatype;
const char *name;
Expand Down Expand Up @@ -313,6 +339,9 @@ typedef struct {
double defaultTolerance;
double defaultStepSize;

int numberOfUnits;
fmi2UnitHandle *units;

int numberOfContinuousStates;

int numberOfVariables;
Expand Down

0 comments on commit 6ae92c0

Please sign in to comment.