#3503 closed defect (fixed)
Support for Modelica_Synchronous
Reported by: | Rüdiger Franke | Owned by: | Rüdiger Franke |
---|---|---|---|
Priority: | high | Milestone: | |
Component: | Backend | Version: | |
Keywords: | Cc: | Bernhard Thiele, Lennart Ochel, Maksimov Doe |
Description
Meanwhile some clocked features are working (or have been re-activated). But still any model of Modelica_Synchronous
fails (besides the reference Examples.SimpleControlledDrive.Continuous
).
Can it be that OpenModelica switches off synchronous features if Modelica_Synchronous
is loaded?
Shouldn't Modelica_Synchronous be added to the nightly tests?
See:
Change History (46)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
The problem is related to composed models. The following example works:
model ClockedSource parameter Real dt = 0.1; Real u = 1; Modelica.Blocks.Interfaces.RealOutput ud; equation ud = sample(time*u, Clock(dt)); end ClockedSource;
Invoke:
$ omc +std=3.3 ClockedSource.mo Modelica
The following composed model fails:
model ClockedModel ClockedSource cs; end ClockedModel;
Invoke:
$ omc +std=3.3 ClockedModel.mo ClockedSource.mo Modelica
to get:
Error processing file: ClockedModel.mo [ClockedSource.mo:6:3-6:33:writable] Error: Failed to instantiate equation ud = sample(time * u, Clock(dt));. Error: Error occurred while flattening model ClockedModel
The same or a similar error shows up for each example from Modelica_Synchronous.
comment:3 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → accepted |
comment:4 by , 9 years ago
Cc: | added |
---|
It seems that Bernhard forgot to add prefixing for Clock expressions.
-PrefixUtil.prefixExp failed on exp: Clock(dt) -PrefixUtil.prefixExp failed on exp: sample(time * u, Clock(dt)) - InstSection.instEquationCommonWork failed for eqn: ud = sample(time * u, Clock(dt)); in scope: ClockedSource
I added the prefixing now and I'll test it a bit before commit.
comment:5 by , 9 years ago
Prefixing is now fixed in c5ce437f2bca9d2ae01dfe3da731770de6fefdd2/OMCompiler.
adrpo@ida-liu050 /f/dev/testing $ ../OpenModelica/build/bin/omc +std=3.3 ClockedModel.mo ClockedSource.mo Modelica Notification: Laddade paket Complex 3.2.1 med automatik tack vare en uses-annotation. Notification: Laddade paket ModelicaServices 3.2.1 med automatik tack vare en uses-annotation. class ClockedModel parameter Real cs.dt = 0.1; Real cs.u = 1.0; Real cs.ud; equation cs.ud = sample(time * cs.u, Clock(cs.dt)); end ClockedModel;
comment:6 by , 9 years ago
Added the given test for this bug in 4b8cd775272ac0d66dbaec08209347c6c4069ba0/testsuite.
I'll add testing of Modelica_Synchronous in Hudson later today.
comment:7 by , 9 years ago
I now added Modelica_Synchronous in Hudson.
@rfranke: I guess you want also Modelica_Synchronous_cpp added to test the C++ runtime. Let me know.
comment:8 by , 9 years ago
We have the first results:
https://test.openmodelica.org/libraries/Modelica_Synchronous/BuildModelRecursive.html
https://test.openmodelica.org/libraries/Modelica_Synchronous_cpp/BuildModelRecursive.html
Most models fail with:
Error: Wrong type or wrong number of arguments to superSample(Clock(factor), resolutionFactor).
So I guess we don't check the superSample function properly. I'll look into it.
comment:9 by , 9 years ago
Besides issues with sub/superSample, there is also a problem with clocks in connectors that are used by about any model. Modelica_Synchronous.Examples.SimpleControlledDrive
provides an illustrative example for different synchronous features, starting from the reference model Continuous
.
ClockedWithDiscreteTextbookController
adds a basic real clock. This leads to:
Error: Illegal connection: component periodicClock.y is not a connector.
comment:10 by , 9 years ago
@rfanke: yes, I know as I already fixed the superSample and I'm about to fix the connector issues. I'll let you know how it goes.
comment:11 by , 9 years ago
Fixed subSample/superSample argument checking and allowance to use Clock as connector in ae1a72c/OMCompiler.
I'll restart the library checking for Modelica_Synchronous to see where we're at after Hudson finishes checking my commit.
comment:12 by , 9 years ago
Cc: | added |
---|
10 Models work now (previously only 3):
https://test.openmodelica.org/libraries/Modelica_Synchronous/BuildModelRecursive.html
https://test.openmodelica.org/libraries/Modelica_Synchronous_cpp/BuildModelRecursive.html
As far as I can tell the problems are in the back-end / code generation now, example errors:
- Error: Partition have different sub-clocks.
- Error: pre-optimization module clockPartitioning failed.
- Internal error -- Function SynchronousFeatures.detectEqPatitionCall1 failed
There are still some issues with the front-end (shiftSample argument handling) which I will fix.
follow-up: 16 comment:14 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | accepted → assigned |
I now fixed the remaining front-end things in 9365264/OMCompiler.
Should we open another ticket for the back-end things?
follow-ups: 17 18 comment:15 by , 9 years ago
As far as I can tell the back-end can only handle component references in functions hold, sample, subSample, superSample, shiftSample, backSample, noClock
. If any of these get a Clock(...)
instead the back-end will fail. The call chain goes like this:
detectEqPartition detectEqPartitionExp detectEqPartitionExp1 detectEqPartitionCall detectEqPartitionCall1
and in detectEqPartitionCall1 the expected expression is a DAE.CREF.
This can be fixed in two ways:
- if we substitute all the
Clock(...)
expressions with new generated variables - if we handle expressions in these operators instead of component references
What do you think?
comment:16 by , 9 years ago
Replying to adrpo:
Should we open another ticket for the back-end things?
You can do so and put me on the new ticket or we can just use this one ;-)
comment:17 by , 9 years ago
Replying to adrpo:
This can be fixed in two ways:
- if we substitute all the
Clock(...)
expressions with new generated variables- if we handle expressions in these operators instead of component references
What do you think?
I will have a closer look, since I am not sure yet what is better.
comment:18 by , 9 years ago
Replying to adrpo:
As far as I can tell the back-end can only handle component references in functions
hold, sample, subSample, superSample, shiftSample, backSample, noClock
. If any of these get aClock(...)
instead the back-end will fail. The call chain goes like this:
detectEqPartition detectEqPartitionExp detectEqPartitionExp1 detectEqPartitionCall detectEqPartitionCall1and in detectEqPartitionCall1 the expected expression is a DAE.CREF.
This can be fixed in two ways:
- if we substitute all the
Clock(...)
expressions with new generated variables- if we handle expressions in these operators instead of component references
What do you think?
This is correct behaviour because all non-trivial arguments of clocked operators are should be substituted before in function substituteParitionOpExps.
So it is function substituteParitionOpExps that should be fixed.
comment:19 by , 9 years ago
@gossen, thanks for the pointer.
I now fixed some minor typos in 213ddae/OMCompiler and 3e6f284/OMCompiler.
follow-up: 21 comment:20 by , 9 years ago
By the way, what function should be uses to get a value for expression?
comment:21 by , 9 years ago
Replying to gossen:
By the way, what function should be uses to get a value for expression?
You can use Ceval.ceval to evaluate a DAE.Exp, see for example EvaluateParameter.mo.
Why do you need it? Sometimes is good not to evaluate things as then you cannot change them without recompiling in a re-simulation (via -override).
comment:22 by , 9 years ago
Clock constructors contain parameter arguments which should be known in clock partitioning phase.
Currently in function SynchronousFeatures.getSubClock we get these parameters using DAE.ICONST pattern.
comment:23 by , 9 years ago
I played with the clock exp substitution with variables in c7257cc/OMCompiler. Might be good that somebody that knows the code better to check my fix as I'm not sure about it, but more models in Modelica_Synchronous are working now: 25/95 in the C runtime 28/95 in the CPP runtime.
@lochel, let's continue using this ticket as it seems OK, I assigned you to it now.
comment:24 by , 9 years ago
Component: | Frontend → Backend |
---|
comment:25 by , 9 years ago
First of all I'm happy that basic periodic and inferred clocks are working now!
I'm neither in the details of clock arithmetics (sub/super/shiftSample). Where should this be treated: in the backend or in the runtime? Or some shared treatment, e.g. the backend breaks it down to basic sample times and offsets?
follow-up: 27 comment:26 by , 9 years ago
Support for embedded continuous equations + solver would be great. See e.g.
Modelica_Synchronous.Examples.System.ControlledMixingUnit
So far the example fails already with Clock instantiation:
[Modelica_Synchronous.ClockSignals: 15:10-15:61]: Wrong type or wrong number of arguments to Clock(Clock(period)). (in component periodicClock).
follow-up: 28 comment:27 by , 9 years ago
Replying to rfranke:
Support for embedded continuous equations + solver would be great. See e.g.
Modelica_Synchronous.Examples.System.ControlledMixingUnit
So far the example fails already with Clock instantiation:
[Modelica_Synchronous.ClockSignals: 15:10-15:61]: Wrong type or wrong number of arguments to Clock(Clock(period)). (in component periodicClock).
This sounds like a front-end issue. I'll have a look.
follow-up: 29 comment:28 by , 9 years ago
Replying to adrpo:
This sounds like a front-end issue. I'll have a look.
The example needs clocked discretized continuous-time partition support. This is a rather advanced feature within the synchronous language element extension. I omitted it, since I wanted first to support the basic features.
follow-ups: 30 34 comment:29 by , 9 years ago
Replying to bthiele:
Replying to adrpo:
This sounds like a front-end issue. I'll have a look.
The example needs clocked discretized continuous-time partition support. This is a rather advanced feature within the synchronous language element extension. I omitted it, since I wanted first to support the basic features.
This is true, but at least we should properly support it in the front-end.
As far as I read the Modelica Specification 3.3 section 16.3 Clock Constructors
the Clock(Clock(period))
is not permitted. However, looking into the code we have:
y = Clock(Clock(period), solverMethod=solverMethod);
so it seems we're not handling the name argument solverMethod
properly.
I now have a fix for it but there is a problem with the way DAE.SOLVER_CLOCK
is defined:
record SOLVER_CLOCK Exp c; String solverMethod; end SOLVER_CLOCK;
The problem is that solverMethod in this case is a parameter. We could evaluate it but I guess the idea is to be able to change the solverMethod without recompilation and for that we need to keep it as a parameter all the way to code. So we need to change DAE.SOLVER_CLOCK to:
record SOLVER_CLOCK Exp c; Exp solverMethod; end SOLVER_CLOCK;
and I assume all the other ClockKind records needs the same treatment.
So the question is: is it desirable to be able to change Clock parameters without recompilation? If so I'll start changing the compiler to handle the parameters in Clock better.
follow-up: 32 comment:30 by , 9 years ago
Replying to adrpo:
Replying to bthiele:
Replying to adrpo:
This sounds like a front-end issue. I'll have a look.
The example needs clocked discretized continuous-time partition support. This is a rather advanced feature within the synchronous language element extension. I omitted it, since I wanted first to support the basic features.
This is true, but at least we should properly support it in the front-end.
As far as I read the Modelica Specification 3.3 section 16.3 Clock Constructors
theClock(Clock(period))
is not permitted. However, looking into the code we have:
y = Clock(Clock(period), solverMethod=solverMethod);so it seems we're not handling the name argument
solverMethod
properly.
I now have a fix for it but there is a problem with the wayDAE.SOLVER_CLOCK
is defined:
record SOLVER_CLOCK Exp c; String solverMethod; end SOLVER_CLOCK;The problem is that solverMethod in this case is a parameter. We could evaluate it but I guess the idea is to be able to change the solverMethod without recompilation and for that we need to keep it as a parameter all the way to code. So we need to change DAE.SOLVER_CLOCK to:
record SOLVER_CLOCK Exp c; Exp solverMethod; end SOLVER_CLOCK;and I assume all the other ClockKind records needs the same treatment.
So the question is: is it desirable to be able to change Clock parameters without recompilation? If so I'll start changing the compiler to handle the parameters in Clock better.
Than we need a rational expressions that would be used in BackendDAE.SUBCLOCK for shift and factor parameters instead of rational constants.
comment:31 by , 9 years ago
I tried to fix the floating point exceptions that occur in certain models with the c runtime.
follow-up: 33 comment:32 by , 9 years ago
Replying to gossen:
Replying to adrpo:
I now have a fix for it but there is a problem with the way
DAE.SOLVER_CLOCK
is defined:
record SOLVER_CLOCK Exp c; String solverMethod; end SOLVER_CLOCK;The problem is that solverMethod in this case is a parameter. We could evaluate it but I guess the idea is to be able to change the solverMethod without recompilation and for that we need to keep it as a parameter all the way to code. So we need to change DAE.SOLVER_CLOCK to:
record SOLVER_CLOCK Exp c; Exp solverMethod; end SOLVER_CLOCK;and I assume all the other ClockKind records needs the same treatment.
So the question is: is it desirable to be able to change Clock parameters without recompilation? If so I'll start changing the compiler to handle the parameters in Clock better.
One needs to make some trade-offs. Of course it is convenient to have it as a parameter, however that requires to generate more generic code. My opinion is that one can do without having it as a parameter that can be changed without recompilation and rather one should at least keep the option to generate specialized code, e.g., using inline integration techniques.
There is another issue. Depending on the solver there will be different data-flow constraints. If "ExplicitEuler" is used, the integration only needs the previous value of an input in order to to the integration. The other methods need the "current" value. Hence, scheduling/sorting of the equations within a model that includes a clocked discretized continuous-time partition depends on the chosen solver. That makes it at least very cumbersome to support parameters that can be changed without recompilation. I would not do it.
Than we need a rational expressions that would be used in BackendDAE.SUBCLOCK for shift and factor parameters instead of rational constants.
Also for other parameters we should think on the trade-offs to support changing them without recompilation. It might complicate things a lot and it is better to be more restrictive rather than supporting features that may be error prone to implement and might result in less efficient execution.
comment:33 by , 9 years ago
Replying to bthiele:
Replying to gossen:
Than we need a rational expressions that would be used in BackendDAE.SUBCLOCK for shift and factor parameters instead of rational constants.
Also for other parameters we should think on the trade-offs to support changing them without recompilation. It might complicate things a lot and it is better to be more restrictive rather than supporting features that may be error prone to implement and might result in less efficient execution.
Well, we already have rational number support in simulation runtime. So subclock's shift and factor parameters can be calculated at compile time as well as at simulation initialization.
comment:34 by , 9 years ago
Replying to adrpo:
So the question is: is it desirable to be able to change Clock parameters without recompilation? If so I'll start changing the compiler to handle the parameters in Clock better.
Clock parameters are structural to some extent.
As bthiele outlines, a different solver method leads to different equation systems. The equations can possibly be better optimized if known at compile time, i.e. if the solver method is known. For intance the system solved by an implicit solver might fall apart if known analytically.
This is why I wouldn't consider it overly important to be able to change Clock parameters without recompilation -- it appears more interesting to see code optimizations thanks to inline integration.
comment:35 by , 9 years ago
Ok. I get the picture.
What I propose is that the front-end doesn't restrict this directly as it is now.
I think we should do the evaluation in the back-end during compilation, that's fine.
At least this way we can change it later if we want to support Clock parameters without recompilation with no need to touch the front-end.
comment:36 by , 9 years ago
I just tried to simulate some of the models that should be working in OMEdit. If executed in OMEdit I get strange errors like (Modelica_Synchronous.IntegerSignals.Sampler.SubSample):
stdout | error | <p>Got number 14.000000, expected: 12.000000<br>
I don't understand why, maybe some default simulation settings in OMEdit are different, but the error message is mysterious to me.
comment:37 by , 9 years ago
This message only shows up with the C runtime -- in an exported FMU as well. You should grep or debug the runtime code.
comment:38 by , 9 years ago
Let's re-activate the ticket. The current OMEdit says "Process crashed" after having issued the error message given in #comment:36 for the C runtime. What is different in the nightly tests, where simulation succeeds for some models?
Moreover, it is really bad that OpenModelica seems to ignore annotation(Evaluate=true). In particular subsample and shift factors disappear during model translation -- because they are stored in rational numbers, but OpenModelica does not evaluate the parameters and leaves the rational numbers with their default values. See e.g.
Modelica_Synchronous.Examples.SimpleControlledDrive.ExactlyClockedWithDiscreteController
The nightly tests report success for this model; but nothing happens during the simulation. Compare load.w with the other SimpleControlledDrive examples.
Last but not least the translation still fails for clocks with solverMethod. See e.g.:
Modelica_Synchronous.Examples.SimpleControlledDrive.ClockedWithDiscretizedContinuousController
If the fronend accepted the model, then someone who knows the backend should be able to replace der(x) with clocked variables and add some simple integration methods like Euler to start with.
The high-end solverMethod implementation would solve the clocked partition to ODE form before adding a solver, e.g. for model inversion. See e.g.:
Modelica_Synchronous.Examples.Systems.ControlledMixingUnit
comment:39 by , 9 years ago
With changes in PR478 we can now flatten Modelica_Synchronous.Examples.Systems.ControlledMixingUnit and I guess other also.
class Modelica_Synchronous.Examples.Systems.ControlledMixingUnit "Simple example of a mixing unit where a (discretized) nonlinear inverse plant model is used as feedforward controller" parameter Real freq(quantity = "Frequency", unit = "Hz") = 0.003333333333333334 "Critical frequency of filter"; parameter Real c0(unit = "mol/l") = 0.848 "Nominal concentration"; parameter Real T0(quantity = "ThermodynamicTemperature", unit = "K", displayUnit = "degC", min = 0.0, start = 288.15, nominal = 300.0) = 308.5 "Nominal temperature"; parameter Real a1_inv = 0.2674; parameter Real a21_inv = 1.815; parameter Real a22_inv = 0.4682; parameter Real b_inv = 1.5476; parameter Real k0_inv = 105000000000000.0; parameter Real eps = 34.2894; parameter Real x10 = 0.42; parameter Real x10_inv = 0.6; parameter Real x20 = 0.01; parameter Real u0 = -0.0224; final parameter Real c_start(unit = "mol/l") = c0 * (1.0 - x10); final parameter Real c_inv_start(unit = "mol/l") = c0 * (1.0 - x10_inv); final parameter Real T_start(quantity = "ThermodynamicTemperature", unit = "K", displayUnit = "degC", min = 0.0, start = 288.15, nominal = 300.0) = T0 * (1.0 + x20); final parameter Real c_high_start(unit = "mol/l") = 0.28 * c0; final parameter Real T_c_start = T0 * (1.0 + u0); parameter Real pro = 1.5 "Deviations of plant to inverse plant parameters"; final parameter Real a1 = a1_inv * pro; final parameter Real a21 = a21_inv * pro; final parameter Real a22 = a22_inv * pro; final parameter Real b = b_inv * pro; final parameter Real k0 = k0_inv * pro; Real invMixingUnit.T_c(unit = "K", start = T_c_start, fixed = true) "Cooling temperature"; Real invMixingUnit.c(unit = "mol/l", start = c_start, fixed = true) "Concentration"; Real invMixingUnit.T(unit = "K", start = T_start, fixed = true, stateSelect = StateSelect.always) "Temperature in mixing unit"; parameter Real invMixingUnit.c0(unit = "mol/l") = c0 "Nominal concentration"; parameter Real invMixingUnit.T0(quantity = "ThermodynamicTemperature", unit = "K", displayUnit = "degC", min = 0.0, start = 288.15, nominal = 300.0) = T0 "Nominal temperature"; parameter Real invMixingUnit.a1 = a1_inv; parameter Real invMixingUnit.a21 = a21_inv; parameter Real invMixingUnit.a22 = a22_inv; parameter Real invMixingUnit.b = b_inv; parameter Real invMixingUnit.k0 = k0_inv; parameter Real invMixingUnit.eps = eps; Real invMixingUnit.gamma "Reaction speed"; protected parameter Real invMixingUnit.tau0(quantity = "Time", unit = "s") = 60.0; protected parameter Real invMixingUnit.wk0 = invMixingUnit.k0 / invMixingUnit.c0; protected parameter Real invMixingUnit.weps = invMixingUnit.eps * invMixingUnit.T0; protected parameter Real invMixingUnit.wa11 = invMixingUnit.a1 / invMixingUnit.tau0; protected parameter Real invMixingUnit.wa12 = invMixingUnit.c0 / invMixingUnit.tau0; protected parameter Real invMixingUnit.wa13 = invMixingUnit.c0 * invMixingUnit.a1 / invMixingUnit.tau0; protected parameter Real invMixingUnit.wa21 = invMixingUnit.a21 / invMixingUnit.tau0; protected parameter Real invMixingUnit.wa22 = invMixingUnit.a22 * invMixingUnit.T0 / invMixingUnit.tau0; protected parameter Real invMixingUnit.wa23 = invMixingUnit.T0 * (invMixingUnit.a21 - invMixingUnit.b) / invMixingUnit.tau0; protected parameter Real invMixingUnit.wb = invMixingUnit.b / invMixingUnit.tau0; Real add.u1 "Connector of Real input signal 1"; Real add.u2 "Connector of Real input signal 2"; Real add.y "Connector of Real output signal"; parameter Real add.k1 = 1.0 "Gain of upper input"; parameter Real add.k2 = 1.0 "Gain of lower input"; Real inverseBlockConstraints.u1 "Input signal 1 (u1 = u2)"; Real inverseBlockConstraints.u2 "Input signal 2 (u1 = u2)"; Real inverseBlockConstraints.y1 "Output signal 1 (y1 = y2)"; Real inverseBlockConstraints.y2 "Output signal 2 (y2 = y2)"; Real mixingUnit.T_c(unit = "K") "Cooling temperature"; Real mixingUnit.c(unit = "mol/l", start = c_start, fixed = true) "Concentration"; Real mixingUnit.T(unit = "K", start = T_start, fixed = true) "Temperature in mixing unit"; parameter Real mixingUnit.c0(unit = "mol/l") = c0 "Nominal concentration"; parameter Real mixingUnit.T0(quantity = "ThermodynamicTemperature", unit = "K", displayUnit = "degC", min = 0.0, start = 288.15, nominal = 300.0) = T0 "Nominal temperature"; parameter Real mixingUnit.a1 = a1; parameter Real mixingUnit.a21 = a21; parameter Real mixingUnit.a22 = a22; parameter Real mixingUnit.b = b; parameter Real mixingUnit.k0 = k0; parameter Real mixingUnit.eps = eps; Real mixingUnit.gamma "Reaction speed"; protected parameter Real mixingUnit.tau0(quantity = "Time", unit = "s") = 60.0; protected parameter Real mixingUnit.wk0 = mixingUnit.k0 / mixingUnit.c0; protected parameter Real mixingUnit.weps = mixingUnit.eps * mixingUnit.T0; protected parameter Real mixingUnit.wa11 = mixingUnit.a1 / mixingUnit.tau0; protected parameter Real mixingUnit.wa12 = mixingUnit.c0 / mixingUnit.tau0; protected parameter Real mixingUnit.wa13 = mixingUnit.c0 * mixingUnit.a1 / mixingUnit.tau0; protected parameter Real mixingUnit.wa21 = mixingUnit.a21 / mixingUnit.tau0; protected parameter Real mixingUnit.wa22 = mixingUnit.a22 * mixingUnit.T0 / mixingUnit.tau0; protected parameter Real mixingUnit.wa23 = mixingUnit.T0 * (mixingUnit.a21 - mixingUnit.b) / mixingUnit.tau0; protected parameter Real mixingUnit.wb = mixingUnit.b / mixingUnit.tau0; Real feedback.u1; Real feedback.u2; Real feedback.y; parameter Real gain.k(unit = "1", start = 1.0) = 20.0 "Gain value multiplied with input signal"; Real gain.u "Input signal connector"; Real gain.y "Output signal connector"; Real filter.u "Connector of Real input signal"; Real filter.y "Connector of Real output signal"; parameter Integer filter.n = 3 "Order of filter"; parameter Real filter.f(quantity = "Frequency", unit = "Hz", start = 1.0) = freq "Cut-off frequency"; parameter Boolean filter.normalized = true "= true, if amplitude at f_cut is 3 dB, otherwise unmodified filter"; Real filter.x[1](start = 0.49, fixed = true) "Filter states"; Real filter.x[2](start = 0.49, fixed = false) "Filter states"; Real filter.x[3](start = 0.49, fixed = false) "Filter states"; protected parameter Real filter.alpha = if filter.normalized then sqrt(-1.0 + 2.0 ^ (1.0 / /*Real*/(filter.n))) else 1.0 "Frequency correction factor for normalized filter"; protected parameter Real filter.w = 6.283185307179586 * filter.f / filter.alpha; parameter Real hold1.y_start = 0.0 "Value of output y before the first tick of the clock associated to input u"; Real hold1.u(start = hold1.y_start) "Connector of clocked, Real input signal"; Real hold1.y "Connector of continuous-time, Real output signal"; Real sample1.u "Connector of continuous-time, Real input signal"; Real sample1.y "Connector of clocked, Real output signal"; parameter Boolean periodicClock1.useSolver = true "= true, if solverMethod shall be explicitely defined"; parameter String periodicClock1.solverMethod = "ExplicitEuler" "Integration method used for discretized continuous-time partitions"; Clock periodicClock1.y; parameter Real periodicClock1.period(quantity = "Time", unit = "s") = 1.0 "Period of clock (defined as Real number)"; Real step.y "Connector of Real output signal"; parameter Real step.offset = c_start "Offset of output signal y"; parameter Real step.startTime(quantity = "Time", unit = "s") = 0.0 "Output y = offset for time < startTime"; parameter Real step.height = c_high_start - c_start "Height of step"; Real sample2.u "Connector of continuous-time, Real input signal"; Real sample2.y "Connector of clocked, Real output signal"; Clock sample2.clock "Output signal y is associated with this clock input"; equation invMixingUnit.gamma = invMixingUnit.c * invMixingUnit.wk0 * exp((-invMixingUnit.weps) / invMixingUnit.T); der(invMixingUnit.c) = invMixingUnit.wa13 + (-invMixingUnit.wa12) * invMixingUnit.gamma - invMixingUnit.wa11 * invMixingUnit.c; der(invMixingUnit.T) = invMixingUnit.wa22 * invMixingUnit.gamma + invMixingUnit.wa23 + invMixingUnit.wb * invMixingUnit.T_c - invMixingUnit.wa21 * invMixingUnit.T; add.y = add.k1 * add.u1 + add.k2 * add.u2; inverseBlockConstraints.u1 = inverseBlockConstraints.u2; inverseBlockConstraints.y1 = inverseBlockConstraints.y2; mixingUnit.gamma = mixingUnit.c * mixingUnit.wk0 * exp((-mixingUnit.weps) / mixingUnit.T); der(mixingUnit.c) = mixingUnit.wa13 + (-mixingUnit.wa12) * mixingUnit.gamma - mixingUnit.wa11 * mixingUnit.c; der(mixingUnit.T) = mixingUnit.wa22 * mixingUnit.gamma + mixingUnit.wa23 + mixingUnit.wb * mixingUnit.T_c - mixingUnit.wa21 * mixingUnit.T; feedback.y = feedback.u1 - feedback.u2; gain.y = gain.k * gain.u; der(filter.x[1]) = (filter.u - filter.x[1]) * filter.w; der(filter.x[2]) = (filter.x[1] - filter.x[2]) * filter.w; der(filter.x[3]) = (filter.x[2] - filter.x[3]) * filter.w; filter.y = filter.x[3]; hold1.y = hold(hold1.u); sample1.y = sample(sample1.u, Clock()); periodicClock1.y = Clock(Clock(periodicClock1.period), periodicClock1.solverMethod); step.y = step.offset + (if time < step.startTime then 0.0 else step.height); sample2.y = sample(sample2.u, sample2.clock); feedback.y = gain.u; add.u2 = gain.y; invMixingUnit.T_c = inverseBlockConstraints.y2; invMixingUnit.c = inverseBlockConstraints.u2; feedback.u1 = invMixingUnit.T; filter.y = inverseBlockConstraints.u1; hold1.y = mixingUnit.T_c; add.y = hold1.u; mixingUnit.T = sample1.u; feedback.u2 = sample1.y; add.u1 = inverseBlockConstraints.y1; sample2.u = step.y; filter.u = sample2.y; periodicClock1.y = sample2.clock; end Modelica_Synchronous.Examples.Systems.ControlledMixingUnit;
comment:40 by , 9 years ago
Great. Now it's up to the backend (mostly). The nightly tests report an internal error -- SynchronousFeatures.resolveClocks failure:
Error: pre-optimization module clockPartitioning (simulation) failed.
Unfortunately the error message does not give more details -- the error falls through due to use of match instead of matchcontinue in the function getSubClock. It is most likely the attempt to get a string for the solverMethod (see #3717).
Clock partitioning passes with the runtime argument -d=evalparam
. The next failure is then:
Error: Internal error BackendDAEOptimize.partitionIndependentBlocks failed without good error message Error: No system for the symbolic initialization was generated
comment:41 by , 9 years ago
The error messages have been improved meanwhile.
Commit
https://github.com/OpenModelica/OMCompiler/commit/4d11cc6c536dd69b0d82b7e1750eafba21bb4595
adds initial support for continuous-time equations in clocked partitions. Basic examples are working, such as Modelica_Synchronous.Examples.SimpleControlledDrive.ClockedWithDiscretizedContinuousController
.
Unfortunately the solver method only works with -d=evalparam
. Meaning that the ball is back on the frontend side (see #3717).
For some other examples the generation of simulation code still fails. See in particular #3741.
comment:44 by , 9 years ago
Owner: | changed from | to
---|
comment:45 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
It might be possible that OpenModelica switches off synchronous features when loading
Modelica_Synchronous
as it hasuses(Modelica(version="3.2.1"))
.However, I think if you activate +std=3.3 before loading Modelica and Modelica_Synchronous it would stay that way.