Running a symmetrical simulation

I am currently trying to form find a (symmetric) inflated shape. In order to speed up the simulation and experiments I thought it would be sensible to to only simulate the “unique” part, apply necessary boundary conditions and then mirror the result afterwards.
It kind of works, however at the “mirror seams” there is a small unwanted kink (marked with the red arrow). Is there something that I am missing? From my understanding I would expect the final shape to be exactly the same as the fully simulated version. I attached the most simple example with an ellipsoid.

Any ideas?

Thanks a lot,
Rudi


simulation_mirror.3dm (3.7 MB)
simulation_mirror.gh (24.2 KB)

1 Like

Hi @rudolf.neumerkel,

Simulating the spheroid as a whole or an eighth of it simply isn’t the same and that’s why you get the slightly inset seam loop, where you’re joining the individual parts after inflation.

You see the spheroid as a whole is a pneu (“Luftkissen”), a system enclosed by a hull and filled usually by a fluid (i.e. gas or liquid). Its surface tension (m = innerpressure * radius / 2) is the same for each point on the hull, which results in the spheroid shape in the first place. It’s a purely tension-based system (“zugbeanspruchtes System”).


Soap Bubble


Ark Nova, Matsushima, Japan, 2013

On the other hand, an eighth of it represents only a surface, not a solid, which in reality corresponds more to something like a net, tent, or membrane, which is also exclusively tension-based, but not because of its inner versus the outer pressure.
What you basically do by configuring a situation for its naked edges is produce a tension-based membrane with tensile-stressed edges (“druckbeanspruchter Rand”), which yields a different result than a pneu with no support whatsoever.


Native American Indian Teepee


Raleigh Arena Roof, North Carolina, USA, 1953

That said, you should in theory be able to accomplish this by dialing all the values in very carefully, but what’s the point of the simulation then, if you fake it so to speak?

Also, I’m no expert, but that’s how I understand it. :wink:

4 Likes

Hi @rudolf.neumerkel - it’s a good question with a simple answer:

Give the edges along the symmetry seam 0.5 times the strength of the internal edges.

Then simulating a fraction of it and mirroring gives you exactly the same result as simulating the whole thing.

simulation_mirror.gh (31.5 KB)

If you think about it, when mirroring, the edges right on the symmetry plane are effectively getting counted twice in the simulation, so without adjustment they are too strong relative to the other surrounding edges, giving that kink you saw. Halving their strength exactly counteracts this.

I’ve used the same approach to model periodic minimal surfaces with translation or reflection symmetry

Pressure is triangle based, and all triangles are unambiguously on one side or the other of the symmetry plane, so no need to do anything different there.

(as a separate issue though - you may want to triangulate your mesh using WbStellate, to avoid introducing any diagonal bias, since all quads get triangulated for pressure, and the default triangulation could introduce a bias)

It’s not really correct what @diff-arch says, sorry.
You can use the pressure goal to simulate a pressurized closed shape without actually modelling the whole shape.
Here you are setting the pressure, but if instead you were setting the volume, you could still use the symmetry, you’d just need to make sure the intersection of the symmetry planes went through the origin.

The SoapFilm goal is triangle based, so can also be mirrored without adjustment.
Other goals which act on different sets of points need slightly different treatment though.

For instance Smooth and TangentialSmooth act on a vertex and its neighbours, so you’d need to consider the case where the neighbours are on the other side of the symmetry plane.
Similarly with the Hinge goal, you need to consider the case where the hinge is actually on the symmetry plane.
For these you sometimes need to include one row of vertices beyond the part you are mirroring, then use the Transform goal to lock them to their matching vertex on the other side.

5 Likes

symmetry_inflate.gh (74.6 KB)
4 Likes

No need to apologize, but I didn’t exactly say that he couldn’t do it, just that in reality there is a difference between closed pneus and tensile-stressed membranes. I even mentioned that by dialing in the Kangaroo values this could probably be done. :wink:

Thanks for your exaplanation, concerning the simulation though! Very interesting!!

I think maybe you’re still a bit confused - a closed pneu is a tensile stressed membrane, just that in addition to any boundary cables or constraints, you have a force normal to the surface pushing it outwards.
This pressure tries to make the shape expand, which is resisted by the tension of the membrane.

(note also that in Rudi’s symmetrical simulation the boundary curve is kept on the symmetry plane, but free to move on that plane, so it’s not like having a fixed boundary. The resulting shape is exactly the same as what you get when you simulate the whole thing at once.)

