Skip to content

Commit

Permalink
fix code generation of python file for linearization (#8751)
Browse files Browse the repository at this point in the history
  • Loading branch information
arun3688 committed Mar 23, 2022
1 parent cf1bf43 commit 809ed28
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 42 deletions.
37 changes: 26 additions & 11 deletions OMCompiler/Compiler/Template/CodegenC.tpl
Expand Up @@ -5045,19 +5045,19 @@ template functionlinearmodelPython(ModelInfo modelInfo, String modelNamePrefix)
::=
match modelInfo
case MODELINFO(varInfo=VARINFO(__), vars=SIMVARS(__)) then
let matrixA = genMatrixMatlab("A", "n", "n", varInfo.numStateVars, varInfo.numStateVars)
let matrixB = genMatrixMatlab("B", "n", "m", varInfo.numStateVars, varInfo.numInVars)
let matrixC = genMatrixMatlab("C", "p", "n", varInfo.numOutVars, varInfo.numStateVars)
let matrixD = genMatrixMatlab("D", "p", "m", varInfo.numOutVars, varInfo.numInVars)
let matrixCz = genMatrixMatlab("Cz", "nz", "n", varInfo.numAlgVars, varInfo.numStateVars)
let matrixDz = genMatrixMatlab("Dz", "nz", "m", varInfo.numAlgVars, varInfo.numInVars)
let matrixA = genMatrixPython("A", "n", "n", varInfo.numStateVars, varInfo.numStateVars)
let matrixB = genMatrixPython("B", "n", "m", varInfo.numStateVars, varInfo.numInVars)
let matrixC = genMatrixPython("C", "p", "n", varInfo.numOutVars, varInfo.numStateVars)
let matrixD = genMatrixPython("D", "p", "m", varInfo.numOutVars, varInfo.numInVars)
let matrixCz = genMatrixPython("Cz", "nz", "n", varInfo.numAlgVars, varInfo.numStateVars)
let matrixDz = genMatrixPython("Dz", "nz", "m", varInfo.numAlgVars, varInfo.numInVars)
//string def_proctedpart("\n Real x[<%varInfo.numStateVars%>](start=x0);\n Real u[<%varInfo.numInVars%>](start=u0);\n output Real y[<%varInfo.numOutVars%>];\n");
<<
const char *<%symbolName(modelNamePrefix,"linear_model_frame")%>()
{
return "def linearized_model()\n"
"# <%modelNamePrefix%>\n"
"# der(x) = A * x + B * u \n# y = C * x + D * u \n"
return "def linearized_model():\n"
" # <%modelNamePrefix%>\n"
" # der(x) = A * x + B * u \n # y = C * x + D * u \n"
" n = <%varInfo.numStateVars%> # number of states\n m = <%varInfo.numInVars%> # number of inputs\n p = <%varInfo.numOutVars%> # number of outputs\n"
"\n"
" x0 = %s\n"
Expand All @@ -5071,8 +5071,7 @@ template functionlinearmodelPython(ModelInfo modelInfo, String modelNamePrefix)
<%getVarNameJulia(vars.inputVars, "u")%>
<%getVarNameJulia(vars.outputVars, "y")%>
"\n"
" return (n, m, p, x0, u0, A, B, C, D)\n"
"end";
" return (n, m, p, x0, u0, A, B, C, D)\n";
}
const char *<%symbolName(modelNamePrefix,"linear_model_datarecovery_frame")%>()
{
Expand Down Expand Up @@ -5146,6 +5145,22 @@ template genMatrixMatlab(String name, String row, String col, Integer rowI, Inte
end match
end genMatrixMatlab;

template genMatrixPython(String name, String row, String col, Integer rowI, Integer colI) "template genMatrixPython
Generates Matrix for linear model in python code"
::=
match rowI
case 0 then
<<" <%name%> = %s\n\n">>
case _ then
match colI
case 0 then
<<" <%name%> = %s\n\n">>
case _ then
<<" <%name%> = %s\n\n">>
end match
end match
end genMatrixPython;

template genMatrixJulia(String name, String row, String col, Integer rowI, Integer colI) "template genMatrixJulia
Generates Matrix for linear model in Julia code"
::=
Expand Down
101 changes: 83 additions & 18 deletions OMCompiler/SimulationRuntime/c/linearization/linearize.cpp
Expand Up @@ -68,6 +68,42 @@ static string array2string(double* array, int row, int col)
return retVal.str();
}

static string array2PythonString(double* array, int row, int col)
{
int i=0;
int j=0;
ostringstream retVal(ostringstream::out);
if (row == 0 || col == 0)
{
retVal << "[]\n";
return retVal.str();
}

retVal.precision(16);
retVal << "[";
for(i=0; i<row; i++)
{
int k = i;
retVal << "[";
for(j=0; j<col-1; j++)
{
retVal << array[k] << ", ";
k += row;
}
if(col > 0)
{
retVal << array[k];
}
if((i+1 != row) && (col != 0))
{
retVal << "],\n\t";
}
}
retVal << "]]\n";

return retVal.str();
}

extern "C" {

int functionODE_residual(DATA* data, threadData_t *threadData, double *dx, double *dy, double *dz)
Expand Down Expand Up @@ -552,28 +588,57 @@ int linearize(DATA* data, threadData_t *threadData)
assertStreamPrint(threadData,0==functionJacD(data, threadData, matrixD),"Error, can not get Matrix D ");
}
}
if (data->modelData->linearizationDumpLanguage != 3)
{

strA = array2string(matrixA,size_A,size_A);
strB = array2string(matrixB,size_A,size_Inputs);
strC = array2string(matrixC,size_Outputs,size_A);
strD = array2string(matrixD,size_Outputs,size_Inputs);
if(do_data_recovery > 0){
strCz = array2string(matrixCz,size_z,size_A);
strDz = array2string(matrixDz,size_z,size_Inputs);
}
strA = array2string(matrixA, size_A, size_A);
strB = array2string(matrixB, size_A, size_Inputs);
strC = array2string(matrixC, size_Outputs, size_A);
strD = array2string(matrixD, size_Outputs, size_Inputs);
if (do_data_recovery > 0)
{
strCz = array2string(matrixCz, size_z, size_A);
strDz = array2string(matrixDz, size_z, size_Inputs);
}

// The empty array {} is not valid modelica, so we need to put something
// inside the curly braces for x0 and u0. {for i in in 1:0} will create an
// empty array if needed.
if(size_A)
strX = "{" + array2string(data->localData[0]->realVars, 1, size_A) + "}";
else
strX = "zeros(0)";
// The empty array {} is not valid modelica, so we need to put something
// inside the curly braces for x0 and u0. {for i in in 1:0} will create an
// empty array if needed.
if (size_A)
strX = "{" + array2string(data->localData[0]->realVars, 1, size_A) + "}";
else
strX = "zeros(0)";

if(size_Inputs)
strU = "{" + array2string(data->simulationInfo->inputVars, 1, size_Inputs) + "}";
if (size_Inputs)
strU = "{" + array2string(data->simulationInfo->inputVars, 1, size_Inputs) + "}";
else
strU = "zeros(0)";
}
else
strU = "zeros(0)";
{
// convert the matrices to Python format
//infoStreamPrint(LOG_STDOUT, 0, "Python selected");
strA = array2PythonString(matrixA, size_A, size_A);
strB = array2PythonString(matrixB, size_A, size_Inputs);
strC = array2PythonString(matrixC, size_Outputs, size_A);
strD = array2PythonString(matrixD, size_Outputs, size_Inputs);
if (do_data_recovery > 0)
{
strCz = array2PythonString(matrixCz, size_z, size_A);
strDz = array2PythonString(matrixDz, size_z, size_Inputs);
}
// strA = "[[-2.887152375617477, -1.62655852935388], [-2.380918056675567, -2.388394731625707]]";
//infoStreamPrint(LOG_STDOUT, 0, strA.c_str());
if (size_A)
strX = "[" + array2string(data->localData[0]->realVars, 1, size_A) + "]";
else
strX = "[0]";

if (size_Inputs)
strU = "[" + array2string(data->simulationInfo->inputVars, 1, size_Inputs) + "]";
else
strU = "[0]";
}

free(matrixA);
free(matrixB);
Expand Down
30 changes: 17 additions & 13 deletions testsuite/openmodelica/linearization/test_dump_languages.mos
Expand Up @@ -168,33 +168,37 @@ readFile("linearized_model.py"); getErrorString();
// end SimulationResult;
// "Warning: The initial conditions are not fully specified. For more information set -d=initialization. In OMEdit Tools->Options->Simulation->Show additional information from the initialization process, in OMNotebook call setCommandLineOptions(\"-d=initialization\").
// "
// "def linearized_model()
// # simple_test
// # der(x) = A * x + B * u
// # y = C * x + D * u
// "def linearized_model():
// # simple_test
// # der(x) = A * x + B * u
// # y = C * x + D * u
// n = 2 # number of states
// m = 1 # number of inputs
// p = 1 # number of outputs
//
// x0 = {1.626558527192664, 2.380918053900121}
// u0 = {0}
// x0 = [1.626558527192664, 2.380918053900121]
// u0 = [0]
//
// A = [-2.887152375617477, -1.62655852935388;
// -2.380918056675567, -2.388394731625707];
// A = [[-2.887152375617477, -1.62655852935388],
// [-2.380918056675567, -2.388394731625707]]
//
// B = [0;
// 0];
//
// C = [0, 0];
// B = [[0],
// [0]]
//
//
// C = [[0, 0]]
//
//
// D = [[4.007476581092785]]
//
// D = [4.007476581092785];
//
// # x_num_x(1) = x(1);
// # x_num_x(2) = x(2);
// # u_u = u(1);
// # y_y = y(1);
//
// return (n, m, p, x0, u0, A, B, C, D)
// end"
// "
// ""
// endResult

0 comments on commit 809ed28

Please sign in to comment.