Strange problem with the fluid library in openmodelica - modelica

I wrote a simple code to experiment the use of the PrescribedPump machine in the Fluid package of the standard library. I'm using OpenModelica 1.13.2.
I would like to pump some water from a tank to another one, by using a prescribedPump driven with a constant value of 10000.
Here the code:
model PompaPilotata
package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater;
inner Modelica.Fluid.System system ;
Modelica.Fluid.Vessels.OpenTank bacinella1(redeclare package Medium = Medium,
T_ambient = system.T_ambient, T_start = system.T_ambient, crossArea = 4, energyDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial,
height = 10, level_start = 2, massDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial, nPorts = 1, p_ambient = system.p_ambient,
use_HeatTransfer = false, use_T_start = true, use_portsData = false) ;
Modelica.Fluid.Vessels.OpenTank bacinella2(redeclare package Medium = Medium,
T_ambient = system.T_ambient, T_start = system.T_ambient, crossArea = 4, energyDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial,
height = 10, level_start = 2, massDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial, nPorts = 1, p_ambient = system.p_ambient,
use_HeatTransfer = false, use_T_start = true, use_portsData = false) ;
Modelica.Fluid.Machines.PrescribedPump Pompa(redeclare package Medium = Medium,
medium(h(stateSelect = StateSelect.default), p(stateSelect = StateSelect.default)),N_nominal = 100, V = 0.1, allowFlowReversal = false,
checkValve = true, energyDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, m_flow_start = 0.0000001,
massDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, nParallel = 1, use_HeatTransfer = false, use_N_in = true) ;
Modelica.Blocks.Sources.Constant Costante(k = 10000);
Modelica.Fluid.Pipes.StaticPipe tubo1(redeclare package Medium = Medium,allowFlowReversal = true,
diameter = 0.1, height_ab = 0, isCircular = true, length = 5, nParallel = 1) ;
Modelica.Fluid.Pipes.StaticPipe tubo2(redeclare package Medium = Medium,allowFlowReversal = true,
diameter = 0.1, height_ab = 0, isCircular = true, length = 5, nParallel = 1);
equation
connect(tubo2.port_b, bacinella2.ports[1]);
connect(Pompa.port_b, tubo2.port_a);
connect(tubo1.port_b, Pompa.port_a);
connect(bacinella1.ports[1], tubo1.port_a);
connect(Costante.y, Pompa.N_in);
end PompaPilotata;
I get this error message from the compiler:
In file included from C:/OpenModelica1.13.264bit/include/omc/c/util/modelica_string.h:38:0,
from C:/OpenModelica1.13.264bit/include/omc/c/openmodelica_func.h:52,
from PompaPilotata_model.h:6,
from PompaPilotata_06inz.c:2:
PompaPilotata_06inz.c: In function 'PompaPilotata_eqFunction_237':
C:/OpenModelica1.13.264bit/include/omc/c/meta/meta_modelica_data.h:231:21: error: incompatible type for argument 2 of 'omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic'
#define mmc_mk_real mmc_mk_rcon
^
C:/OpenModelica1.13.264bit/include/omc/c/meta/meta_modelica_data.h:225:45: note: in definition of macro 'mmc_unbox_real'
#define mmc_unbox_real(X) mmc_prim_get_real(X)
^
PompaPilotata_06inz.c:3005:139: note: in expansion of macro 'mmc_mk_real'
data->simulationInfo->realParameter[7] = mmc_unbox_real(omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic(threadData, mmc_mk_real(data->simulationInfo->realParameter[5])));
^
In file included from PompaPilotata_model.h:23:0,
from PompaPilotata_06inz.c:2:
PompaPilotata_functions.h:223:15: note: expected 'modelica_real {aka double}' but argument is of type 'void *'
modelica_real omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic(threadData_t threadData, modelica_real _V_flow);
^
: recipe for target 'PompaPilotata_06inz.o' failed
\tools\msys\mingw64\bin\mingw32-make: [PompaPilotata_06inz.o] Error 1
\tools\msys\mingw64\bin\mingw32-make: * Waiting for unfinished jobs....
Compilation process failed. Exited with code 2.
Someone can explain me what does it mean and how to fix it?
Thanks

