Modelica - join connectors after some distance
In modelica I need to connect two spaces and pass an object, lets say a ball, between them after some distance. In my example I have two spaces one which is free space (no forces) and suddenly we enter near earth space (gravity) which acts on the ball. I need to be able to pass the ball from the开发者_JAVA技巧 first space to the second but I can't get it. Here is a minimal example.
model Ball
Real[2] position;
Real[2] velocity;
parameter Real mass=1;
equation
der(position) = velocity;
end Ball;
connector Flange
Real p;
flow Ball b;
end Flange;
model FreeSpace
Ball ball;
parameter Real length;
Flange f;
equation
// need to do something, probably here, to end the first space when ball is at length
end FreeSpace;
model NearEarth
extends FreeSpace;
parameter Real[2] g={0,-9.8};
equation
der(ball.velocity) = g;
end NearEarth;
model PassBall
FreeSpace free(ball.velocity={5,0},ball.position={0,10});
NearEarth near;
equation
connect(free.f,near.f);
end Equation;
Perhaps I am doing something very wrong, but this is where I am. (In the real problem I have an electron pulse propagating through spaces which inherit from a FreeSpace, but have different forces acting in each.) Any suggestions would be great!
If I understand your goal, you want to have two different "environments" and then pass objects between these two environments?
This is problematic in Modelica. Modelica is designed for systems that have static topologies. By this I mean that all connections are present at the start of the simulation and no connections are added or removed during the simulation. Of course, it would be nice to have more dynamic features, but things can quickly become overwhelming if you add too many features/capabilities.
As to your issue, one thing you can do would be to have a FreeSpaceInteraction class to describe the interaction between the ball and a FreeSpace object and a NearEarthInteraction class to describe the interaction between the ball and the NearEarth object. Then you can have a boolean signal to both indicating which should be active at any given time (based on distance).
I could work out an example if you'd like. A very similar example is present in "Introduction to Physical Modeling with Modelica" (if you have a copy) that involves planets and gravitational attraction. One issue that occurs there is that you get into some combinatorial issues when you have lots of bodies all acting on one another.
Updates:
Joel, Google Books is your friend here. I did a search of "Modelica gravity Tiller" and came up with this link. I hope it works for you. If not, let me know and I can try and paste a copy of the model in here.
Glad to hear UI had my book...that's where I got my Ph.D. I'd like to think it was because I was an alum, but I doubt it.
The key to this is that you have "FixedSpace" has-a "Ball". That isn't the way I modeled it (because the has-a relationship would be transient). In the orbital model, I create a "solar system" which has a bunch of "planets" and then I create a whole network of many-to-many "gravitational pull" objects connecting everything to everything. For your case, you might want to create a similar "forces" kind of object and connect it the ball and each environment and then have it figure out how it could behaves based on its position. That is at least, conceptually, one way to do it.
I'm not Prof. Tiller but I do have some experience in modelling with Modelica too.
If I understood you right, you wish to simulate the movement of a ball in a two-dimensional plane, which consists of two domains: zero-g space, and gravitational field centered around a planet on the plane.
The following variables describe the movement of the ball both within the zero-g space as well as within the gravitational field:
- Real[2] velocity
- Real[2] position
- Real[2] acceleration
Then you have a constant parameter which describes where earth is located:
- parameter Real[2] positionEarth
You also need a parameter which describes how far out the gravitational field extends, and how strong it is:
- parameter Real radiusGravField
- parameter Real gravConstant
Now you can write equations for the movement of the ball in both domains, where the acceleration acting on the ball may be computed by different expressions, depending on where in the plane the ball is:
model grav
import Modelica.Math.Vectors.*;
Real[2] velocity(start={-1,-0.9});
Real[2] position(start={5,5});
Real[2] acceleration;
parameter Real[2] positionEarth={0,0};
parameter Real radiusGravField=2;
parameter Real gravConstant=10;
equation
der(position) = velocity;
der(velocity) = acceleration;
if norm(positionEarth - position, 2) > radiusGravField then
acceleration = {0,0};
else
acceleration = gravConstant/norm(positionEarth - position, 2)^2
* normalize(positionEarth - position);
end if;
end grav;
The switching from one domain to the other is detected automatically, and the right equations are applied without you needing to specify any transfers.
You can add actions to happen at discrete events like this:
when norm(positionEarth - position, 2) < radiusGravField/1000 then
terminate("Simulation over, crashed on planet");
end when;
精彩评论