It’s not about any mysterious extra ‘dialing in’ of values - you have boundaries pulling the surface out, pressure pushing it out, and the tension of the membrane resisting both of these.

Now there is still a difference between using only 1D spring tensions in mesh edges vs triangle area based elements like the soap film for tensile membranes, but that’s the same whether you have pressure or not.
(area based elements are the way to get true minimal surfaces, or CMC surfaces when you have pressure, while using only mesh edges gives more of an approximation, and the quality of the approximation depends on how even the mesh is).

1 Like

Yeah, that’s a state I’m constantly in. :slight_smile:

Yes, that’s basically what I meant. You can just express yourself much better than I can!

Yes, that’s what I misunderstood!

Got it.

Interesting! Meshes seem to be an approximation of everything, except themselves. :smiley:

1 Like

@DanielPiker @diff-arch, thank you for your elaborate answers! :pray:t3:

What a beautiful and logical solution… made my day! :rocket:

Is the Pressure component triangle based in order to get a single identifiable normal vector per face - which could not be the case with a non-planar quad?

Makes sense! So you are saying that one should always use a “isotropic triangulation” in order to get accurate membrane behavior right?
In the file you sent back it seems, that edge lengths vary. As the pressure component is area based, my guess is, that this doesn’t matter?

Why is the Pressure component based on springs while the Soap Film component is based on triangle area?

Lots of questions, I know - but I am very curious…

2 Likes

Yes, exactly.

The pressure goal and soap film goal both operate on whole triangles, not just individual edges like springs. So they are less affected by the mesh quality, since a larger triangle produces force proportional to its area.

Your simulation has the membrane tension simulated with edge springs.
In theory this is less accurate than using the area based soap film elements, but unless the mesh is really uneven, the difference is actually pretty tiny.

I made a quick test of relaxing a cube while keeping the volume fixed with different combinations of meshing and goals to simulate the tension. Here we know the correct result is a sphere.
shown from left to right they are:

  • default (asymmetric) triangulation, 1d springs
  • symmetrical triangulation, 1d springs
  • remeshed, SoapFilm (area based, topology stays the same during simulation)
  • remeshed, LiveSoap (area based, topology updates with edge flips during simulation)

I was actually surprised how little difference it makes. Although in theory the left is least accurate and the right is most accurate, even for the worst one with asymmetric triangulation and 1d elements, the biggest difference from the sphere is still only about 1% of the radius.

The difference will probably be more apparent on some different shapes though. Also, here the membranes all have zero rest area (or zero length for the spring ones). Using a non-zero rest length would probably show more of a difference.

3 Likes

Get it, thanks a lot!

My guess is also, that the Area/Length minimization prevents the shape from becoming unnecessarily uneven - thus all of them converge to spheres…

Thank you for sharing your insights! This is a very interesting topic and I will very probably have many more questions… :coffee:

btw so happy that this works, as it increases performance for my simulations by 6-8 times! :rocket::rocket::rocket:

1 Like

Incredible how you already answered a future problem of mine in your first response… After the inflation (form finding), I am now trying to deflate and fold the shape agaiin.

I tried to fix it by following your steps mentioned above:

  • extended the initial quad-mesh (dont know how achieve this in a simple way with the triangulated mesh)
  • extracted the point pairs and applied the Transform Force with the mirror transformation with the corresponding plane
  • applied smoothing onto the extended mesh

results are looking much better now, however I am not sure if this is 100% correct, as the transform force and the smoothing seem to stabilize the mirrored edge a bit and thus resulting in small hills at the border…

1 Like

in order to prevent self intersections during deflation, I am also using the Sphere Collide component. Setting the shortest edge length of the mesh as the sphere diameter works, but the spheres become too small:

So I thought, looking for the shortest connected edge to each individual vertex and taking it as the diameter for each respective sphere would make more sense.

It looks as if it should work, however running the simulation with those individual diameters slows Kangaroo down a lot and does not yield any results, as the Sphere Collider seems to create lots of self intersections…

Any ideas why this is the case?

deflation.gh (187.2 KB)

1 Like

@DanielPiker I tried to narrow down the problem:

There seems to be an issue when a list of radii is connected to the sphere collision component.

This is the first approach using different radii - one would mean that this should work perfectly.

However this is the simulatino result:

