smenon / dynamicTopoFvMesh

Parallel Adaptive Simplical Remeshing for OpenFOAM
http://smenon.github.com/dynamicTopoFvMesh/
37 stars 20 forks source link

sixDoF problems #4

Closed robertsawko closed 10 years ago

robertsawko commented 10 years ago

Hello Sandeep,

together with a colleague of mine we're trying to run your port on 2.2.x with sixDoFDisplacement boundary condition.

We run in two configurations with and without usePointDisplacement.

a) Without usePointDisplacement in mesquiteOptions

In this case we're providing boundary setup in mesquiteOptions. We can see that the code works, velocities get recalculated, mesh moves etc, etc. But for the purpose of mesh movmemt only the initial value of velocity and angular momentum is used. We believe that this is tied to the fact that in this configuration sixDoF is essentially being reconstructed on each time step. This is evident here

            autoPtr<pointPatchField<point> > pField
            (
                pointPatchField<point>::New
                (
                    pMesh.boundary()[patchI],
                    dPointField,
                    fvpDict.subDict(fixPatches[wordI])
                )
            );

            pField().updateCoeffs();

b) With usePointDisplacement

something goes seriously wrong when moving from one time step to another. When we print the fields it looks that boundaryField of pointVectorField is somehow lost. This usally results in errors of this form

#0  Foam::error::printStack(Foam::Ostream&) at ??:?
#1  Foam::sigSegv::sigHandler(int) at ??:?
#2   in "/usr/lib/libc.so.6"
#3  Foam::GeometricField<Foam::Vector<double>, Foam::pointPatchField, Foam::pointMesh>::GeometricBoundaryField::writeEntry(Foam::word const&, Foam::Ostream&) const at ??:?
#4  Foam::GeometricField<Foam::Vector<double>, Foam::pointPatchField, Foam::pointMesh>::writeData(Foam::Ostream&) const at ??:?
#5  Foam::regIOobject::writeObject(Foam::IOstream::streamFormat, Foam::IOstream::versionNumber, Foam::IOstream::compressionType) const at ??:?
#6  Foam::objectRegistry::writeObject(Foam::IOstream::streamFormat, Foam::IOstream::versionNumber, Foam::IOstream::compressionType) const at ??:?
#7  Foam::objectRegistry::writeObject(Foam::IOstream::streamFormat, Foam::IOstream::versionNumber, Foam::IOstream::compressionType) const at ??:?
#8  Foam::Time::writeObject(Foam::IOstream::streamFormat, Foam::IOstream::versionNumber, Foam::IOstream::compressionType) const at ??:?
#9  

You can suppress that by specifying that this is not written to the file, but this will result in further errors which are tied to missing boundaryField.

We would appreciate your advice on how to fix that issue. In theory this should be made to work in a smilar fashion like pointDisplacementMotionSolver from standard distribution, but somehow we were unable to find the difference that makes one code pass pointDisplacement BCs to the next time step.

Thanks, Robert

smenon commented 10 years ago

Robert,

About the two situations:

(a) I understand your predicament, and I can see why it doesn't work like you expect it to. Perhaps you could work around this problem for the moment by modifying the dictionary entry explicitly at run-time, so that pField creates a new patch with updated values at each time-step? The alternative is to have a permanent pointer to a pointField (similar to the usePointDisplacement approach) which handles mapping,etc automatically through the objectRegistry. If you have a better suggestion, I'd be open to it.

(b) Do you see the seg-fault only when topology-changes are involved? If so, then it's likely that the fields are not being mapped automatically from the object registry. If you set the objectRegistry debug flag (or whatever it is that prints out the current field being mapped in MapGeometricFields), you should be able to tell whether the mapping takes place.

Thanks, Sandeep

robertsawko commented 10 years ago

Thanks for the reply.

For now I was investigating only (a). I think that the workaround with the dictionary is inelegant but should be the easiest thing to do for now and see if this is really the problem. Unfortunately I do not know how to write an entry in the dictionary. I've been playing with the documentation for a while and could only figure out clearing.

