diff --git a/Compiler/BackEnd/BackendDAE.mo b/Compiler/BackEnd/BackendDAE.mo index 399a417e0de..70e639dfd30 100644 --- a/Compiler/BackEnd/BackendDAE.mo +++ b/Compiler/BackEnd/BackendDAE.mo @@ -227,6 +227,9 @@ uniontype VarKind "variable kind" record OPT_INPUT_WITH_DER end OPT_INPUT_WITH_DER; record OPT_INPUT_DER end OPT_INPUT_DER; record OPT_TGRID end OPT_TGRID; + record OPT_LOOP_INPUT + .DAE.ComponentRef replaceExp; + end OPT_LOOP_INPUT; end VarKind; public uniontype TearingSelect diff --git a/Compiler/BackEnd/BackendDump.mo b/Compiler/BackEnd/BackendDump.mo index f6fda18cc25..a08d3b3b333 100644 --- a/Compiler/BackEnd/BackendDump.mo +++ b/Compiler/BackEnd/BackendDump.mo @@ -2302,6 +2302,7 @@ algorithm case BackendDAE.OPT_INPUT_WITH_DER() then "OPT_INPUT_WITH_DER"; case BackendDAE.OPT_INPUT_DER() then "OPT_INPUT_DER"; case BackendDAE.OPT_TGRID() then "OPT_TGRID"; + case BackendDAE.OPT_LOOP_INPUT() then "OPT_LOOP_INPUT"; end match; end kindString; diff --git a/Compiler/BackEnd/BackendVariable.mo b/Compiler/BackEnd/BackendVariable.mo index 49a1739b572..baf4f1e5419 100644 --- a/Compiler/BackEnd/BackendVariable.mo +++ b/Compiler/BackEnd/BackendVariable.mo @@ -862,6 +862,7 @@ algorithm case (BackendDAE.VAR(varKind=BackendDAE.OPT_INPUT_WITH_DER())) then (); case (BackendDAE.VAR(varKind=BackendDAE.OPT_INPUT_DER())) then (); case (BackendDAE.VAR(varKind=BackendDAE.OPT_TGRID())) then (); + case (BackendDAE.VAR(varKind=BackendDAE.OPT_LOOP_INPUT())) then (); end match; end failIfNonState; @@ -973,6 +974,7 @@ algorithm case ((BackendDAE.VAR(varKind=BackendDAE.OPT_INPUT_WITH_DER()) :: _)) then true; case ((BackendDAE.VAR(varKind=BackendDAE.OPT_INPUT_DER()) :: _)) then true; case ((BackendDAE.VAR(varKind=BackendDAE.OPT_TGRID()) :: _)) then true; + case ((BackendDAE.VAR(varKind=BackendDAE.OPT_LOOP_INPUT()) :: _)) then true; case ((_ :: vs)) then hasContinousVar(vs); case ({}) then false; end match; @@ -991,12 +993,21 @@ algorithm /* Real non discrete variable */ case (BackendDAE.VAR(varKind = kind, varType = DAE.T_REAL(_,_))) equation kind_lst = {BackendDAE.VARIABLE(), BackendDAE.DUMMY_DER(), BackendDAE.DUMMY_STATE(), BackendDAE.OPT_INPUT_WITH_DER(), BackendDAE.OPT_INPUT_DER()}; - then listMember(kind, kind_lst); + then listMember(kind, kind_lst) or isOptLoopInput(kind); else false; end match; end isVarNonDiscreteAlg; +protected function isOptLoopInput + input BackendDAE.VarKind kind; + output Boolean b; +algorithm + b := match(kind) case(BackendDAE.OPT_LOOP_INPUT()) then true; + else false; + end match; +end isOptLoopInput; + public function isVarDiscreteAlg input BackendDAE.Var var; output Boolean result; diff --git a/Compiler/BackEnd/DynamicOptimization.mo b/Compiler/BackEnd/DynamicOptimization.mo index 11b620c776c..72d199bcd2a 100644 --- a/Compiler/BackEnd/DynamicOptimization.mo +++ b/Compiler/BackEnd/DynamicOptimization.mo @@ -201,7 +201,7 @@ protected function makeVar "author: Vitalij Ruge" algorithm cr := ComponentReference.makeCrefIdent(name, DAE.T_REAL_DEFAULT, {}); - v := BackendDAE.VAR(cr, BackendDAE.VARIABLE(), DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER()); + v := BackendDAE.VAR(cr, BackendDAE.VARIABLE(), DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), SOME(BackendDAE.AVOID()), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER()); end makeVar; protected function addOptimizationVarsEqns1 @@ -652,13 +652,17 @@ algorithm // new input(resvar) (cr,var) := makeVar("OMC$Input" + intString(ind_v)); var := BackendVariable.setVarDirection(var, DAE.INPUT()); - var := BackendVariable.mergeAliasVars(var, var_, false, knvars); - oshared := BackendVariable.addKnVarDAE(var, oshared); // resvar = new input(resvar) e := Expression.crefExp(cr_var); if BackendVariable.isStateVar(var_) then e := Expression.expDer(e); + var := BackendVariable.setVarKind(var, BackendDAE.OPT_LOOP_INPUT(ComponentReference.crefPrefixDer(cr_var))); + else + // don't merge der(x) with x + var := BackendVariable.mergeAliasVars(var, var_, false, knvars); + var := BackendVariable.setVarKind(var, BackendDAE.OPT_LOOP_INPUT(cr_var)); end if; + oshared := BackendVariable.addKnVarDAE(var, oshared); oeqns := BackendEquation.addEquation(BackendDAE.EQUATION(e, Expression.crefExp(cr), DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN), oeqns); end for; diff --git a/Compiler/SimCode/SerializeModelInfo.mo b/Compiler/SimCode/SerializeModelInfo.mo index dd60448da5e..533aae7f106 100644 --- a/Compiler/SimCode/SerializeModelInfo.mo +++ b/Compiler/SimCode/SerializeModelInfo.mo @@ -766,6 +766,10 @@ algorithm equation File.write(file,"time grid for optimization"); then (); + case BackendDAE.OPT_LOOP_INPUT() + equation + File.write(file,"variable for transform loop in constraint"); + then (); else equation Error.addMessage(Error.INTERNAL_ERROR, {"serializeVarKind failed"}); diff --git a/Compiler/SimCode/SimCodeUtil.mo b/Compiler/SimCode/SimCodeUtil.mo index 0bcce77ec1a..3c3f926e506 100644 --- a/Compiler/SimCode/SimCodeUtil.mo +++ b/Compiler/SimCode/SimCodeUtil.mo @@ -10004,6 +10004,11 @@ algorithm case (BackendDAE.VAR(varKind = BackendDAE.EXTOBJ(_), bindExp = SOME(e))) then SOME(e); + case (BackendDAE.VAR(values = dae_var_attr)) + guard(BackendVariable.isVarNonDiscreteAlg(daelowVar)) + then SOME(DAEUtil.getStartAttrFail(dae_var_attr)); + + else NONE(); end matchcontinue; end getStartValue; diff --git a/Compiler/Template/CodegenC.tpl b/Compiler/Template/CodegenC.tpl index c73aa8f8c1f..4e7386a0ed6 100644 --- a/Compiler/Template/CodegenC.tpl +++ b/Compiler/Template/CodegenC.tpl @@ -518,7 +518,7 @@ template simulationFile_opt_header(SimCode simCode, String guid) int <%symbolName(modelNamePrefixStr,"mayer")%>(DATA* data, modelica_real** res, short*); int <%symbolName(modelNamePrefixStr,"lagrange")%>(DATA* data, modelica_real** res, short *, short *); int <%symbolName(modelNamePrefixStr,"pickUpBoundsForInputsInOptimization")%>(DATA* data, modelica_real* min, modelica_real* max, modelica_real*nominal, modelica_boolean *useNominal, char ** name, modelica_real * start, modelica_real * startTimeOpt); - int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data); + int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data, const modelica_boolean file); int <%symbolName(modelNamePrefixStr,"getTimeGrid")%>(DATA *data, modelica_integer * nsi, modelica_real**t); #if defined(__cplusplus) } @@ -644,7 +644,7 @@ template simulationFile(SimCode simCode, String guid) extern int <%symbolName(modelNamePrefixStr,"mayer")%>(DATA* data, modelica_real** res, short *); extern int <%symbolName(modelNamePrefixStr,"lagrange")%>(DATA* data, modelica_real** res, short *, short *); extern int <%symbolName(modelNamePrefixStr,"pickUpBoundsForInputsInOptimization")%>(DATA* data, modelica_real* min, modelica_real* max, modelica_real*nominal, modelica_boolean *useNominal, char ** name, modelica_real * start, modelica_real * startTimeOpt); - extern int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data); + extern int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data, const modelica_boolean file); extern int <%symbolName(modelNamePrefixStr,"getTimeGrid")%>(DATA *data, modelica_integer * nsi, modelica_real**t); struct OpenModelicaGeneratedFunctionCallbacks <%symbolName(modelNamePrefixStr,"callback")%> = { @@ -10846,7 +10846,7 @@ template optimizationComponents( list classAttributes ,SimC int <%symbolName(modelNamePrefixStr,"mayer")%>(DATA* data, modelica_real** res,short *i){return -1;} int <%symbolName(modelNamePrefixStr,"lagrange")%>(DATA* data, modelica_real** res, short * i1, short*i2){return -1;} int <%symbolName(modelNamePrefixStr,"pickUpBoundsForInputsInOptimization")%>(DATA* data, modelica_real* min, modelica_real* max, modelica_real*nominal, modelica_boolean *useNominal, char ** name, modelica_real * start, modelica_real * startTimeOpt){return -1;} - int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data){return -1;} + int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data, const modelica_boolean file){return -1;} int <%symbolName(modelNamePrefixStr,"getTimeGrid")%>(DATA *data, modelica_integer * nsi, modelica_real**t){return -1;} >> else @@ -10897,6 +10897,12 @@ template optimizationComponents1(ClassAttributes classAttribute, SimCode simCode match modelInfo case MODELINFO(vars=SIMVARS(__)) then << + if(file){ + <%vars.inputVars |> SIMVAR(varKind = OPT_LOOP_INPUT(replaceExp=cr)) hasindex i0 => + '<%cref(name)%> = <%cref(cr)%> ;' + ;separator="\n" + %> + } <%vars.inputVars |> SIMVAR(__) hasindex i0 => 'data->simulationInfo.inputVars[<%i0%>] = <%cref(name)%>;' ;separator="\n" @@ -10954,7 +10960,7 @@ template optimizationComponents1(ClassAttributes classAttribute, SimCode simCode return 0; } - int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data) + int <%symbolName(modelNamePrefixStr,"setInputData")%>(DATA *data, const modelica_boolean file) { TRACE_PUSH <%setInput%> diff --git a/Compiler/Template/SimCodeTV.mo b/Compiler/Template/SimCodeTV.mo index 9bf5c338be5..3a4424fa5ac 100644 --- a/Compiler/Template/SimCodeTV.mo +++ b/Compiler/Template/SimCodeTV.mo @@ -945,6 +945,9 @@ package BackendDAE record OPT_INPUT_WITH_DER end OPT_INPUT_WITH_DER; record OPT_INPUT_DER end OPT_INPUT_DER; record OPT_TGRID end OPT_TGRID; + record OPT_LOOP_INPUT + DAE.ComponentRef replaceExp; + end OPT_LOOP_INPUT; end VarKind; uniontype ZeroCrossing diff --git a/SimulationRuntime/c/openmodelica_func.h b/SimulationRuntime/c/openmodelica_func.h index 37e8631743f..ddd58ce2a11 100644 --- a/SimulationRuntime/c/openmodelica_func.h +++ b/SimulationRuntime/c/openmodelica_func.h @@ -276,7 +276,7 @@ int (*pickUpBoundsForInputsInOptimization)(DATA* data, modelica_real* min, model * and set simulationInfo.inputVars. In case it's not present * a dummy function is added which return -1. */ -int (*setInputData)(DATA* data); +int (*setInputData)(DATA* data, const modelica_boolean file); /* diff --git a/SimulationRuntime/c/optimization/DataManagement/InitialGuess.c b/SimulationRuntime/c/optimization/DataManagement/InitialGuess.c index dd9fdeac9e0..4ff741270d0 100644 --- a/SimulationRuntime/c/optimization/DataManagement/InitialGuess.c +++ b/SimulationRuntime/c/optimization/DataManagement/InitialGuess.c @@ -44,8 +44,8 @@ static int initial_guess_ipopt_cflag(OptData *optData, char* cflags); static inline void smallIntSolverStep(DATA* data, SOLVER_INFO* solverInfo, const double tstop); -static inline void initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o); -static inline void init_ipopt_data(OptData *optData); +static short initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o); +static inline void init_ipopt_data(OptData *optData, const short o); /*! * create initial guess @@ -74,9 +74,9 @@ inline void initial_guess_optimizer(OptData *optData, SOLVER_INFO* solverInfo){ } if(opt > 0) - initial_guess_ipopt_sim(optData, solverInfo, opt); + opt = initial_guess_ipopt_sim(optData, solverInfo, opt); - init_ipopt_data(optData); + init_ipopt_data(optData, opt); } @@ -84,7 +84,7 @@ inline void initial_guess_optimizer(OptData *optData, SOLVER_INFO* solverInfo){ * create initial guess dasslColorSymJac * author: Vitalij Ruge **/ -static inline void initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o) +static short initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solverInfo, const short o) { double *u0; int i,j,k,l; @@ -227,6 +227,7 @@ static inline void initial_guess_ipopt_sim(OptData *optData, SOLVER_INFO* solver data->simulationInfo.tolerance = tol; externalInputFree(data); + return op; } @@ -272,7 +273,7 @@ static int initial_guess_ipopt_cflag(OptData *optData, char* cflags) * init ipopt data struct * author: Vitalij Ruge **/ -static inline void init_ipopt_data(OptData *optData){ +static inline void init_ipopt_data(OptData *optData, const short op){ OptDataIpopt* ipop = &optData->ipop; DATA * data = optData->data; const int NV = optData->dim.NV; @@ -301,7 +302,7 @@ static inline void init_ipopt_data(OptData *optData){ for(i = 0, shift = 0; i < nsi; ++i){ for(j = 0; j < np; ++j, shift+=nv){ memcpy(data->localData[0]->realVars, optData->v[i][j], nReal*sizeof(double)); - optData->data->callback->setInputData(optData->data); + optData->data->callback->setInputData(optData->data, op == 2); for(l = 0; lvopt[l + shift] = optData->v[i][j][l]*optData->bounds.scalF[l]; }