CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Post-Processing (https://www.cfd-online.com/Forums/openfoam-post-processing/)
-   -   Reading Lagrangian Position Data (https://www.cfd-online.com/Forums/openfoam-post-processing/225531-reading-lagrangian-position-data.html)

cjc96 March 30, 2020 13:45

Reading Lagrangian Position Data
 
Hello everyone,

I'm currently working on a custom (PISO-based) Eulerian-Lagrangian Solver in OpenFOAM 7, primarily based on this presentation and existing work carried out by my department in OpenFOAM 2.4.

I'm trying to extract the data for post-processing in MATLAB, OpenFOAMs built-in 'particleTracks' function doesn't seem overly versatile, unless I am missing something here also.

My problem is reading the position data from:

Code:

*/lagrangian/kinematicCloud/positions
My data is of the format:

Code:

(0.08930289 0.6773368 0.1431805 0.09017981) 1135715 3437655 1
As you can see, there are seemingly four 'position' values

Whereas data I have from the work in 2.4 (albeit from a different problem) is formatted as so:

Code:

(-0.189055 -0.169927 0.157027) 22739688
Which has three 'position' values, as one would expect

Taking a rather crude measurement (using the ruler) of the corresponding particle position in ParaView shows an actual position of:

Code:

expectedPosition = [1.50022 0.031163 0.56261]
I've tried to manipulate the numbers based on an initial injection point of:

Code:

injectorPosition = [1.01, -0.15, 0.414]
But even then I can't get the numbers to add up.

If anyone has any experience in this regard I would be extremely grateful!

cjc96 March 30, 2020 15:28

On further inspection, I think the issue is stemming from OpenFOAMs move to Barycentric Tracking in 2017.

So, that begs the question, how does one convert from these Barycentric Co-ordinates to the Global system? Or, as a less ideal alternative, configure the 'particleTracks' function to properly evolve over time and colour according to other Lagrangian parameters, such as diameter?

Thanks again,

zhangyan March 31, 2020 12:16

https://github.com/blueCFD/lagrangia...unctionObjects

olesen April 2, 2020 10:54

Quote:

Originally Posted by cjc96 (Post 763588)
On further inspection, I think the issue is stemming from OpenFOAMs move to Barycentric Tracking in 2017.

So, that begs the question, how does one convert from these Barycentric Co-ordinates to the Global system?

Similar issue when reading with paraview, as discussed here:

https://discourse.paraview.org/t/par...penfoam/3456/8

cjc96 April 2, 2020 11:15

Quote:

Originally Posted by olesen (Post 763937)
Similar issue when reading with paraview, as discussed here:

https://discourse.paraview.org/t/par...penfoam/3456/8

Hey Olesen,
Thanks for the reply.

While that is indeed the source of my problem, I have no problems actually opening and viewing the Lagrangian data in ParaView (OF 7, PV 5.6). I'm not overly versed in this area, but is that because I'm using paraFoam as opposed to the native client?

olesen April 2, 2020 17:27

Quote:

Originally Posted by cjc96 (Post 763941)
While that is indeed the source of my problem, I have no problems actually opening and viewing the Lagrangian data in ParaView (OF 7, PV 5.6). I'm not overly versed in this area, but is that because I'm using paraFoam as opposed to the native client?


Yes exactly. As you may realize, "paraFoam" is simply a script to touch a file and start paraview, under the assumption that an additional combined reader plugin is loadable that is compiled with OpenFOAM and ParaView sources.

cjc96 April 3, 2020 14:36

As an update,

zhangyan's suggestion of lagrangianExtraFunctionObjects doesn't currently fulfil my needs, it seems that it is written in such a way that you add additional code for each solver used, of which my custom solver is of course not one of.

While I am sure that the function can be modified to work with my solver, my (naive and inexperienced) impression, is that its functionality could be added to my user-attributed Lagrangian directory.

I've already made some small progress by modifying a section of my custom version of:

Code:

src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C
from:

Code:

    if (this->db().time().writeTime())
    {
        outputProperties_.writeObject
        (
            IOstream::ASCII,
            IOstream::currentVersion,
            this->db().time().writeCompression(),
            true
        );
    }

to:

Code:

    if (this->db().time().writeTime())
    {
        outputProperties_.writeObject
        (
            IOstream::ASCII,
            IOstream::currentVersion,
            this->db().time().writeCompression(),
            true
        );

                // Conor
                Info << "Temporary Position Write" << nl << endl;
                this->writePositions();
    }

which writes the Cartesian position of each particle to an unformatted .obj file that is overwritten each write interval, but at least I know the data can be extracted.

My first thought was to look at 'outputProperties' to see if I could stitch on a new output, but from what I could find using some rather inelegant grep searches, it seems to be responsible for the contents of:

Code:

case/time/uniform
as opposed to the desired:

Code:

case/time/lagrangian/kinematicCloud
I am aware that this is becoming a rather broad "can you do it for me?" type thread, but could anyone point me towards a tutorial on how to add new data outputs to the source code? I'm hoping I'd be able to use such a guide to create my own 'positionsXYZ' output.

While I expect this exercise to be rather beneficial in the long run, due to my current inexperience, I've spent the better part of this week aimlessly searching through the Lagrangian source code, and it's becoming somewhat demoralising.

Again, thanks for your help!

Tobi April 6, 2020 16:31

Quote:

Originally Posted by cjc96 (Post 763941)
Hey Olesen,
Thanks for the reply.

While that is indeed the source of my problem, I have no problems actually opening and viewing the Lagrangian data in ParaView (OF 7, PV 5.6). I'm not overly versed in this area, but is that because I'm using paraFoam as opposed to the native client?


Hi, since I am checking out some new simulation, I focused this problem too. As Mark already mentioned, I also went through the thread from paraview. However, I cannot watch any field of the Lagragian data in OF 7 and PV 5.8. I am wondering why you can view this data. Even using paraFoam does not work in my case. Maybe the problem is that I have to start paravFoam -builtin.


I will check it.

clapointe April 6, 2020 16:49

Hi all,

I have encountered similar problems in the past, and figured I might weigh in. I use paraview 5.4 and most recently OpenFOAM-7. With the openfoam reader I can view my particles without any problem -- this seems to be in agreement with Conor's experience. That said, I have seen the previous error (e.g. with precompiled paraview binaries or on an hpc) -- the only time I've had no problems viewing particles is when I compile everything myself. But I know that this is often not an option. When using the built in reader (either by calling paraview directly, or with paraFoam -builtin) is unavoidable, the foamToVTK work-around has worked for me. It does make the visualization process a bit clunky, but there is a foamSequenceVTKFiles utility that can help.

As for saving data, saving it through paraview (e.g. position, velocity) has been sufficient for me (assuming that you're able to load them in the first place).

Caelan

Tobi April 6, 2020 17:47

My problem (as I always compile everything myself to be conform with the latest dev-line) is that I do not have the PVReader compiled and I cannot figure out how / where to compile that plugin. In former times, I remember that it was automatically compiled or at least a information popped out at the end of compiling or while calling paraFoam. Now, while starting paraFoam I get the info, that the reader plugin is not available.

clapointe April 6, 2020 17:53

The pvreader is -- at least for openfoam 7 -- in $FOAM_APP/utilities/postProcessing/graphics/PVReaders. I agree that it should be compiled automatically.

Caelan

Tobi April 6, 2020 18:13

Thanks. Compiled and it is working now.

cjc96 April 18, 2020 15:01

Hey guys,

Just thought I'd post an update as I figured at some point, someone else will be trying to do the same thing. I have successfully modified OpenFOAM 7 to output global Cartesian position data, alongside the barycentric data. It's worth mentioning that this is specifically for 'kinematicCloud' based solvers and that I recommend making your own user-defined 'src' directory (and pointing your solver to that) as opposed to making these changes to the main OpenFOAM source files.

The modification consisted of minor additions to the following:

Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C
lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C



In each of these files, I made reference to my own custom field 'globalPos' in much the same way as the other particle properties ('active', 'age', 'd' etc.) are referenced, such as the following :

Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C

ParcelType(p),
active_(p.active_),
typeId_(p.typeId_),
nParticle_(p.nParticle_),
d_(p.d_),
dTarget_(p.dTarget_),
U_(p.U_),
rho_(p.rho_),
age_(p.age_),
tTurb_(p.tTurb_),
UTurb_(p.UTurb_),
globalPos_(p.globalPos_) // cjc96

And then defined the field at the end of the 'move' function
Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C

// cjc96 {
// Store current global position
p.globalPos() = p.position();
// cjc96 }

In hindsight, I think it may have been overkill to define my own field, when 'p.position' already existed, and it is likely simpler (and less expensive) to force the solver to write 'p.position' directly. However, the exercise was very useful in identifying the methods of actually adding a field, enabling me to do so with those that aren't already sitting hidden in the solver.

Hopefully this helps someone, and I'd be happy to detail each of the additions I made if someone has need for it!

Mirza8 September 14, 2021 06:35

Quote:

Originally Posted by zhangyan (Post 763704)

Hi all,
Thanks Yan, your solution was helpful as always! :)

I have compiled and used lagrangianExtraFunctionObjects in OF7 and it works in a serial case to generate positions.orig, which I need for post-processing.
However, I have problems when I run a parallel case. I have "positions" and "positions.orig" files in each processor directory. However, when I reconstruct the case, I only get the reconstructed "positions" file. Any insights on how to reconstruct the "positions.orig" which has the cartesian coordinates?

/ Morteza

lf.lopez18 November 30, 2021 21:17

Quote:

Originally Posted by Mirza8 (Post 812161)
However, I have problems when I run a parallel case. I have "positions" and "positions.orig" files in each processor directory. However, when I reconstruct the case, I only get the reconstructed "positions" file. Any insights on how to reconstruct the "positions.orig" which has the cartesian coordinates?


Same problem here :(. If any of you know how to reconstruct with the "positions.orig" file, please let us know.



Thanks,
Luis.

cjc96 December 1, 2021 05:07

Quote:

Originally Posted by lf.lopez18 (Post 817653)
Same problem here :(. If any of you know how to reconstruct with the "positions.orig" file, please let us know.



Thanks,
Luis.


Luis, you can always do as I did and compile your own, local versions of the relevant
Code:

src/lagrangian
files to achieve the desired functionality.

Assuming you are using OpenFOAM v7, these files being:

Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C
lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C

Where you find references to other particle properties, such as 'nParticle' and add a new property, which you define as the Cartesian position.

joshwilliams January 11, 2022 04:37

Quote:

Originally Posted by Mirza8 (Post 812161)
Hi all,
Thanks Yan, your solution was helpful as always! :)

I have compiled and used lagrangianExtraFunctionObjects in OF7 and it works in a serial case to generate positions.orig, which I need for post-processing.
However, I have problems when I run a parallel case. I have "positions" and "positions.orig" files in each processor directory. However, when I reconstruct the case, I only get the reconstructed "positions" file. Any insights on how to reconstruct the "positions.orig" which has the cartesian coordinates?

/ Morteza


I also had this issue. For this, I just run a post-processing step in serial to get positions.orig. i.e.



Code:

mpirun -np 4 MPPICFoam -parallel

MPPICFoam -postProcess


geth03 September 26, 2022 07:57

1 Attachment(s)
Quote:

Originally Posted by olesen (Post 763937)
Similar issue when reading with paraview, as discussed here:

https://discourse.paraview.org/t/par...penfoam/3456/8

hi,

after executing foamToVTK the "positions"-file is not converted, including other data, please find attached screenshot.

am i missing something?

how do i make the particles visible? i could not find any good tutorial.

joshwilliams September 26, 2022 15:37

You can visualise particles using the 'Glyph' option in paraview.



If you wish to colour particles by their position (e.g. maybe by initial z coordinate for some reason), I guess you could use paraview calculator and select "coordsZ" in the scalars toolbar. I guess the coords does not come up in an option in the toolbar you show as this is for colouring by some scalar field, and it is rare that people colour particles by their position in space.



Quote:

Originally Posted by geth03 (Post 836503)
how do i make the particles visible? i could not find any good tutorial.


xhan July 29, 2023 22:19

Quote:

Originally Posted by cjc96 (Post 766308)
Hey guys,

Just thought I'd post an update as I figured at some point, someone else will be trying to do the same thing. I have successfully modified OpenFOAM 7 to output global Cartesian position data, alongside the barycentric data. It's worth mentioning that this is specifically for 'kinematicCloud' based solvers and that I recommend making your own user-defined 'src' directory (and pointing your solver to that) as opposed to making these changes to the main OpenFOAM source files.

The modification consisted of minor additions to the following:

Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelI.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.H
lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcelIO.C
lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C



In each of these files, I made reference to my own custom field 'globalPos' in much the same way as the other particle properties ('active', 'age', 'd' etc.) are referenced, such as the following :

Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C

ParcelType(p),
active_(p.active_),
typeId_(p.typeId_),
nParticle_(p.nParticle_),
d_(p.d_),
dTarget_(p.dTarget_),
U_(p.U_),
rho_(p.rho_),
age_(p.age_),
tTurb_(p.tTurb_),
UTurb_(p.UTurb_),
globalPos_(p.globalPos_) // cjc96

And then defined the field at the end of the 'move' function
Code:

lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C

// cjc96 {
// Store current global position
p.globalPos() = p.position();
// cjc96 }

In hindsight, I think it may have been overkill to define my own field, when 'p.position' already existed, and it is likely simpler (and less expensive) to force the solver to write 'p.position' directly. However, the exercise was very useful in identifying the methods of actually adding a field, enabling me to do so with those that aren't already sitting hidden in the solver.

Hopefully this helps someone, and I'd be happy to detail each of the additions I made if someone has need for it!

Hi,
Thanks for sharing your idea, cjc96.
However, when i followed all your comment above and compiled my new intermediate, there was always an error message "class 'Foam::KinematicParcel<parceltype>'does not have any field named globalpos".
I have no idea how to deal with this. could you please tell us more details of your idea?


All times are GMT -4. The time now is 08:21.