pField().updateCoeffs();                                                                                 
Info << fvpDict.subDict(fixPatches[wordI]) << endl;
Info << fvpDict.keys()[0] << endl;                                                                       
fvpDict.subDict(fixPatches[wordI]).clear();                                                              
fvpDict.add(fvpDict.keys()[0], pField());

0 is there just tentatively to address the BC I'm interested in. add does not work in the way I was hoping. At least not with that invocation. It seems I am only achieving the clearing of the subdictionary and the case crashes on the next construction as my subdict is empty.

I've already tried the alternative solution to (a) and tried a couple of things. I tried changing your motion solver to displacementMotionSolver and in a separate effort just add the pointField. In all the cases BCs are lost somehow on transition between time steps in the same way as in (b). This is strange as displacement motion solvers in standard OF do not experience this even though topology can change there too (see floatingObject tutorial). The solvers are too different for me to spot what's causing this, but objectRegistry is almost definitely involved.

I am still confident there should be an easy fix to this and it would extend potential applications a lot.

robertsawko commented 10 years ago

I have temporarily stopped my pursuit of (a) and looked again into (b). It looks to me that the reason for disappearing pointDisplacement BCs is a part of code in resetMesh in dynamicTopoFvMesh.C. More precisely the lines 3964-4407. It's more than 400 lines of code so it will take me a while to understand but if you have any idea what can go wrong there, I would appreciate some advice.

robertsawko commented 10 years ago

Apologies for bumping this thread in this fashion, especially over weekend. I just noticed that commenting out

        polyMesh::resetPrimitives
        (
            xferCopy(preMotionPoints),
            xferMove(faces),
            xferMove(owner),
            xferMove(neighbour),
            patchSizes_,
            patchStarts_,
            false
        );

in resetMesh of dynamicTopoFvMesh object solves the problem of disappearing boundaries in pointDisplacement. Then 6DoF works properly - I can see angularMomentum and velocity being changed. But the dynamic mesh doesn't adjust in quite the same way.

Can you make any suggestions on how to invoke resetPrimitives so that the pointDisplacement BCs are intact?

smenon commented 10 years ago

Robert,

Unfortunately, that line is quite important - it resets the polyMesh with the new set of points, faces and cells, as well as the boundary patches. It isn't immediately clear to me what might be going wrong. Have you tried the objectRegistry debug suggestion? Also, maybe you can print out the pointField boundaries after the mesh.update() call, and see if the point patch sizes are consistent with the mesh?

Clearly, you're seeing a seg-fault because the underlying mesh patch changed in topology, but the field associated with it wasn't mapped automatically from the registry. If all else fails, perhaps you could send me a small sample case that can quickly reproduce the problem, but I can't promise to look at it soon.

Thanks, Sandeep

robertsawko commented 10 years ago

Again, thanks for the advice. Didn't know about debug switches in etc/controlDict. I played a little bit with it, but couldn't learn much more. I looked up MapGeometricFields and this

if (polyMesh::debug)
{
   Info<< "Mapping " << field.typeName << ' ' << field.name()
         << endl;
}

suggests to me that it is polyMesh flag that should be set, but after setting the flag and resourcing I cannot see anything particularly informative. The above message does not show up.

It would be great if I could send you the case but would like to work on it a little bit more before I do this. At the moment I cannot work on this problem continuously so I only look at it in free time. I am surprised though that my case is anything special. Have you not seen this issue before with Port 2.2.x and usePointDisplacement? I am also surprised that pressure and velocity field get mapped but not pointDisplacement.

smenon commented 10 years ago

The pointDisplacement support was a very recent addition, and is completely untested, so I'm not surprised that you see these issues. Since all my previous work involved fixed displacement boundary conditions, the existing code worked well for my purposes, and I decided to slowly incorporate these changes to make it applicable for things like 6DOF. As you can see, we're not quite there yet. The mapping of pointFields has been a pretty thorny issue, and probably requires some walking through the code to figure out what's going on.

robertsawko commented 10 years ago

Hello Sandeep,