Assuming that the issue lies with the radii list, i created the average of the radii list (=single value):

and ran the simulatin again:

Although there are now a lot of sphere collisions, which did not exist before - the results looks much better and exactly as it should.
Furthermore, attaching a list of radii a slows down Kangaroo immensely, going from around 30-50ms per iteratino to more than a second.

Is there some bug here, or are adaptive radii just not supported?

sc_problem.gh (105.9 KB)

Thanks a lot,
Rudi

Hi Rudi,

Thanks for narrowing it down - I did open your earlier definition, but there was a lot to look through.

Here the issue is that SphereCollide uses all the same radius - so by giving it multiple radii, you were actually duplicating the entire set of collisions for every value.

The Goal which does support different radii is Collider

1 Like

Beautiful, will try it out immediately!

Having the Transform boundary condition and the Smooth goal applied to the quad mesh and the actual fabric simulation in the subdivided triangle mesh seems to introduce some sharp kinks in some places where the “Smooth resolution” is not sufficiently high enough. I guess going with a full triangle mesh approach is the solution? (haven´t figured out yet how to apply the Transform with triangulated meshes…)

Totally understand - thats also why I thought it would be very useful to narrow the issue down.

There is a thing about simulating / form-finding inflated shapes, that I did not quite understand yet: What role does the initial coarse mesh play in regard to the final inflated result?
As we could see above, it is even possible to form find a sphere from a coarse cube.
Are there maybe issues with edge length variations which could cause inhomogeneous contractions in the final result, as Length(Line) or EdgeLengths are probably being used?
Are there certain things that should be taken care of?

Hi @rudolf.neumerkel
Sorry for taking a while to get back to you on this.
Regarding the edge lengths - if you want to model a material which stretches very little, you should use the actual lengths of the lines as their rest length (which is the default behaviour if you do not give any input to the LengthFactor input of EdgeLengths, or the Length input of Length(Line)), and have their strength high relative to the pressure.
The mesh also needs to be triangulated so it resists shear.
Doing this it relaxes to a shape like this instead of stretching all the way into a sphere (like it does when using zero rest length or soap film elements).


inflate_cube.gh (8.3 KB)

2 Likes

@DanielPiker, thanks a lot for your answer Sir!

This is, what I also did in order to check/proove that a certain shape is actually an inflatable geometry - if you apply this to a form-found shape, there should not be any noticeable movement (?).

What I actually meant, was: What role does the mesh play in terms of form-finding? Certain boundary conditions, such as pressure, supports, maybe material behavior are given and a fitting solution is looked for. In order to start the simulation some coarse mesh has to be created, which is then subsequently relaxed - and this part is where my question lies: Can this initial mesh be any mesh? Or should it maybe approximate the final geometry as much as possible?

Also just for completeness of understanding: should the mesh you are simulating here be triangulated first? Or do you think that, the difference would only be very small?

Again, thanks a lot for this valuable discussion!

Hi Rudi,

For any tensile structure (with or without pressure), you generally want all parts of the mesh in tension, and the form-finding is a way of achieving this. If you are using springs, as long as the rest length is low enough, the relaxed form will be all in tension. One easy way of guaranteeing this is to give them all a rest length of zero.
Using non-zero rest lengths can give you more ways of controlling the shape, but you need to be careful that none of them end up in compression because this would result in slack areas in the resulting structure (you can also use ClampLength to create springs with non-zero rest length which act only in tension).

You can get different results for the same boundary conditions by using different meshing or tension parameters, and triangulating or not.
In general the result of this form-finding will have varying tension across the mesh, unless you use soap film elements to specifically target a constant tension surface (a constant-mean-curvature surface when there is pressure, or zero-mean-curvature (i.e. minimal) surface when there is not).

Non constant tension isn’t necessarily a problem - many built tensile structures don’t form strictly minimal surfaces, but I think it can often be good to stay reasonably close to it to avoid stress concentrations.
If you start the relaxation from a fairly isotropic triangular mesh that approximates the final form fairly well, then the difference between using zero length springs vs soap film elements will be small.

After the form-finding, if you then run a simulation with the form-found shape as the rest geometry, and it should change very little if the material is not very stretchy.
You can also even calculate the pre-tension from the form-finding to find the slightly reduced rest geometry so the shape doesn’t change at all when you simulate (see this example for how to do this for zero-rest length springs).

2 Likes