How can I encapsulate models of the fluid library of openmodelica? - modelica

Problem and Motivation:
the models of the fluid library in openmodelica are very elaborated, with a lot of parameters one has to set correctly to get the model running with acceptable results.
I want to set up an environment for daily engineering calculations, for mechanical and process engineers - no simulation experts.
So the components of my library must be pre-configured and the users shouldn't be forced to edit the code behind the graphical model (eg redeclaration of the Medium).
Idea:
drop the fluid models in own models, configure them properly, redeclare the Medium and provide fluid connectors.
model flowEncapsulateFluid1
inner Modelica.Fluid.System system;
replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater constrainedby
Modelica.Media.Interfaces.PartialMedium "Medium in the component"
annotation (choicesAllMatching = true);
model myStaticPipe
Modelica.Fluid.Pipes.StaticPipe pipe(redeclare package Medium = Medium, allowFlowReversal = true, height_ab = 2, length = 2, diameter = 0.1);
Modelica.Fluid.Interfaces.FluidPort_a port_a;
Modelica.Fluid.Interfaces.FluidPort_b port_b;
equation
connect(pipe.port_b, port_b);
connect(port_a, pipe.port_a);
model myTank1
Modelica.Fluid.Vessels.OpenTank tank1(crossArea = 1,
redeclare package Medium = Medium, use_portsData = true, height = 12,
level_start = 8, nPorts = 6,
portsData = {Modelica.Fluid.Vessels.BaseClasses.VesselPortsData
(diameter = 0.1)});
Modelica.Fluid.Interfaces.FluidPort_a port_a
(redeclare package Medium = Medium);
Modelica.Fluid.Interfaces.FluidPort_a port_a1
(redeclare package Medium = Medium);
Modelica.Fluid.Interfaces.FluidPort_a port_a2
(redeclare package Medium = Medium);
Modelica.Fluid.Interfaces.FluidPort_a port_a3
(redeclare package Medium = Medium) ;
Modelica.Fluid.Interfaces.FluidPort_a port_a4
(redeclare package Medium = Medium) ;
Modelica.Fluid.Interfaces.FluidPort_b port_b
(redeclare package Medium = Medium);
equation
connect(tank1.ports[6], port_b);
connect(port_a4, tank1.ports[5]);
connect(port_a3, tank1.ports[4]);
connect(port_a2, tank1.ports[3]);
connect(port_a1, tank1.ports[2]);
connect(port_a, tank1.ports[1]);
end myTank1;
package UnitTests
model Test1
flowEncapsulateFluid1.myTank1 myTank11;
myStaticPipe myStaticPipe1;
myTank1 myTank12;
equation
connect(myStaticPipe1.port_b, myTank12.ports_b);
connect(myTank11.ports_b, myStaticPipe1.port_a);
end Test1;
end UnitTests;
annotation(
uses(Modelica(version = "3.2.2")));
end flowEncapsulateFluid1;
I get the message "No corresponding 'inner' declaration found for component .Modelica.Fluid.System tank1.system declared as 'outer '.
The existing 'inner' components are:
There are no 'inner' components defined in the model in any of the parent scopes of 'outer' component's scope: Modelica.Fluid.Vessels.OpenTank$tank1.
Check if you have not misspelled the 'outer' component name.
Please declare an 'inner' component with the same name in the top scope.
Continuing flattening by only considering the 'outer' component declaration."
I don't know how to interpret the message. Any help would be welcome.
Furthermore I would appreciate, if some one could provide me advices or links for this project.
Many thanks in advance.

y4cine,
You could create a library of components that extend from the Modelica.Fluid components and finalize the parameters that you don't want your users to see. For example
model myPipe
extends Modelica.Fluid.Pipes.DynamicPipe(
redeclare package Medium = Modelica.Media.Water.StandardWater,
final height_ab=0,
final isCircular=true);
end myPipe;
When you instantiate the component (shown in Dymola) the parameters are not visible (see screenshot below).
Best regards,
Rene Just Nielsen

In regards to this portion of your question: "No corresponding 'inner' declaration found for component .Modelica.Fluid.System tank1.system declared as 'outer '.
outer and inner are special key words in modelica.
The fluid library defines an "outer" model called "system" located at Modelica.Fluid.System. If you drag that into a model that gives that warning the issue will go away as it will find this outer model. Typically this system model should be at a high level and not at individual components...

Related

How do I deploy GPU enabled model on HuggingFace?

