Modelica Dymola: How to change component parameters during state graph simulation? - dymola

Say I have a fluid model, with initial pressures, temperatures, valve settings, etc.
Is there a way to run a State Graph simulation where each of the states contains new component parameter settings for the model, i.e. some parameters of some selected components are changed during one state, and are changed again during the next state?
For example, during State1 let's set the values for the following component parameters:
source.pressure = 1
source.temperature = 1
valve1.opening = 1
Until State1 switches to State2 where the parameters are:
source.pressure = 0.5
source.temperature = 0.5
valve1.opening = 0.5
Thanks for your time :-)

Short answer: No. For that use-case you should use discrete variables (and change them using a when-clause).
Long answer: As of version 3.3, Modelica has a new feature, called State Machines (see chapter 17 of the specification). In theory, it should do what you require, but it might still be buggy since it is quite new.
What you are attempting to do is called "variable structure modeling" (although only changing parameters is hardly "variable structure" and can be implemented using discrete variables instead, as my short answer suggests). Long before StateMachines where introduced to Modelica, this was (and remains) an active area of research. You could also use an external tool to achieve your goal, e.g. DysMo

Related

Optimize "1D" bin packing/sheet cutting

Our use case could be described as a variant of 1D bin packing or sheet cutting.
Imagine a drywall with a beam framing.
We want to optimize the number and size of gypsum boards that would be needed to cover the wall.
Boards must start and end on a beam.
Boards must not overlap (hard constraint).
Less (i.e. bigger) boards, the better (soft constraint).
What we currently do:
Pre-generate all possible boards and pass them as problem facts.
Let the solver pick the best subset of those (nullable planning variable).
First Fit Decreasing + Simulated Annealing
Even relatively small walls (~6m, less than 20 possible boards to pick from) take sometimes minutes and while we mostly get a feasible solution, it's rarely optimal.
Is there a better way to model that?
EDIT
Our current domain model looks like the following. Please note that the planning entity only holds the selected/picked material but nothing else. I.e. currently our planning entities are all equal, which kind of prevents any optimization that depends on planning entity difficulty.
data class Assignment(
#PlanningId
private val id: Long? = null,
#PlanningVariable(
valueRangeProviderRefs = ["materials"],
strengthComparatorClass = MaterialStrengthComparator::class,
nullable = true
)
var material: Material? = null
)
data class Material(
val start: Double,
val stop: Double,
)
Active (sub)pillar change and swap move selectors. See optaplanner docs section about move selectors (move neighorhoods). The default moves (single swap and single change) are probably getting stuck in local optima (and even though SA helps them escape those, those escapes are probably not efficient enough).
That should help, but a custom move to swap two subpillars of the almost the same size, might improve efficiency further.
Also, as you're using SA (Simulated Annealing), know that SA is parameter sensitive. Use optaplanner-benchmark to try multiple SA starting temp parameters with different dataset set sizes. Also compare it to a plain LA (Late Acceptance) in benchmarks too. LA isn't fickle like SA can be. (With fickle I don't mean unstable. I mean potential dataset size sensitive parameter tweaking.)

DEAP evolutionary module, always evaluate entire population

I'm trying to solve a non-deterministic problem with DEAP. the problem is that the module only evaluate new chromosome and uses the score kept in memory for old ones.
How can i set the module, so at each generation the ENTIRE population will be evaluated, and not just the new ones?
Thx
I don't think DEAP package can do that.
You can simply implement the algorithm on your own or find the new packages.
Anyway, check out my library contains most of the state-of-the-art meta-heuristic algorithms. It also evaluates the entire population in each generation.
https://github.com/thieunguyen5991/mealpy
You can modify 2-3 lines in your current chosen algorithm like below to force evaluation on all items. This can be done via copying from the source, to your local script, and then editing the invalid_individual flagged item check pre evaluation. Make sure in main you call local easimple and not algorithms.easimple to make the switch to local code.
If you are using easimple or eaMuPlusLambda, for example, you can find that function here in this file:
https://github.com/DEAP/deap/blob/master/deap/algorithms.py#L85
The 0th gen case here may not change(but can change anyway, unless your individuals come with a fitness already and you want to skip evaluation):
#(line 149 in above URL)
invalid_ind = [ind for ind in population if not ind.fitness.valid]
And then inside the generational process loop:
#(line 171 in url above):
invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
Removing the invalid check will result in all items being passed to evaluation:
invalid_ind = [ind for ind in population] #149
...
invalid_ind = [ind for ind in offspring] #171
But keep the algorithms import! note you also need to change varAnd(case of easimple) to algorithms.varAnd to prevent a break.
offspring = algorithms.varAnd(offspring, toolbox, cxpb, mutpb)

Redeclaring two Medium packages in One system component

I am new to modelica, and i don't have this much experience in it, but i got the basics of course. I am trying to model a micrfluidic network. The network consists of two sources of water and oil, controlled by two valves. The flow of the two mediums interact at a Tjunction and then into a tank or chamber. I don't care about the fluid properties of the mixture because its not my purpose. My question is how do redeclare two medium packages (water and oil) in one system component such as the Tjunction or a tank in order to simulate the system. In my real model, the two mediums doesn't meet, becuase every medium passes through the channels at a different time.
I attached the model with this message. Here's the link.
https://www.dropbox.com/s/yq6lg9la8z211uc/twomediumsv2.zip?dl=0
Thanks for the help .
I don't think you can redeclare a medium during simulation. In your case (where you don't need the mixing of the two fluids) you could create a new medium, for instance called OilWaterMixture, extending from Modelica.Media.Interfaces.PartialMedium.
If you look into the code of PartialMedium you'll see that it contains a lot of partial ("empty") functions that you should fill in in your new medium model. For example, in OilWaterMixture you should extend the function specificEnthalpy_pTX to return the specific enthalpy of your water/oil mixture, for a certain water/oil mixture (given by the mass fraction vector X). This could be done by adding the following model to the OilWaterMixture package:
redeclare function extends specificEnthalpy_pTX "Return specific enthalpy"
Oil = Modelica.Media.Incompressible.Examples.Essotherm650;
Water = Modelica.Media.Water.StandardWater;
algorithm
h_oil := Oil.h_pT(p,T);
h_water := Water.specificEnthalpy_pT(p,T);
h := X[0]*h_oil + X[1]*h_water;
end specificEnthalpy_pTX;
The mass fraction vector X is defined in PartialMedium and in OilWaterMixture you must define that it has two elements.
Again, since you are not going to actually use the mixing properties but only mass fraction vectors {0,1} or {1,0} the simple linear mixing equation should be adequate.
When you use OilWaterMixture in the various components, the error log will tell you which medium functions they need. So you probably don't need to extend all the partial functions in PartialMedium.

