Access package contents from string argument in Modelica - modelica

I have a string vector with the names of some substances vec = {"H2","O2"}, and I would like to use these strings to access a record in a package such that
Modelica.Media.IdealGases.Common.SingleGasesData.'vec[1]'
returns the data of H2.
Is this possible in Modelica, or do I have to do it manually?

I ended up doing it manually:
import d = Modelica.Media.IdealGases.Common.SingleGasesData;
constant Modelica.Media.IdealGases.Common.DataRecord data[Species]={d.H2,d.O2};
It might be slow and requires some index tracking, but for small sizes it is doable.

Related

Extract Types/Classnames from flat Modelica code

I was wondering if there already exists a possibility to extract from flat Modelica code all variables AND their corresponding types (classnames respectively).
For example:
Given an extract from a flattened Modelica model:
constant Integer nSurfaces = 8;
constant Integer construction1.nLayers(min = 1.0) = 2 "Number of layers of the construction";
parameter Modelica.SIunits.Length construction1.thickness[construction1.nLayers]= {0.2, 0.1} "Thickness of each construction layer";
Here, the wanted output would be something like:
nSurfaces, Integer, constant;
construction1.nLayers, Integer, constant;
construction1.thickness[construction1.nLayers], Modelica.SIunits.Length, parameter
Ideally, for construction1.thickness there would be two lines (=number of construction1.nLayers).
I know, that it is possible to get a list of used variables from the dsin.txt, which is produced while translating a model. But until now I did not find an already existing way to get the corresponding types. And I really would like to avoid writing an own parser :-).
You could try to generate the file modelDescription.xml as defined by the FMI standard. It contains a ton of information and XML should be easier to parse, e.g. python has a couple of xml parsing/reading packages.
If you are using Dymola you just set the flag Advanced.FMI.GenerateModelDescriptionInterface2 = true to generate the model description file.
The second idea could be to let the compiler/tool parse the Modelica file for you as they need to do that anyway, try searching for AST (abstract syntax tree). In Dymola, this is available through the ModelManagement library, and also through the Python interface.
Third idea could be to use one of the Modelica parsers available, e.g. have a look at:
https://github.com/lbl-srg/modelica-json
https://hackage.haskell.org/package/modelicaparser
https://github.com/xie-dongping/modparc
https://github.com/pymoca/pymoca
https://github.com/pymola/pymola/tree/master/src/pymola
Fourth, if all that did not work, you still do not have to write a full parser, you could use ANTLR, then use an existing grammar file (look for e.g. modelica.g4).

OCaml: serialize data into string with additional requirements

