CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   OpenFOAM coupling with matlab (https://www.cfd-online.com/Forums/openfoam-programming-development/226781-openfoam-coupling-matlab.html)

neko2650 May 7, 2020 13:40

OpenFOAM coupling with matlab
 
1 Attachment(s)
Hello,

I am working on a Sloshing tank 2d simulation problem. Initially, I have used linear motion for simulation and successfully simulated the programme. The next task I am assigned is with two-way coupling with Matlab.

I followed a reference work: http://www.tfd.chalmers.se/~hani/kur...D3D_Report.pdf

Using this file I have created a matlabPipe.so file which calls Matlab engine.h

The basic idea is to extract sloshing force from OpenFOAM at each time step and give these input values to Matlab and the Matlab calculates the displacement using numerical integration and returns back the value to Open foam in terms of displacement (amplitude) values. The description is also given in the flowchart.

I understood that the Matlab engine works with a pointer which are
1. Get the pointer
2. Evaluate the pointer
3. Put the pointer

1. Get the pointer.

To get the pointer I looked into my SloshingTank2D contolDict file where I used probes function to obtain pressure. This function creates a P file postprocessing folder.

Code:

functions
{
probes
{
type probes;
libs ("libsampling.so");
writeControl writeTime;
probeLocations
(
(0 .29 -0.04)
(0 -.29 -0.04)
);
fixedLocations false;

The question is how can link the pointer value to matlab engine i.e do I have to use 'libsampling.so' or 'P' csv format file. Is there any way to do so

2. Evaluate the pointer:

I have my Matlab interpolation code in .m file format in which utility file I can connect it.

3. Put the pointer:
The solidBodyMotionFunction provides a utility where the solid body motion can be read from text file. Can I modify tabulated6DoFMotion utility function such that the Matlab writes the files at each time step and FoamSolver reads the file at each time step?

I have looked into the tabulated6DoFMotion.H file
and tabulated6DoFMotion.C file in which line I should provide the pointer such that
Code:

  #include "tabulated6DoFMotion.H"
 #include "addToRunTimeSelectionTable.H"
 #include "Tuple2.H"
 #include "IFstream.H"
 #include "interpolateSplineXY.H"
 #include "unitConversion.H"
 
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
 namespace solidBodyMotionFunctions
 {
    defineTypeNameAndDebug(tabulated6DoFMotion, 0);
    addToRunTimeSelectionTable
    (
        solidBodyMotionFunction,
        tabulated6DoFMotion,
        dictionary
    );
 }
 }
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::tabulated6DoFMotion
 (
    const dictionary& SBMFCoeffs,
    const Time& runTime
 )
 :
    solidBodyMotionFunction(SBMFCoeffs, runTime)
 {
    read(SBMFCoeffs);
 }
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::~tabulated6DoFMotion()
 {}
 
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
 Foam::septernion
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::transformation() const
 {
    scalar t = time_.value();
 
    if (t < times_[0])
    {
        FatalErrorInFunction
            << "current time (" << t
            << ") is less than the minimum in the data table ("
            << times_[0] << ')'
            << exit(FatalError);
    }
 
    if (t > times_.last())
    {
        FatalErrorInFunction
            << "current time (" << t
            << ") is greater than the maximum in the data table ("
            << times_.last() << ')'
            << exit(FatalError);
    }
 
    translationRotationVectors TRV = interpolateSplineXY
    (
        t,
        times_,
        values_
    );
 
    // Convert the rotational motion from deg to rad
    TRV[1] *= degToRad();
 
    quaternion R(quaternion::XYZ, TRV[1]);
    septernion TR(septernion(-CofG_ + -TRV[0])*R*septernion(CofG_));
 
    DebugInFunction << "Time = " << t << " transformation: " << TR << endl;
 
    return TR;
 }
 
 
 bool Foam::solidBodyMotionFunctions::tabulated6DoFMotion::read
 (
    const dictionary& SBMFCoeffs
 )
 {
    solidBodyMotionFunction::read(SBMFCoeffs);
 
    // If the timeDataFileName has changed read the file
 
    fileName newTimeDataFileName
    (
        fileName(SBMFCoeffs_.lookup("timeDataFileName")).expand()
    );
 
    if (newTimeDataFileName != timeDataFileName_)
    {
        timeDataFileName_ = newTimeDataFileName;
 
        IFstream dataStream(timeDataFileName_);
 
        if (dataStream.good())
        {
            List<Tuple2<scalar, translationRotationVectors>> timeValues
            (
                dataStream
            );
 
            times_.setSize(timeValues.size());
            values_.setSize(timeValues.size());
 
            forAll(timeValues, i)
            {
                times_[i] = timeValues[i].first();
                values_[i] = timeValues[i].second();
            }
        }
        else
        {
            FatalErrorInFunction
                << "Cannot open time data file " << timeDataFileName_
                << exit(FatalError);
        }
    }
 
    SBMFCoeffs_.readEntry("CofG", CofG_);
 
    return true;
 }
 
 
 // ************************************************************************* //

I tried to learn the links but there are too many library files interconnected. I don't know how to solve this loop. At least if someone directs me a path will be very much helpful.:)

HPE May 12, 2020 16:19

Hi,

- Would the following help?
- https://www.precice.org/
- https://www.openfoam.com/documentati...alCoupled.html

Santiago May 13, 2020 08:32

Quote:

Originally Posted by neko2650 (Post 769287)
Hello,

I am working on a Sloshing tank 2d simulation problem. Initially, I have used linear motion for simulation and successfully simulated the programme. The next task I am assigned is with two-way coupling with Matlab.

I followed a reference work: http://www.tfd.chalmers.se/~hani/kur...D3D_Report.pdf

Using this file I have created a matlabPipe.so file which calls Matlab engine.h

The basic idea is to extract sloshing force from OpenFOAM at each time step and give these input values to Matlab and the Matlab calculates the displacement using numerical integration and returns back the value to Open foam in terms of displacement (amplitude) values. The description is also given in the flowchart.

I understood that the Matlab engine works with a pointer which are
1. Get the pointer
2. Evaluate the pointer
3. Put the pointer

1. Get the pointer.

To get the pointer I looked into my SloshingTank2D contolDict file where I used probes function to obtain pressure. This function creates a P file postprocessing folder.

Code:

functions
{
probes
{
type probes;
libs ("libsampling.so");
writeControl writeTime;
probeLocations
(
(0 .29 -0.04)
(0 -.29 -0.04)
);
fixedLocations false;

The question is how can link the pointer value to matlab engine i.e do I have to use 'libsampling.so' or 'P' csv format file. Is there any way to do so

2. Evaluate the pointer:

I have my Matlab interpolation code in .m file format in which utility file I can connect it.

3. Put the pointer:
The solidBodyMotionFunction provides a utility where the solid body motion can be read from text file. Can I modify tabulated6DoFMotion utility function such that the Matlab writes the files at each time step and FoamSolver reads the file at each time step?

I have looked into the tabulated6DoFMotion.H file
and tabulated6DoFMotion.C file in which line I should provide the pointer such that
Code:

  #include "tabulated6DoFMotion.H"
 #include "addToRunTimeSelectionTable.H"
 #include "Tuple2.H"
 #include "IFstream.H"
 #include "interpolateSplineXY.H"
 #include "unitConversion.H"
 
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
 namespace solidBodyMotionFunctions
 {
    defineTypeNameAndDebug(tabulated6DoFMotion, 0);
    addToRunTimeSelectionTable
    (
        solidBodyMotionFunction,
        tabulated6DoFMotion,
        dictionary
    );
 }
 }
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::tabulated6DoFMotion
 (
    const dictionary& SBMFCoeffs,
    const Time& runTime
 )
 :
    solidBodyMotionFunction(SBMFCoeffs, runTime)
 {
    read(SBMFCoeffs);
 }
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::~tabulated6DoFMotion()
 {}
 
 
 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
 
 Foam::septernion
 Foam::solidBodyMotionFunctions::tabulated6DoFMotion::transformation() const
 {
    scalar t = time_.value();
 
    if (t < times_[0])
    {
        FatalErrorInFunction
            << "current time (" << t
            << ") is less than the minimum in the data table ("
            << times_[0] << ')'
            << exit(FatalError);
    }
 
    if (t > times_.last())
    {
        FatalErrorInFunction
            << "current time (" << t
            << ") is greater than the maximum in the data table ("
            << times_.last() << ')'
            << exit(FatalError);
    }
 
    translationRotationVectors TRV = interpolateSplineXY
    (
        t,
        times_,
        values_
    );
 
    // Convert the rotational motion from deg to rad
    TRV[1] *= degToRad();
 
    quaternion R(quaternion::XYZ, TRV[1]);
    septernion TR(septernion(-CofG_ + -TRV[0])*R*septernion(CofG_));
 
    DebugInFunction << "Time = " << t << " transformation: " << TR << endl;
 
    return TR;
 }
 
 
 bool Foam::solidBodyMotionFunctions::tabulated6DoFMotion::read
 (
    const dictionary& SBMFCoeffs
 )
 {
    solidBodyMotionFunction::read(SBMFCoeffs);
 
    // If the timeDataFileName has changed read the file
 
    fileName newTimeDataFileName
    (
        fileName(SBMFCoeffs_.lookup("timeDataFileName")).expand()
    );
 
    if (newTimeDataFileName != timeDataFileName_)
    {
        timeDataFileName_ = newTimeDataFileName;
 
        IFstream dataStream(timeDataFileName_);
 
        if (dataStream.good())
        {
            List<Tuple2<scalar, translationRotationVectors>> timeValues
            (
                dataStream
            );
 
            times_.setSize(timeValues.size());
            values_.setSize(timeValues.size());
 
            forAll(timeValues, i)
            {
                times_[i] = timeValues[i].first();
                values_[i] = timeValues[i].second();
            }
        }
        else
        {
            FatalErrorInFunction
                << "Cannot open time data file " << timeDataFileName_
                << exit(FatalError);
        }
    }
 
    SBMFCoeffs_.readEntry("CofG", CofG_);
 
    return true;
 }
 
 
 // ************************************************************************* //

I tried to learn the links but there are too many library files interconnected. I don't know how to solve this loop. At least if someone directs me a path will be very much helpful.:)


I dont find a good reason for coupling at all! Why don't you just re-implement whatever you are doing in matlab into an OpenFOAM class/library? Coupling codes is certainly more "difficult", from a programming standpoint, specially when you have to interface with commercial codes (MATLAB).

BTW, using file pipes as means of coupling data-intensive codes is rather inefficient, slow, prone to IO errors, and you might run with caching/memory issues along the way. What is better to do in this cases is to program a DRIVER, a third program that interact directly with the codes you want to couple. One example of that is preCICE.

neko2650 May 13, 2020 09:56

I Thank HPE and Santiago for taking their precious time and reverting back.

I have seen the src files relating to 'spring', 'mass', 'damper' systems, which I can attach to my sloshingTank and run my simulations. But my goal is to derive the equation of motion flutter derivatives using Matlab which I guess would be difficult to frame in OpenFOAM.

To do this I am trying to couple the two systems with the basic equation of motion as my first step. With HPE's advice, I am looking into the preCICE.

Also, I have one more query. Instead of Matlab can I use Python script as I have seen OpenFOAM env supports pyFOAM. If so how can I add my class/library files in OpenFOAM using python?

For example: Here in my case, I have my probes function which calculates pressure to should be taken by python/Matlab and return the values to OpenFOAM in dynamic library dictionary files. If there is some possibility it would be really helpful if someone shares the manual/URL using pyFOAM.:)

Santiago May 13, 2020 10:34

Quote:

Originally Posted by neko2650 (Post 770253)
I have seen the src files relating to 'spring', 'mass', 'damper' systems, which I can attach to my sloshingTank and run my simulations. But my goal is to derive the equation of motion flutter derivatives using Matlab which I guess would be difficult to frame in OpenFOAM.

Not true. You can solve ODE's within OpenFOAM, rather easily. The it depends on you how much time you want to dedicate into "framing" it. You can call OpenGL within OF, and use their spring-mass systems solvers. An example:

https://github.com/muzuka/MassSpringSystem

Or you can implement it directly, for instance:

http://www.tfd.chalmers.se/~hani/kur...FoamReport.pdf

In any case, its just an additional set of ODEs solved over the surface of your airfoil, calculating displacements and rotations:

https://perso.limsi.fr/olm/archives/flutter.pdf

Which lays in the very reasons as to why OpenFOAM exists. Anyway, you decide whether it's worth to implement it there, or not.

Note that your code will be inevitably slowed down by the blocked communications caused by the preCICE driver. If you are doing toy simulations it may not be a problem though...

In any case it'd be nice to see the implementation of such coupling.

Quote:

Originally Posted by neko2650 (Post 770253)
Also, I have one more query. Instead of Matlab can I use Python script as I have seen OpenFOAM env supports pyFOAM. If so how can I add my class/library files in OpenFOAM using python?

If there is a library that can do what you look for in Python, in 99.99999999999% of the cases that library is either written in C/C++ or it also exists in C/C++, so you can avoid python altogether. And to answer your question, yes, you may try swak4foam as a means of importing/exporting (piping) your data as well.

HPE May 13, 2020 17:01

Hi,

- For data transfer from OpenFOAM, I suggest Ofpp, which is a bliss in my opinion in comparison to PyFoam.

Hope this helps.


All times are GMT -4. The time now is 13:11.