How to change the serie colur and pen in wxFreeChart?

I am using wxFreeChart library in my project. However I am unable to change the colour and line type in XY data series. In the documentation nor in the samples there is no example of such functionality. Also there are not straightforward functions allowsing to do this. Does anyone has experience with this library to say if it is even possible?
Yes, it is possible to set both the serie colour and the pen type for XY line charts.
These attributes are set via the XYLineRenderer class. The documentation does cover this but you have to click on the "List all members" to see them. The current documentation is available under XYLineRenderer Members.
For simple changes, you can access the XYLineRenderer using the XYDataset::GetRenderer() method. This returns an XYRenderer* which you will need to cast to a XYLineRenderer* in order to set the pen type. Of course you can create the XYLineRenderer* first and pass it to the XYDataset::SetRenderer method instead.
Here is an example:
// Set the colour and pen of the first series.
static_cast<XYLineRenderer*>(dataset->GetRenderer())
->SetSeriePen(0, new wxPen(*wxRED, 5, wxPENSTYLE_SHORT_DASH));
// Set the colour and pen of the second series.
static_cast<XYLineRenderer*>(dataset->GetRenderer())
->SetSeriePen(1, new wxPen(*wxBLUE, 1, wxPENSTYLE_DOT_DASH));
SetSeriePen is only available to XYLineRenderer for obvious reasons, but you can set the colour of any renderer with Renderer::SetSerieColour(size_t serie, wxColour *color).
Note: I am not that happy with the way wxFreeChart takes pointers in these functions. This project is not actively maintained, but I would like at some point to fork it and update the API to be more consistent with modern versions of C++ and wxWidgets.

How to convert Greensock's CustomEase functions to be usable in CreateJS's Tween system?

I'm currently working on a project that does not include GSAP (Greensock's JS Tweening library), but since it's super easy to create your own Custom Easing functions with it's visual editor - I was wondering if there is a way to break down the desired ease-function so that it can be reused in a CreateJS Tween?
Example:
var myEase = CustomEase.create("myCustomEase", [
{s:0,cp:0.413,e:0.672},{s:0.672,cp:0.931,e:1.036},
{s:1.036,cp:1.141,e:1.036},{s:1.036,cp:0.931,e:0.984},
{s:0.984,cp:1.03699,e:1.004},{s:1.004,cp:0.971,e:0.988},
{s:0.988,cp:1.00499,e:1}
]);
So that it turns it into something like:
var myEase = function(t, b, c, d) {
//Some magic algorithm performed on the 7 bezier/control points above...
}
(Here is what the graph would look like for this particular easing method.)
I took the time to port and optimize the original GSAP-based CustomEase class... but due to license restrictions / legal matters (basically a grizzly bear that I do not want to poke with a stick...), posting the ported code would violate it.
However, it's fair for my own use. Therefore, I believe it's only fair that I guide you and point you to the resources that made it possible.
The original code (not directly compatible with CreateJS) can be found here:
https://github.com/art0rz/gsap-customease/blob/master/CustomEase.js (looks like the author was also asked to take down the repo on github - sorry if the rest of this post makes no sense at all!)
Note that CreateJS's easing methods only takes a "time ratio" value (not time, start, end, duration like GSAP's easing method does). That time ratio is really all you need, given it goes from 0.0 (your start value) to 1.0 (your end value).
With a little bit of effort, you can discard those parameters from the ease() method and trim down the final returned expression.
Optimizations:
I took a few extra steps to optimize the above code.
1) In the constructor, you can store the segments.length value directly as this.length in a property of the CustomEase instance to cut down a bit on the amount of accessors / property lookups in the ease() method (where qty is set).
2) There's a few redundant calculations done per Segments that can be eliminated in the ease() method. For instance, the s.cp - s.s and s.e - s.s operations can be precalculated and stored in a couple of properties in each Segments (in its constructor).
3) Finally, I'm not sure why it was designed this way, but you can unwrap the function() {...}(); that are returning the constructors for each classes. Perhaps it was used to trap the scope of some variables, but I don't see why it couldn't have wrapped the entire thing instead of encapsulating each one separately.
Need more info? Leave a comment!