sorry for being out of touch for a bit. I was on short holidays and came back today.

So I implemented a nasty filesystem workaround saving the state of updated pointPatchField and rereading it at next time step. I am glad to report that this works fine for our purposes and could be extended to multiple boundaries relatively easy, but I wouldn't like to leave like this. The filesystem is used unnecessarily.

Here's a 2D animation of what we're trying to achieve. It's supposed to mimic a valve in some conduit. https://dl.dropboxusercontent.com/u/13129740/valve.mpg

The domain is short as this was for testing only. The valve, initially stationary, is pushed only by flow induced torque but should be balanced by torque due to gravity. The centre of mass and fixedPoint are closer to the top wall to break the symmetry. Our qualitative expectation is that for slow flows there will be an equilibrium position or a slight oscillation.

I am also attaching here a basic case setup on a slightly longer domain. https://dl.dropboxusercontent.com/u/13129740/valve.tar.gz

I would like to help you develop pointDisplacement handling, but I underestimated the size* of your code and I don't think I know enough about low-level OpenFOAM meshing to be of any use. However, if you have any suggestions at what I could look, I will definitely find the time to do some debugging or code reviewing and testing. We will probably need this to work in 3D and with EdgeRefinement. It may turn out a gargantuan task, but maybe I can engage one PhD student and one post-doc here to work on it.

smenon commented 10 years ago

Interesting.. So I presume the 2D case uses dynamicTopoFvMesh with a fixed displacement? Or is this done with sixDOF using the hack you implemented?

Thanks for providing a test case that I can work with - possibly sometime on a weekend.

robertsawko commented 10 years ago

Yes, this is the hack. So the acceleration and torque change. I already got some results where the valve vibrates.

Thanks, looking forward to hear from you then.

smenon commented 10 years ago

Hello Robert,

I made a few recent fixes (although still a work in progress), and the Port-2.3.x branch now works with the test case you provided me with, using the pointDisplacement approach. You'll have to use OpenFOAM-2.3.x, of course. It still has some issues with edge-refinement, so I'll look into that next.

robertsawko commented 10 years ago

Hello Sandeep,

thanks for fixing this. Works like charm now. Sorry for the later reply - we had to move to 2.3.x and do some adjustments for our 6DOF as the dictionaries don't look exactly the same. We will be testing it without edgeRefinement, but may need it some time in the future, so it would be great if we could ask you for help again.

smenon commented 10 years ago

Hello Robert,

I've made an additional bug-fix (related to a motionSolver update), and now edge-refinement works as well. I used the following settings on the case you provided me:

edgeRefinement      on;

refinementOptions
{
    bisectionRatio  2.0;
    collapseRatio   0.5;
    growthFactor    1.05;

    fixedLengthScalePatches
    {
        GEOM        0.02;
    }

    freeLengthScalePatches
    {
        OUTLET;
        INLET;
        TOPWALL;
        BOTTOMWALL;
    }
}

maxModifications   100;

And I managed to get some decent results, although the flow-field is a bit diffused. You can play around with the length-scales for better resolution.

smenon commented 10 years ago

Here's a video of the simulation: https://www.dropbox.com/l/lxNNhNGwCgiOFYPjdsK8Gq?

robertsawko commented 10 years ago

Thanks a lot Sandeep. Also it seems that 6DoF was improved in OpenFOAM 2.3 which we wouldn't be able to take advantage of if you didn't prepare 2.3.x port. We will be doing some validation of the valve motion on longer domains now and will let you know how it goes. Thanks again.

mojtabaAmiraslanpour commented 8 years ago

Hi, I am very interested in this problem, unfortunately I couldn't download the test case file attached above. Its probably deleted. Is it possible to re-upload the test case and give a short description about the hack discussed above?

Thank you.

RupeshW commented 8 years ago

Hello Sandeep, I recently came across "dynamicTopoFvMesh" as i installed foam extend 3.1 (also read some of the documents available online, mostly written by you.), but still not sure about how it works, So can you please share any simple test/tutorial case, so that it will be easy to understand.