The model does not work in Dymola eiter, but it gives the following hint:
Function Pompa.flowCharacteristic_Unique7 is neither external nor has an algorithm. It should have been redeclared.
Therefore redeclaring the function for the flowCharacteristic should help. Copying this part from Modelica.Fluid.Examples.PumpingSystem and reducing the values for V_flow_nominal by a factor of 1000 (which is a wild guess) gives:
Modelica.Fluid.Machines.PrescribedPump Pompa(redeclare package Medium = Medium,
redeclare function flowCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticFlow (V_flow_nominal={0.001,0.0025,0.005}, head_nominal={100,60,0}),
medium(h(stateSelect = StateSelect.default), p(stateSelect = StateSelect.default)),N_nominal = 100, V = 0.1, allowFlowReversal = false,
checkValve = true, energyDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, m_flow_start = 0.0000001,
massDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, nParallel = 1, use_HeatTransfer = false, use_N_in = true);
With the second line actually being added.

Related

How to get SubtractAsync to fully slice off piece of the part

I'm trying to slice a part of this part, so that it matches the bottom part, and the method I'm trying is SubtractAsync.
When I do it however, the part gets sliced, but not so that the remaining part gets removed. Here's what I mean:
How do I edit my code to slice off the piece of the part?
My code:
local Brick = workspace.Brick
local Stack = Brick:Clone()
local TS = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(3, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, math.huge, true)
Stack.Position = Vector3.new(Brick.Position.X, Brick.Position.Y + Brick.Size.Y, Brick.Position.Z - 55)
local tween = TS:Create(Stack, tweenInfo, {Position = Vector3.new(Stack.Position.X, Stack.Position.Y, Stack.Position.Z + (55 * 2))})
Stack.Parent = workspace
tween:Play()
game.ReplicatedStorage.PlaceDown.OnServerEvent:Connect(function()
tween:Pause()
local PartA = Instance.new("Part")
local PartB = Instance.new("Part")
PartA.Transparency = 1
PartB.Transparency = 1
PartA.Parent = workspace
PartB.Parent = workspace
PartA.Orientation = Vector3.new(-90, 0, 0)
PartB.Orientation = Vector3.new(-90, 0, 0)
PartA.Size = Vector3.new(15, 0.051, 15)
PartB.Size = Vector3.new(15, 0.051, 15)
PartA.Position = Vector3.new(Brick.Position.X, Brick.Position.Y + 2.5, Brick.Position.Z - (Brick.Size.Z/2))
PartB.Position = Vector3.new(Brick.Position.X, Brick.Position.Y + 2.5, Brick.Position.Z + (Brick.Size.Z/2))
PartA.Anchored = true
PartB.Anchored = true
local SlicedStack = Stack:SubtractAsync({PartA, PartB})
SlicedStack.Position = Stack.Position
SlicedStack.Parent = workspace
Stack:Destroy()
PartA:Destroy()
PartB:Destroy()
end)

Machine Translation FFN : Dimension problem due to window size

