writing a vector using "readTrajectory" function in Dymola - dymola

I write a vector in Dymola mos script in a simple manner like this:
x_axis = cell.spatialSummary.x_cell;
output: x_axis={1,2,3,4,5} // row vector
I want to do the same thing in a function.'x_cell' has 5 values which I want to store in a row vector. I use DymolaCommands.Trajectories.readTrajectory function to read x_cell values one by one in for loop (I use for loop because, readTrajectory throws an error when I try to read entire x_cell)
Real x_axis[:],axis_value[:,:];
Integer len=5;
for i in 1:len loop
axis_value:=readTrajectory(result,{"cell.spatialSummary.x_cell["+String(i)+"]"},1); //This intermediate variable returns [1,1] matrix
x_axis[i]:=scalar(axis_value);
end for;
I get an error:
Assignment failed x_axis[i] = scalar(axis_value);
what's wrong here? All I want to do is read all values of x_cell and write it into a vector. How can I do this in dymola function?
Thank you!

Solution: Initialize the vector with a certain value. In this case,
x_axis :=fill(0, len);
This solved the above problem for me.

Pre filling as in the other solution works, and is generally the best solution. However, in some cases you might have to append to the vector as follows:
x_axis=fill(0.0, 0);
for i in 1:len loop
axis_value:=readTrajectory(result,{"cell.spatialSummary.x_cell["+String(i)+"]"},1); //This intermediate variable returns [1,1] matrix
x_axis:=cat(1, x_axis, {scalar(axis_value)});
end for;
(This takes x_axis and concatenates a new element at the end. It is generally slower.)

Related

Error when using least_squares to solve constrained nonlinear system of equations

I'm trying to solve a nonlinear system of 7 equations with least_squares, as some variables are molar fractions and go between 0 and 1 (fsolve doesnt allow constraints as far as I've read). Heres the main part of the code:
def fun_t(w,x_2):
x_1=1-x_2;
z_A=w[0];
z_B=w[1];
z_AB=w[2];
gamma_A=w[3];
gamma_B=w[4];
gamma_AB=w[5];
eps=w[6]
K_gamma=gamma_AB/(gamma_A*gamma_B)
K=K_gamma*z_AB/(z_A*z_B)
phi_A=z_A*v_A/(z_A*v_A+z_B*v_B+z_AB*v_AB);
phi_B=z_B*v_B/(z_A*v_A+z_B*v_B+z_AB*v_AB);
phi_AB=z_AB*v_AB/(z_A*v_A+z_B*v_B+z_AB*v_AB);
return [z_AB-eps/(1-eps),
z_A-(x_2-eps)/(1-eps),
z_B-(x_1-eps)/(1-eps),
eps-(1-(1-4*K/(K+K_gamma)*x_1*x_2)**0.5)/2,
R*T*np.log(gamma_A)-v_A*(alphaT_AB*phi_B**2+alphaT_AAB*phi_AB**2+(alphaT_AB+alphaT_AAB-alphaT_BAB)*phi_B*phi_AB),
R*T*np.log(gamma_B)-v_B*(alphaT_AB*phi_A**2+alphaT_BAB*phi_AB**2+(alphaT_AB+alphaT_BAB+alphaT_AAB)*phi_A*phi_AB),
R*T*np.log(gamma_AB)-v_AB*(alphaT_AAB*phi_A**2+alphaT_BAB*phi_B**2+(alphaT_AAB+alphaT_BAB-alphaT_AB)*phi_A*phi_B)
]
x_2=np.linspace(0,1,11)
guess=[0.5,0.5,0.5,1,1,1,0.25];
roots_t=np.zeros(shape=(len(x_2),len(guess)))
for i in range(len(x_2)):
roots_t[i] = least_squares(fun_t, guess, bounds = ((0,0,0,-5,-5,-5,0),(1,1,1,5,5,5,0.5)), args=x_2[i])
I get the error TypeError: fun_t() argument after * must be an iterable, not numpy.float64. My goal is to give the elements of the array x_2 as the fuction's second argument in order to get the rest of the variables for a set of compositions. I dont understand why it cant iterate over x_2, as it worked when I was using fsolve.
I'm just starting using python for this kind of calculations, so any help will be much appreciated!

X and Y inputs in LabVIEW