I have a full stable diffusion image to image model working on Colab, powered by Gradio. However, it requries nvidia gpu. When I deploy it to hugging face spaces, a runtime error occurs:
RuntimeError: Found no NVIDIA driver on your system. Please check that you have an NVIDIA GPU and installed a driver from http://www.nvidia.com/Download/index.aspx
How do i deploy the model? Is there some other way to deploy the model, like some resources for deploying on AWS, Azure, for free.
Here's the main code of the model:
def predict(img, strength, seed, prompt):
seed = int(seed)
img1 = np.asarray(img)
img2 = Image.fromarray(img1)
init_image = img2.resize((768, 512))
generator = torch.Generator(device=device).manual_seed(seed)
with autocast("cuda"):
image = pipe(prompt=prompt, init_image=init_image, strength=strength, guidance_scale=5, generator=generator).images[0]
return image
gr.Interface(
predict,
title = 'Image to Image using Diffusers',
inputs=[
gr.Image(),
gr.Slider(0, 1, value=0.05, label ="strength (keep it close to 0 to make minimal changes to image (such as 0.1, 0.2, 0.3)"),
gr.Number(label = "seed (any number, generally 1024. But it's totally random. Change it and see different outputs)"),
gr.Textbox(label="Prompt, empty by default")
],
outputs = [
gr.Image()
]
).launch()

CRS for HS2 snakegrid plotting in wrong location on Folium and Leaflet