this is my first time creating a FFN to train it to translate French to English using word prediction:
Input are two arrays of size 2 x window_size + 1 from source language and window_size target language. And the label of size 1
For e.g for window_size = 2:
["je","mange", "la", "pomme","avec"]
and
["I", "eat"]
So the input of size [5] and [2] after concatenating => 7
Label: "the" (refering to "la" in French)
The label is changed to one-hot-encoding before comparing with yHat
I'm using unique index for each word ( 1 to len(vocab) ) and train using the index (not the words)
The output of the FFN is a probability of the size of the vocab of the target language
The problem is that the FFN doesn't learn and the accuracy stays at 0.
When I print the size of y_final (target probability) and yHat (Model Hypo) they have different dimensions:
yHat.size()=[512, 7, 10212]
with 64 batch_size, 7 is the concatenated input size and 10212 size of target vocab, while
y_final.size()= [512, 10212]
And over all the forward method I have these sizes:
torch.Size([512, 5, 32])
torch.Size([512, 5, 64])
torch.Size([512, 5, 64])
torch.Size([512, 2, 256])
torch.Size([512, 2, 32])
torch.Size([512, 2, 64])
torch.Size([512, 2, 64])
torch.Size([512, 7, 64])
torch.Size([512, 7, 128])
torch.Size([512, 7, 10212])
Since the accuracy augments when yHat = y_final then I thought that it is never the case because they don't even have the same shapes (2D vs 3D). Is this the problem ?
Please refer to the code and if you need any other info please tell me.
The code is working fine, no errors.
trainingData = TensorDataset(encoded_source_windows, encoded_target_windows, encoded_labels)
# print(trainingData)
batchsize = 512
trainingLoader = DataLoader(trainingData, batch_size=batchsize, drop_last=True)
def ffnModel(vocabSize1,vocabSize2, learningRate=0.01):
class ffNetwork(nn.Module):
def __init__(self):
super().__init__()
self.embeds_src = nn.Embedding(vocabSize1, 256)
self.embeds_target = nn.Embedding(vocabSize2, 256)
# input layer
self.inputSource = nn.Linear(256, 32)
self.inputTarget = nn.Linear(256, 32)
# hidden layer 1
self.fc1 = nn.Linear(32, 64)
self.bnormS = nn.BatchNorm1d(5)
self.bnormT = nn.BatchNorm1d(2)
# Layer(s) afer Concatenation:
self.fc2 = nn.Linear(64,128)
self.output = nn.Linear(128, vocabSize2)
self.softmaaax = nn.Softmax(dim=0)
# forward pass
def forward(self, xSource, xTarget):
xSource = self.embeds_src(xSource)
xSource = F.relu(self.inputSource(xSource))
xSource = F.relu(self.fc1(xSource))
xSource = self.bnormS(xSource)
xTarget = self.embeds_target(xTarget)
xTarget = F.relu(self.inputTarget(xTarget))
xTarget = F.relu(self.fc1(xTarget))
xTarget = self.bnormT(xTarget)
xCat = torch.cat((xSource, xTarget), dim=1)#dim=128 or 1 ?
xCat = F.relu(self.fc2(xCat))
print(xCat.size())
xCat = self.softmaaax(self.output(xCat))
return xCat
# creating instance of the class
net = ffNetwork()
# loss function
lossfun = nn.CrossEntropyLoss()
# lossfun = nn.NLLLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=learningRate)
return net, lossfun, optimizer
def trainModel(vocabSize1,vocabSize2, learningRate):
# number of epochs
numepochs = 64
# create a new Model instance
net, lossfun, optimizer = ffnModel(vocabSize1,vocabSize2, learningRate)
# initialize losses
losses = torch.zeros(numepochs)
trainAcc = []
# loop over training data batches
batchAcc = []
batchLoss = []
for epochi in range(numepochs):
#Switching on training mode
net.train()
# loop over training data batches
batchAcc = []
batchLoss = []
for A, B, y in tqdm(trainingLoader):
# forward pass and loss
final_y = []
for i in range(y.size(dim=0)):
yy = [0] * target_vocab_length
yy[y[i]] = 1
final_y.append(yy)
final_y = torch.tensor(final_y)
yHat = net(A, B)
loss = lossfun(yHat, final_y)
################
print("\n yHat.size()")
print(yHat.size())
print("final_y.size()")
print(final_y.size())
# backprop
optimizer.zero_grad()
loss.backward()
optimizer.step()
# loss from this batch
batchLoss.append(loss.item())
print(f'batchLoss: {loss.item()}')
#Accuracy calculator:
matches = torch.argmax(yHat) == final_y # booleans (false/true)
matchesNumeric = matches.float() # convert to numbers (0/1)
accuracyPct = 100 * torch.mean(matchesNumeric) # average and x100
batchAcc.append(accuracyPct) # add to list of accuracies
print(f'accuracyPct: {accuracyPct}')
trainAcc.append(np.mean(batchAcc))
losses[epochi] = np.mean(batchLoss)
return trainAcc,losses,net
trainAcc,losses,net = trainModel(len(source_vocab),len(target_vocab), 0.01)
print(trainAcc)

tm_compass does not appear inside of graph

I'm trying to make a map of Europe using tmap and the eurostat package.
I want to add a compass and a scale bar to the map. However they don't appear inside the graph, but outside of the map, at the bottom. Does anyone know what I'm doing wrong? I want the compass at the left top of the map, and the scale bar at the right bottom.
countries = gisco_get_countries(
year = "2016",
epsg = "3035",
resolution = "3"
)
br = c(0,40,50,65,80,150)
tm_shape(countries, bbox = c(23, 14, 74, 55) * 10e4) +
tm_fill("#E0E0E0") +
tm_shape(nuts2.sf) +
tm_fill(
"fatal_inj_30day",
breaks = br,
style = "fixed",
palette = "Blues",
alpha = .7,
title = "Fatalities per million inhabitants \n(2018-2019)"
) +
tm_compass(position = c("left","top")) +
tm_scale_bar(position = c("right","bottom")) +
tm_shape(countries) +
tm_borders(lwd = .25) +
tm_layout(
bg.color = "#F2F2F2",
outer.bg.color = "white",
legend.bg.color = "white",
legend.frame = "black",
legend.title.size = 0.8,
inner.margins = c(0, 0, 0, 0),
outer.margins = c(0, 0, 0, 0),
frame = TRUE,
frame.lwd = 0,
attr.outside = TRUE,
legend.position = c("right", "top"),
main.title = "Note: regions with 10 fatalities or less are not included in the Figure",
main.title.position = "left",
main.title.size = 0.7
)