I am new to LabVIEW and I am trying to read a code written in LabVIEW. The block diagram is this:
This is the program to input x and y functions into the voltage input. It is meant to give an input voltage in different forms (sine, heartshape , etc.) into the fast-steering mirror or galvano mirror x and y axises.
x and y function controls are for inputting a formula for a function, and then we use "evaluation single value" function to input into a daq assistant.
I understand that { 2*(|-Mpi|)/N }*i + -Mpi*pi goes into the x value. However, I dont understand why we use this kind of formula. Why we need to assign a negative value and then do the absolute value of -M*pi. Also, I don`t understand why we need to divide to N and then multiply by i. And finally, why need to add -Mpi again? If you provide any hints about this I would really appreciate it.
This is just a complicated way to write the code/formula. Given what the code looks like (unnecessary wire bends, duplicate loop-input-tunnels, hidden wires, unnecessary coercion dots, failure to use appropriate built-in 'negate' function) not much care has been given in writing it. So while it probably yields the correct results you should not expect it to do so in the most readable way.
To answer you specific questions:
Why we need to assign a negative value and then do the absolute value
We don't. We can just move the negation immediately before the last addition or change that to a subtraction:
{ 2*(|Mpi|)/N }*i - Mpi*pi
And as #yair pointed out: We are not assigning a value here, we are basically flipping the sign of whatever value the user entered.
Why we need to divide to N and then multiply by i
This gives you a fraction between 0 and 1, no matter how many steps you do in your for-loop. Think of N as a sampling rate. I.e. your mirrors will always do the same movement, but a larger N just produces more steps in between.
Why need to add -Mpi again
I would strongly assume this is some kind of quick-and-dirty workaround for a bug that has not been fixed properly. Looking at the code it seems this +Mpi*pi has been added later on in the development process. And while I don't know what the expected values are I would believe that multiplying only one of the summands by Pi is probably wrong.

How to find out what arguments DM functions should take?

Through trial and error, I have found that the GetPixel function takes two arguments, one for X and one for Y, even if used on a 1D image. On a 1D image, the second index must be set to zero.
image list := [3]: {1,2,3}
list.GetPixel(0,0) // Gets 1
GetPixel(list, 0, 0) // Equivalent
How am I supposed to know this? I can't see anything clearly specifying this in the documentation.
This is best done by using the script function with an incorrect parameter list, running the script, and observing the error output:

Error due to variable size data in Simulink Matlab function block

I'm working with the Simulink block MATLAB FUNCTION and I'm having problems with the bounds of the variables that I define in there.
This is the part of the code where I’m getting troubles
function P_S1_100= fcn(SOC_S1_100,S1_AGENTS_10,time_CAP_100)
assert(time_CAP_100(1)<100)
tcharging_a1_1=[0:0.05:time_CAP_100(1)]
tcharging_a1_2=[time_CAP_100(1):0.05:time_CAP_100(1)*2]
tcharging_a1=[0:0.05:time_CAP_100(1)]
(Where time_CAP_100 is a vector [1x6])
And this is the error that I'm getting:
Computed maximum size of the output of function 'colon' is not bounded.
Static memory allocation requires all sizes to be bounded.
The computed size is [1 x :?].
Function 'Subsystem1/Slow Charge/S1/MATLAB Function5' (#265.262.302), line 8, column 16:
"[time_CAP_100(1):0.05:time_CAP_100(1)*2]"
Could anyone give me an idea of how to solve this error?
Thanks in advance.
For each of your variable-size data inputs/outputs, you need to define what the upper bound is. See http://www.mathworks.co.uk/help/simulink/ug/declare-variable-size-inputs-and-outputs.html for more details.
Only work around I can think of is to manually write a loop with fixed loop bounds to expand [time_CAP_100(1):0.05:time_CAP_100(1)*2]. That expression is what is causing the problem. You need to know the bounds of this vector. Then you can write a loop something like
% max_size is the maximum length possible for tcharging_a1_2
tcharging_a1_2 = zeros(1,max_size);
tcharging_a1_2(1) = time_CAP_100(1);
for ii=2:max_size
if tcharging_a1_2(ii) < time_CAP_100(1)*2
tcharging_a1_2(ii) = tcharging_a1_2(ii) + .05;
end
end

Catch errors (not exceptions) in Mathematica

I have a Table that does fitting operations for 10000 datasets that looks as follows:
ParallelTable[
NonlinearModelFit[data[[i]], func[t,a,b,c,d], {a,b,c,d}, t],
{i,1,10000}];
Which I can change to a for loop if necessary for my problem. That's no problem.
I would like to be able to catch errors in this statement. So if NonlinearModelFit returns any kind of errors (saddle point, maximum iterations reached, non-convergence), I would like to have "i" printed or appended to some other array, in order to know which dataset is not compatible with the fit and debug it. How can I do that?
Just to paraphrase belisarius and make it an answer:
Use
Check[ mymaincommand, resultexpressioniferror, optionallistofspecificmessages]