what I am looking for
Let T be an OCaml data type, (example: type t = A | B of int), and x be a value of type T, is there a function f that satisfies the following requirements:
f maps x to a string, i.e. f(x) is a string representation of x
for all u, v in T, u = v if and only if f(u) = f(v)
f can be derived automatically, like type t = ... [##deriving yojson]
the string representation of a value of a relatively simple type, like the one defined above, should be human editable
(not essential, but nice to have) locality, i.e., if you extend the type t above to type t = A | B of int | C of something, then f("A the one before the extending") should be equal to f("A the one after the extending"), in another word, it should make upgrading an old version of a type to the new version easy
why I want this
Store an OCaml data into Postgres column. I have a small web app that uses PGOCaml to fetch data from Postgres, and PGOCaml type checks the SQL statement at compile time, so if you create domain some_type as text in Postgres, and change the source code of PGOCaml a bit (to use the above f to convert a Postgres text into an OCaml type), you can store ADT into a Postgres table, while maintain type safety.
The second point in the requirements is important, for on the Postgres side, you likely need to test for equality on that column, and such tests are done on Postgres text type.
I looked into Sexp, didn't find information about the second point.
PS, new to OCaml, does this kind of thing already have a mature solution?
Update
I end up using yojson, since my type is very simple, just nullary variants, I can get away with it, it's a galaxy away from perfect though.
Update 2
For those who has the similar problem, I think the current best solution is to use yojson, and instead of storing it in a text column, storing it in a jsonb, this way, you get white space and order insensitive comparison, (though I cannot find pg's documentation on the equality of jsonb type).
Upgrading RichouHunters comment to an answere as I think Sexplib is a good module for this:
I think the way s-expressions may (or may not) satisfy your second requirement will depend a lot on your type T and on the way you define the serializer. You'll find more about them (and Sexplib) here.

how single and double type variables work in the same copy of code in Matlab like template in C++

I am writing a signal processing program using matlab. I know there are two types of float-pointing variables, single and double. Considering the memory usage, I want my code to work with only single type variable when the system's memory is not large, while it can also be adapted to work with double type variables when necessary, without significant modification (simple and light modification before running is OK, i.e., I don't need runtime-check technique). I know this can be done by macro in C and by template in C++. I don't find practical techniques which can do this in matlab. Do you have any experience with this?
I have a simple idea that I define a global string containing "single" or "double", then I pass this string to any memory allocation method called in my code to indicate what type I need. I think this can work, I just want to know which technique you guys use and is widely accepted.
I cannot see how a template would help here. The type of c++ templates are still determined in compile time (std::vector vec ...). Also note that Matlab defines all variables as double by default unless something else is stated. You basically want runtime checks for your code. I can think of one solution as using a function with a persistent variable. The variable is set once per run. When you generate variables you would then have to generate all variables you want to have as float through this function. This will slow down assignment though, since you have to call a function to assign variables.
This example is somehow an implementation of the singleton pattern (but not exactly). The persistent variable type is set at the first use and cannot change later in the program (assuming that you do not do anything stupid as clearing the variable explicitly). I would recommend to go for hardcoding single in case performance is an issue, instead of having runtime checks or assignment functions or classes or what you can come up with.
function c = assignFloat(a,b)
persistent type;
if (isempty(type) & nargin==2)
type = b;
elseif (isempty(type))
type = 'single';
% elseif(nargin==2), error('Do not set twice!') % Optional code, imo unnecessary.
end
if (strcmp(type,'single'))
c = single(a);
return;
end
c = double(a);
end

Phobos-Range Compatible Fixed-Dimensional Vector

What is the most clever way of implementing a fixed-dimensional vector in D that is compatible with the RandomAccessRange interface in Phobos? Do I have to reimplement all the members opIndex, length etc or is the cleverer way through delegation, alias this or template mixins? I've been looking at a couple of fixed-size vector structs on github D projects but none seem to care about being compatible with Phobos ranges. Update: Is just read that containers should be reference types so I guess this isn't the way to do it in D right?
If your vector has continuous internal storage then you can just return a slice of that data from opSlice():
struct Vector
{
private real[4] data;
auto opSlice() { return data[]; }
}
Containers don't have to be reference types, but either way using opSlice is the usual way to get a range from a container.

matlab: is there a way to import/promote variables from a structure to the current workspace?

function y = myfunc(param)
C = param.C;
L = param.L;
Kp = param.Kp;
Ki = param.Ki;
...
Is there a way to generalize the above code? I know how to generalize the structure access using fieldnames() and getfield(), but not how to set variables without calling eval() (which is evil).
for n = fieldnames(param)'
name = n{1};
value = param.(name);
do_something_with(name,value); % ????
never mind, I figured it out; this helper function works:
function vars_pull(s)
for n = fieldnames(s)'
name = n{1};
value = s.(name);
assignin('caller',name,value);
end
The only way to create a variable whose name is determined at run-time is to use a function like eval, evalin, feval, or assignin. (assignin is the least evil choice BTW, at least you don't need to convert your value to a string and back.)
However, I question why you want to do that, why not just access the values through the input structure as you need them. If you want to save typing (speaking from experience, as I am extremely lazy), I usually name my input parameter structure something short, like p. The throughout my code I just access the fields directly, (e.g. p.Kp, and after a while I don't even see the p. anymore.) This also makes it easy to pass the structure into subfunctions as needed.
You can use the excellent submission at FileExchange:
V2STRUCT - Pack & Unpack variables to & from structures with enhanced functionality
Here's a workaround: save the structure to a .mat file using the '-struct' option, and then immediately reload it. Here's an example for struct variable X:
save('deleteme.mat','-struct','X');
load('deleteme.mat');
delete('deleteme.mat');
It's kludgey, but actually pretty fast, at least with an SSD.