Error calling / running Model via OMShell & OMPython - OpenModelica

I am using the Dimensions model for placing parameters of the system that I use in many different models and call them by using extend, instead of declaring them again for each model. This is a simple example, but in reality, I have the way more of them.
A simple model with the structure I have:
package Main
model Dimensions
final parameter Modelica.SIunits.Length x = 10;
final parameter Modelica.SIunits.Length y = 5;
end Dimensions;
package Test_env
extends Main.Dimensions;
model Test_model
Real z;
equation
z = x + y;
end Test_model;
end Test_env;
end Main;
If I run this example in OMEdit it works without any problem. However, if I run it in OMShell or OMPython / OMCSessionZMQ it doesn't work.
Q - maybe I am using the extends clause incorrectly? If so, what would be the alternative of declaring parameters once and reusing them in other models?
This is what I get in OMShell:
>> loadFile("D:/1.Modelica/Simulations/Main.mo")
true
>> getClassNames()
{Main}
>> getClassNames(Main)
{Dimensions,Test_env}
>> getClassNames(Main.Test_env)
{Test_model}
>> simulate(Main.Test_env.Test_model, startTime=0, stopTime=1, numberOfIntervals=500, tolerance=1e-4, method="dassl", outputFormat="mat"); getErrorString()
record SimulationResult
resultFile = "",
simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 0.0001, method = 'dassl', fileNamePrefix = 'Main.Test_env.Test_model', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
messages = "Failed to build model: Main.Test_env.Test_model",
timeFrontend = 0.0110966,
timeBackend = 0.0,
timeSimCode = 0.0,
timeTemplates = 0.0,
timeCompile = 0.0,
timeSimulation = 0.0,
timeTotal = 0.0111225
end SimulationResult;
"[D:/1.Modelica/Simulations/Main.mo:3:5-3:45:writable] Error: Class Modelica.SIunits.Length not found in scope Main.Dimensions.
[D:/1.Modelica/Simulations/Main.mo:1:1-18:9:writable] Error: Class Test_env.Test_model not found in scope Main.
Error: Class Main.Test_env.Test_model not found in scope .
Error: Error occurred while flattening model Main.Test_env.Test_model
"
And this is from OMPython / OMCSessionZMQ:
omc.sendExpression('simulate(Main.Test_env.Test_model, stopTime=1.0)')
---------------------------------------------------------------------------
{'resultFile': '',
'simulationOptions': "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 1e-006, method = 'dassl', fileNamePrefix = 'Main.Test_env.Test_model', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
'messages': 'Failed to build model: Main.Test_env.Test_model',
'timeFrontend': 0.0018766,
'timeBackend': 0.0,
'timeSimCode': 0.0,
'timeTemplates': 0.0,
'timeCompile': 0.0,
'timeSimulation': 0.0,
'timeTotal': 0.0018919}
To summarise the answers given via comments:
Use extends inside your model which will be extended.
package Test_env
model Test_model
Real z;
extends Main.Dimensions;
equation
z = x + y;
end Test_model;
end Test_env;
If all your models need the same fixed parameters it is still a good practise to add the extend to every model, so everybody knows where the variables come from.
Also compare with Modelica.Constants to see how the Modelica Standard Library defines constants. I used this to create the completed example:
package Main
model Dimensions
final constant Modelica.SIunits.Length x = 10;
final constant Modelica.SIunits.Length y = 5;
end Dimensions;
package Test_env
import Dim = Main.Dimensions;
model Test_model
Real z;
equation
z = Dim.x + Dim.y;
end Test_model;
end Test_env;
end Main;
And if you use something from a different package (here Modelica.SIunits.Length) you need to load the package. That's what your errors say with
Error: Class Modelica.SIunits.Length not found in scope Main.Dimensions.
In OpenModelica Modelica is already loaded on startup, so use loadModel(Modelica) or loadFile(...) in OMShell.
>> loadModel(Modelica)
true
>> loadFile("Path/To/Main.mo")
true
>> simulate(Main.Test_env.Test_model, startTime=0, stopTime=1, numberOfIntervals=500, tolerance=1e-4, method="dassl", outputFormat="mat")
record SimulationResult
resultFile = "C:/Users/USERNAME/AppData/Local/Temp/OpenModelica/Main.Test_env.Test_model_res.mat",
simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 0.0001, method = 'dassl', fileNamePrefix = 'Main.Test_env.Test_model', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
messages = "LOG_SUCCESS | info | The initialization finished successfully without homotopy method.
LOG_SUCCESS | info | The simulation finished successfully.
",
timeFrontend = 0.3193980510936645,
timeBackend = 0.00467019998960375,
timeSimCode = 0.001078686094233897,
timeTemplates = 0.02625684206983937,
timeCompile = 9.15578961474681,
timeSimulation = 0.2440117147112652,
timeTotal = 9.751522705140404
end SimulationResult;
>>

