Skip to content

Commit

Permalink
Add dependencies to FMIUnknown (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
t-sommer committed Sep 19, 2024
1 parent 78ada8b commit 9904675
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 9 deletions.
104 changes: 95 additions & 9 deletions fmusim/FMIModelDescription.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,19 +266,54 @@ static FMIStatus readUnknownsFMI2(xmlXPathContextPtr xpathCtx, FMIModelDescripti

for (size_t i = 0; i < xpathObj->nodesetval->nodeNr; i++) {

xmlNodePtr unkownNode = xpathObj->nodesetval->nodeTab[i];
xmlNodePtr unknownNode = xpathObj->nodesetval->nodeTab[i];

FMIUnknown* unknown;

CALL(FMICalloc((void**)&unknown, 1, sizeof(FMIUnknown)));

(*unknowns)[i] = unknown;

const char* indexLiteral = (char*)xmlGetProp(unkownNode, (xmlChar*)"index");
const char* indexLiteral = (char*)xmlGetProp(unknownNode, (xmlChar*)"index");

unknown->modelVariable = FMIModelVariableForIndexLiteral(modelDescription, indexLiteral);

if (!unknown->modelVariable) {
FMILogError("Illegal variable index %s for unkonwn (line %hu).\n", indexLiteral, unknownNode->line);
xmlFree((void*)indexLiteral);
status = FMIError;
goto TERMINATE;
}

xmlFree((void*)indexLiteral);

const char* dependenciesLiteral = (char*)xmlGetProp(unknownNode, (xmlChar*)"dependencies");

if (dependenciesLiteral) {

unsigned int* dependencyIndices;

CALL(FMIParseValues(FMIMajorVersion2, FMIUInt32Type, dependenciesLiteral, &unknown->nDependencies, &dependencyIndices));

CALL(FMICalloc(&unknown->dependencies, unknown->nDependencies, sizeof(FMIModelVariable*)));

for (size_t j = 0; j < unknown->nDependencies; j++) {

const unsigned int index = dependencyIndices[j];

if (index < 1 || index > modelDescription->nModelVariables) {
FMILogError("Dependency %zu of unknown (line %hu) has illegal index %u.\n", j + 1, unknownNode->line, index);
status = FMIError;
goto TERMINATE;
}

unknown->dependencies[j] = modelDescription->modelVariables[index - 1];
}

FMIFree((void**)&dependencyIndices);

xmlFree((void*)dependenciesLiteral);
}
}

xmlXPathFreeObject(xpathObj);
Expand Down Expand Up @@ -308,16 +343,42 @@ static FMIStatus readUnknownsFMI3(xmlXPathContextPtr xpathCtx, FMIModelDescripti

(*unknowns)[i] = unknown;

FMIValueReference valueReference = getUInt32Attribute(unknownNode, "valueReference");
const FMIValueReference valueReference = getUInt32Attribute(unknownNode, "valueReference");

for (size_t j = 0; j < modelDescription->nModelVariables; j++) {
unknown->modelVariable = FMIModelVariableForValueReference(modelDescription, valueReference);

FMIModelVariable* variable = modelDescription->modelVariables[j];

if (variable->valueReference == valueReference) {
unknown->modelVariable = variable;
break;
if (!unknown->modelVariable) {
FMILogError("Illegal value reference %u for unknown (line %hu).\n", valueReference, unknownNode->line);
status = FMIError;
goto TERMINATE;
}

const char* dependenciesLiteral = (char*)xmlGetProp(unknownNode, (xmlChar*)"dependencies");

if (dependenciesLiteral) {

unsigned int* dependencyValueReferences;

CALL(FMIParseValues(FMIMajorVersion3, FMIUInt32Type, dependenciesLiteral, &unknown->nDependencies, &dependencyValueReferences));

CALL(FMICalloc(&unknown->dependencies, unknown->nDependencies, sizeof(FMIModelVariable*)));

for (size_t j = 0; j < unknown->nDependencies; j++) {

const FMIValueReference valueReference = dependencyValueReferences[j];

unknown->dependencies[j] = FMIModelVariableForValueReference(modelDescription, valueReference);

if (!unknown->dependencies[j]) {
FMILogError("Illegal value reference %zu for dependency %zu of unkonwn (line %hu).\n", valueReference, j + 1, unknownNode->line);
status = FMIError;
goto TERMINATE;
}
}

FMIFree((void**)&dependencyValueReferences);

xmlFree((void*)dependenciesLiteral);
}
}

Expand Down Expand Up @@ -1215,6 +1276,25 @@ FMIModelDescription* FMIReadModelDescription(const char* filename) {
return modelDescription;
}

static void freeUnknowns(FMIUnknown* unknowns[], size_t nUnknowns) {

if (!unknowns) {
return;
}

for (size_t i = 0; i < nUnknowns; i++) {

FMIUnknown* unknown = unknowns[i];

if (unknown) {
FMIFree((void**)&unknown->dependencies);
FMIFree((void**)&unknown);
}
}

FMIFree((void**)&unknowns);
}

void FMIFreeModelDescription(FMIModelDescription* modelDescription) {

if (!modelDescription) {
Expand Down Expand Up @@ -1311,6 +1391,12 @@ void FMIFreeModelDescription(FMIModelDescription* modelDescription) {
}
}

// unknowns
freeUnknowns(modelDescription->outputs, modelDescription->nOutputs);
freeUnknowns(modelDescription->derivatives, modelDescription->nContinuousStates);
freeUnknowns(modelDescription->initialUnknowns, modelDescription->nInitialUnknowns);
freeUnknowns(modelDescription->eventIndicators, modelDescription->nEventIndicators);

FMIFree((void**)&modelDescription->modelVariables);

FMIFree((void**)&modelDescription);
Expand Down
2 changes: 2 additions & 0 deletions fmusim/FMIModelDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ typedef struct {
typedef struct {

FMIModelVariable* modelVariable;
size_t nDependencies;
FMIModelVariable** dependencies;

} FMIUnknown;

Expand Down

0 comments on commit 9904675

Please sign in to comment.