I've been trying to plot some geographical date which is the HS2 snakegrid co-ordinate system
According to ESPG HS2 ESPG Geodetic Parameters Page I should be using CRS 9300 (although have also tried 9306)
When used, the location is not plotting correctly, example below uses folium to generate a basemap in WGS 84 and geopandas to add a point with the CRS changed to the HS2 9300.
The co-ordinates used should place the point just outside Euston Station but instead is plotting in Hyde Park
I've used Jupyter notebooks to run the below code, although i've also run in geodjango so i could use leaflet with proj4js string for HS2 and same thing
import folium
from folium import plugins
import geopandas as gpd
from shapely.geometry import Point
f = folium.Figure()
m = folium.Map(
location=[51.5091, -0.16006],
max_zoom = 22,
zoom_start = 16,
tiles = None,
control_scale = True,
prefer_canvas = True,
crs = 'EPSG3857',
)
folium.TileLayer('cartodbpositron', max_zoom = 22, detect_retina = True, name = 'Carto',).add_to(m)
s = gpd.GeoSeries([Point(292001.0182, 288039.0657),],)
s = s.set_crs('epsg:9300')
s.explore(name = "S", m = m, highlight = True, show = False, style_kwds={'color': 'green','fill': False},)
example output
UPDATE
I need to use HS2TN15_NTv2.gsb transformation file within pyproj
Reading the pyproj docs i should use pyproj.datadir.get_data_dir() to identify the data directory which gives \Lib\site-packages\pyproj\proj_dir\share\proj
However when i then run TransformerGroup("epsg:4258","epsg:9300") I still get the following warning
\lib\site-packages\pyproj\transformer.py:184: UserWarning: Best
transformation is not available due to missing
Grid(short_name=HS2TN15_NTv2.gsb, full_name=, package_name=, url=,
direct_download=False, open_license=False, available=False)
super().init(

How to change color in networkx graph plotted with holoviews/bokeh?

How can I change the color of individual nodes in the following example?
%pylab inline
import pandas as pd
import networkx as nx
import holoviews as hv
hv.extension('bokeh')
G = nx.Graph()
ndxs = [1,2,3,4]
G.add_nodes_from(ndxs)
G.add_weighted_edges_from([(1,2,0), (1,3,1), (1,4,-1),
(2,4,1), (2,3,-1), (3,4,10)])
hv.extension('bokeh')
%opts Graph [width=400 height=400]
padding = dict(x=(-1.1, 1.1), y=(-1.1, 1.1))
hv.Graph.from_networkx(G, nx.layout.spring_layout).redim.range(**padding)
The graph as you currently define it does not define any attributes but you could still color by the node index. To color by a particular node attribute you can use the color_index option along with a cmap. Here's how we would color by the 'index'
graph = hv.Graph.from_networkx(G, nx.layout.spring_layout)
graph.options(color_index='index', cmap='Category10').redim.range(**padding)
If you do have attributes defined on the nodes the next version of HoloViews (1.10.5) due to be released this week will be able to extract them automatically and let you use the same approach to color by those variables.
If you want to manually add node attributes until the next release you can pass in a Dataset with a single key dimension defining the node indices and any attributes you want to add defined as value dimensions, e.g.:
nodes = hv.Dataset([(1, 'A'), (2, 'B'), (3, 'A'), (4, 'B')], 'index', 'some_attribute')
hv.Graph.from_networkx(G, nx.layout.spring_layout, nodes=nodes).options(color_index='some_attribute', cmap='Category10')
Thanks to Philippjfr, here is a nice solution (using the current development version of holoviews) that uses node attributes for coloring:
%pylab inline
import pandas as pd
import networkx as nx
import holoviews as hv
hv.extension('bokeh')
G = nx.Graph()
ndxs = [1,2,3,4]
G.add_nodes_from(ndxs)
G.add_weighted_edges_from([(1,2,0), (1,3,1), (1,4,-1),
(2,4,1), (2,3,-1), (3,4,10)])
attributes = {ndx: ndx%2 for ndx in ndxs}
nx.set_node_attributes(G, attributes, 'some_attribute')
%opts Graph [width=400 height=400]
padding = dict(x=(-1.1, 1.1), y=(-1.1, 1.1))
hv.Graph.from_networkx(G, nx.layout.spring_layout)\
.redim.range(**padding)\
.options(color_index='some_attribute', cmap='Category10')

Modelica Standard Library component AbruptAdaptor

Tested with:
MSL Versions:
3.2.1, 2013-08-14, build 2 (2013-08-14 08:44:41Z)
3.2.1, 2013-08-14, build 4 (2015-09-30 09:15:00Z)
Below is a model with 4 components:
Mass flow source (M_bound)
AbruptAdapter (abruptAdapter)
Dynamic Pipe (pipeSmall)
Pressure Source (P_bound)
Two connection cases of the model are also contained in the equation section:
Case #1: M_bound -> abruptAdaptor -> pipeSmall -> P_bound
Case #2: M_bound -> pipeSmall -> abruptAdaptor -> P_bound
Summary: Case #1 simulates fine but Case #2 fails. The error generated is shown below:
The following error was detected at time: 0
Model error - division by zero: (data.zeta1) / ((if data.zeta1_at_a then rho_a_des*A_a^2 else rho_b_des*A_b^2)) = (0.402964) / (0)
The stack of functions is:
Modelica.Fluid.Fittings.BaseClasses.QuadraticTurbulent.pressureLoss_m_flow_totalPressure
Modelica.Fluid.Fittings.BaseClasses.QuadraticTurbulent.pressureLoss_m_flow_totalPressure(
-pipeBig.port_b.m_flow,
abruptAdaptor.state_a.d,
abruptAdaptor.state_b_des.d,
abruptAdaptor.state_b.d,
abruptAdaptor.state_a_nondes.d,
abruptAdaptor.data,
abruptAdaptor.m_flow_small)
First evaluation failed for non-linear solver.
Question: Why does Case #2 fail and recommendations on how to fix it? Any insight would be great. It may even be a bug in the AbruptAdaptor component.
Model Code
model AbruptAdaptor_1Pipe
replaceable package Medium = Modelica.Media.Water.StandardWater;
inner Modelica.Fluid.System system;
Modelica.Fluid.Sources.Boundary_pT P_bound(
redeclare package Medium = Medium,
nPorts=1,
p=system.p_ambient,
T=M_bound.T);
Modelica.Fluid.Sources.MassFlowSource_T M_bound(
redeclare package Medium = Medium,
m_flow=1,
T=300,
nPorts=1);
Modelica.Fluid.Fittings.AbruptAdaptor abruptAdaptor(
redeclare package Medium = Medium,
diameter_a=1,
diameter_b=0.5,
m_flow_nominal=M_bound.m_flow,
m_flow_start=M_bound.m_flow);
Modelica.Fluid.Pipes.DynamicPipe pipeSmall(
redeclare package Medium = Medium,
T_start=M_bound.T,
m_flow_start=M_bound.m_flow,
length=1,
diameter=0.5,
modelStructure=Modelica.Fluid.Types.ModelStructure.av_b); // switch to av_vb with case #2
equation
// Case #1
connect(M_bound.ports[1],abruptAdaptor.port_a);
connect(abruptAdaptor.port_b,pipeSmall.port_a);
connect(pipeSmall.port_b,P_bound.ports[1]);
// Case #2
//connect(M_bound.ports[1],pipeSmall.port_b);
//connect(abruptAdaptor.port_b,pipeSmall.port_a);
//connect(abruptAdaptor.port_a,P_bound.ports[1]);
annotation (uses(Modelica(version="3.2.1")));
end AbruptAdaptor_1Pipe;
your staggered grid is fine, you set volumes where you had to.
Don't worry, it's not your fault, is a debug, I tried to use it several times, and it always fails in one of the ways (I don't know the position of your adaptor, but it doesn't really matter). You can always use orifices where you define the relations dp(Areas_rate), avoiding reversal flows in both cases, so connecting two volumes before and after the orifices (like two valves in parallel).
That should work.

Using a Private Property directly vs using Get and Let/Set

Beginner VBA programmer here (and beginner to programming in general) looking to learn more about how effective OOP is done.
Can someone explain or provide a reference discussing the benefits/purpose of using - INSIDE of a class module - Private Property Get and/or Let/Set statements in VBA vs accessing properties directly although no manipulation is required of the data?
Example:
I have created a cDimension class (in Excel). This class draws lines as Shape objects, and a few other things that are not relevant. The DrawingScale variable allows the entire drawing to be scaled as desired. Some of the properties require manipulation when Getting/Setting, others don't.
So, for example, pWidth needs to be scaled going in:
'clsDimension
Private pWidth As Single
Private Property Get Width() As Single
Width = pWidth
End Property
Private Property Let Width(w As Single)
pWidth = w / DrawingScale
End Property
But pColor does not require any manipulation, in or out:
Private pColor As Integer
Private Property Get Color() As Integer
Color = pColor
End Property
Private Property Let Color(c As Integer)
pColor = c
End Property
The pWidth property is an instance where using the Private Property Get and Let methods for procedures inside of the class itself makes sense to me. However, my question is: is there any reason to also use Private Property methods to Get and Let/Set the pColor property as well, as I have given them above?
Public Function Line(sht As Worksheet, L As tLine, Optional c = vbBlack) As Shape
Width = DistanceBetweenTwoPoints(L.first.x, L.first.y, _
L.second.x, L.second.y) '<-- pWidth is scaled
Color = c '<-- Vs. just using pColor = c
Set Line = sht.Shapes.AddLine(L.first.x, L.first.y, L.second.x, L.second.y)
End Function
Thanks in advance.
If you are not manipulating the values on the way in or way out, just use public variables. VBA is more like Python than Java or C++ in that there is no real penalty for switching from public variables to "getter/setter" functions down the road.
Let's say you start with the following code:
'clsCar
Public Speed As Double
Public Sub Drive()
MsgBox "Driving at " & Speed & " MPH"
End Sub
'Module1
Sub DriveCar()
Set Car = New clsCar
Car.Speed = 100
Car.Drive 'shows msg: "Driving at 100 MPH"
End Sub
Then you decide that driving that fast is dangerous, so you want to add a "governor" to your vehicle and need to update your class:
'clsCar
Private mSpeed As Double
Private Const SpeedLimit As Double = 55
Public Property Get Speed()
Speed = mSpeed
End Property
Public Property Let Speed(Val As Double)
If Val > SpeedLimit Then
mSpeed = SpeedLimit
ElseIf Val < 0 Then
mSpeed = 0
Else
mSpeed = Val
End If
End Property
Public Sub Drive()
MsgBox "Driving at " & Speed & " MPH"
End Sub
'Module1
'Note that no changes to this code are necessary; the change
' is entirely encapsulated within the class (as it should be)
Sub DriveCar()
Set Car = New clsCar
Car.Speed = 100
Car.Drive 'shows msg: "Driving at 55 MPH"
End Sub
Tim Williams's comment is what you will often hear as justification for unnecessarily using Get/Let/Set in VBA, but that's the byproduct of good advice from other languages (C++ and Java, notably) being misapplied to VBA/VB6.
As always.... it depends. Your x property should definitely be accessed via the letter because the letter performs a calculation on the input.
'clsDimension
Private Let Width(w As Single)
pWidth = w / DrawingScale
End Property
You should NOT access the pWidth variable directly. If you did, you would have to duplicate the pWidth = w / DrawingScale logic elsewhere in your module.
Your pColor property could be a public variable, because there's no logic in getting or setting it. I don't recommend it though. What if later you realize you don't want to allow certain colors? Then you would need logic behind it and you would need to switch to a property anyway. The property is easier to maintain and more semantically correct.
The value I see is reduced code, which you are not taking advantage of in your sample code. You could replace this:
'clsDimension
Private pWidth As Single
Private Property Get Width() As Single
Width = pWidth
End Property
Private Property Let Width(w As Single)
pWidth = w / DrawingScale
End Property
with this:
'clsDimension
Private Property Get Width() As Single
Width = w / DrawingScale
End Property
This eliminates the potential ambiguity of accessing pWidth or the width property since pWidth no longer exists. It also eliminates the potential pitfall of Width being read before it has been written, although it would be wise to add a bit of code that checks that w and DrawingScale have been set to valid values before you read Width.