#2519 closed defect (fixed)
constant evaluation of spice3 functions fails, needed for Inverter example
Reported by: | Peter Aronsson | Owned by: | somebody |
---|---|---|---|
Priority: | critical | Milestone: | 1.9.1 |
Component: | Frontend | Version: | trunk |
Keywords: | Cc: | Adrian Pop, Per Östlund |
Description
See attached model which is just a set of constant values (records) from the spice3 library.
This example has been constructed to illustrate the need of being able to constant evaluate certain record elements to allow the backend to recognize that certain states must be eliminated. For instance, the Inverter example has the equation (in the Modelica.Electrical.Spice3.Internal.MOS model):
icBD = cc.cBD * (der(B.v) - der(Dinternal));
But, cc.cBD will for both transistors of the model be 0, thus completely eliminating Dinternal and B.v as states. The model won't work if this is not detected, and the only way to detect that is to build some analysis based on constant evaluation of functions to figure out that e.g. cc.CBD is constant (depending on parameters). Note that other elements of the cc record are time-varying!
partial failtrace:
Ceval.ceval DAE.CALL failed: Modelica.Electrical.Spice3.Internal.Mos.mosCalcDEVqmeyer(int_c.m_vgs, vgd, vgb, /*Modelica.Electrical.Spice3.Internal.Mos.MosCalc*/(int_c)) - CevalFunction.evaluateStatement failed for: qm := Modelica.Electrical.Spice3.Internal.Mos.mosCalcDEVqmeyer(int_c.m_vgs, vgd, vgb, /*Modelica.Electrical.Spice3.Internal.Mos.MosCalc*/(int_c)); ...
Attachments (1)
Change History (18)
by , 11 years ago
comment:1 by , 11 years ago
follow-up: 5 comment:2 by , 11 years ago
Cc: | added |
---|
I think I have found the problem:
Ceval for casting of records is not implmented, so :
/*Modelica.Electrical.Spice3.Internal.Mos.MosCalc*/(int_c)
fails. But shouldn't this be resolved in Static where type checking is performed? Since int_c above is type equivalent with MosCalc, I would expect that there is no need for a cast.
comment:3 by , 11 years ago
In Types.mo:
In Types.mo: {{{ // Complex types (records) that need a cast case (e, DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(p1),varLst = els1), t2 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(p2),varLst = els2),_) equation false = Absyn.pathEqual(p1,p2) "We need to add a cast from one record to another"; true = subtypeVarlist(els1, els2); e = DAE.CAST(t2, e); then (e, t2); }}} The comment ''We need to add a cast from one record to another'' doesn't say much. Why is it needed? The records must be type equivalent so why do we need a cast?
comment:4 by , 11 years ago
A fix for this in ceval is:
// Cast of records (Check done by static, so ok to just evaluate the expression and return) case(cache,env,DAE.CAST(ty = ty,exp = e),impl,stOpt,msg,_) equation true = Types.isRecord(ty); (cache,value,stOpt) = ceval(cache, env, e, impl, stOpt,msg,numIter+1); then (cache,value,stOpt);
comment:5 by , 11 years ago
Replying to petar:
But shouldn't this be resolved in Static where type checking is performed? Since int_c above is type equivalent with MosCalc, I would expect that there is no need for a cast.
The CAST is needed because the C-code needs it (and maybe other targets too)
comment:6 by , 11 years ago
Peter A., i'll try your fix and see what the testsuite gives us.
If is working I'll commit it.
follow-up: 10 comment:9 by , 11 years ago
Of course we don't. Anyway, I would make it also type-convert the Values.RECORD to the expected type. It will probably work fine anyway since we only do ceval on complete expressions and not subexpressions. But you never know...
comment:10 by , 11 years ago
Replying to sjoelund.se:
Of course we don't. Anyway, I would make it also type-convert the Values.RECORD to the expected type. It will probably work fine anyway since we only do ceval on complete expressions and not subexpressions. But you never know...
That is probably good. That will only change the record name (because e.g. record assignments must be type-equivalent), right?
comment:12 by , 11 years ago
The only difference the modification makes is that all these constants have a zero binding:
constant Real cc.idrain(quantity = \"ElectricCurrent\", unit = \"A\", start = 0.0) = 0.0; constant Real cc.iBD(quantity = \"ElectricCurrent\", unit = \"A\", start = 0.0) = 0.0; constant Real cc.iBS(quantity = \"ElectricCurrent\", unit = \"A\", start = 0.0) = 0.0; constant Real cc.cGS(quantity = \"Capacitance\", unit = \"F\", min = 0.0, start = 0.0) = 0.0; constant Real cc.cGB(quantity = \"Capacitance\", unit = \"F\", min = 0.0, start = 0.0) = 0.0; constant Real cc.cGD(quantity = \"Capacitance\", unit = \"F\", min = 0.0, start = 0.0) = 0.0; constant Real cc.cBS(quantity = \"Capacitance\", unit = \"F\", min = 0.0, start = 0.0) = 0.0; constant Real cc.cBD(quantity = \"Capacitance\", unit = \"F\", min = 0.0, start = 0.0) = 0.0; constant Real cc.m_capgd(quantity = \"Capacitance\", unit = \"F\", min = 0.0) = 0.0;
Is this what is desired?
With the current trunk (no modification) these constants have no binding.
The testsuite seems to be fine, so I'll commit this.
comment:13 by , 11 years ago
Yes, that is fine. It's just a dummy example and most parameters should be zero. Thanks a lot!
follow-up: 16 comment:14 by , 11 years ago
Fixed in r18500 using the suggested ceval case.
However, at least for us seems to be no change in the simulation of:
Modelica.Electrical.Spice3.Examples.Inverter.
It still fails with singular system.
comment:16 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Replying to adrpo:
Fixed in r18500 using the suggested ceval case.
However, at least for us seems to be no change in the simulation of:
Modelica.Electrical.Spice3.Examples.Inverter.
It still fails with singular system.
No, you need more stuff in order to make it work, a'la Dymola tricks. I am working on a workaround to change the library so it can be correctly translated by using annotation(Evaluate=true).
comment:17 by , 11 years ago
On why the model doesn't simulate in omc I would like to point to #2576
Note that MathCore needs this to be fixed in CevalFunction (i.e. interpretative) as we cannot use dynamic loading of functions in our kernel.