scipy transferfunction vs state space

I have a LTI system which I am modeling using scipy.signals. But I get different results when using TransferFunction or StateSpace.
Besides the magnitudes for both the bode plot and the step response being different, the StateSpace representation add two more zeros on the LTI system I know are not there.
I know for a fact the two descriptions should be equivalent (at least I think I do), because I re did the math several times.
Could someone please help me explain what is happening?
the for the transfer function:
from params import *
numeratorthetaact = [Kt*Jl/(L*Jl*Ja), Kt*(betal+betac)/(L*Jl*Ja), Kt*kc/(L*Jl*Ja)]
denominatorthetaact = [1.0,
(L*betac*(Ja+Jl))/(Jl*Ja) + R/L,
(Ja+Jl)*(L*kc+R*betac)/(Jl*Ja*L) + (Kt*Kb)/(Ja*L),
(R*kc*(Ja+Jl))/(L*Jl*Ja) + (betac*Kt*Kb)/(L*Jl*Ja),
(kc*Kt*Kb)/(L*Jl*Ja),
0.0]
tfact = TransferFunction(numeratorthetaact, denominatorthetaact)
sysact = lti(tfact.num, tfact.den)
print "Zeros: ", sysact.zeros
print "Poles: ", sysact.poles
t, swact = step(sysact, T = time)
freqrad = numpy.multiply(frequency, 2.0*numpy.pi)
wrad, magact, phaseact = sysact.bode(w=freqrad)
whz = numpy.multiply(wrad, 1.0/(numpy.pi*2.0))
p.subplot(3,1,1)
p.plot(t, swact, label="Step Galvo")
p.legend()
p.subplot(3,1,2)
p.semilogx(whz, magact, label="Freq Galvo")
p.legend()
p.grid()
p.subplot(3,1,3)
p.semilogx(whz, phaseact, label="Phase Galvo")
p.legend()
p.grid()
p.show()
The code for StateSpace
from params import *
matrixA = numpy.array([[-(betaa+betac)/Ja, -kc/Ja, betac/Ja, kc/Ja, Kb/Ja],
[1.0, 0, 0, 0, 0],
[betac/Jl, kc/Jl, -(betal+betac)/Jl, -kc/Jl, 0],
[0, 0, 1.0, 0, 0],
[-Kb/L, 0, 0, 0, -R/L]])
matrixB = numpy.array([[0],
[0],
[0],
[0],
[1.0/L]])
matrixC = numpy.array([[0, 1.0, 0, 0, 0]])
matrixD = 0.0
ssact = StateSpace(matrixA, matrixB, matrixC, matrixD)
sysact = lti(ssact.A, ssact.B, ssact.C, ssact.D)
print "Zeros: ", sysact.zeros
print "Poles: ", sysact.poles
t, swact = step(sysact, T = time)
freqrad = numpy.multiply(frequency, 2.0*numpy.pi)
wrad, magact, phaseact = sysact.bode(w=freqrad)
whz = numpy.multiply(wrad, 1.0/(numpy.pi*2.0))
p.subplot(3,1,1)
p.plot(t, swact, label="Step Galvo")
p.legend()
p.subplot(3,1,2)
p.semilogx(whz, magact, label="Freq Galvo")
p.legend()
p.grid()
p.subplot(3,1,3)
p.semilogx(whz, phaseact, label="Phase Galvo")
p.legend()
p.grid()
p.show()
The resulting plots:
StateSpace vs TransferFunction
It is also worth mentioning that i get a BadCoefficients: Badly conditioned filter coefficients (numerator): the results may be meaningless "results may be meaningless", BadCoefficients) error when running the StateSpace code.
Thank you