CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (https://www.cfd-online.com/Forums/openfoam-solving/)
-   -   icoUncoupledKinematicParcelFoam (https://www.cfd-online.com/Forums/openfoam-solving/92556-icouncoupledkinematicparcelfoam.html)

kamranian September 18, 2011 03:26

icoUncoupledKinematicParcelFoam
 
Hi Foamers,

I`m particularly interested in DEM-CFD coupling. My question is about icoUncoupledKinematicParcelFoam. The solver name includes `uncoupled` which leads me to the conclusion that is not capable of solving coupled problems.
Could please anybody clarify if coupling by interaction of fluid and particles (forces) is already possible in OpenFoam v2.0 or if the coupling is still work in progress ?
If OpenFoam v2.0 already includes some coupling functionality what source files should I look at ?
I also checked the doxygen documentation and could not find anything about icoUncoupledKinematicParcelFoam solver yet.
Is there any document or tutorial that shown the procedure of modeling and modeling parameters?

Best Regards,
A. Kamranian

AMahrla September 20, 2011 10:42

Hi!

The icoUncoupledKinematicParcelFoam is only a coupled solver in the sense that particle-particle interaction is considered. Any coupling between fluid and particulate phase is neglected.

Please refer also to this thread!

Best,

Astrid

kamranian September 21, 2011 04:04

icoUncoupledKinematicParcelFoam
 
Dear Astrid,

Thank you for your reply. If it is possible to couple this solver with fluid interaction? I am interested to use CFD-DEM to simulation of four-way coupling via OpenFOAM. Can I do it in OpenFOAM? Do you have any recommand for me?

Regards,
A. Kamranian

AMahrla September 21, 2011 05:40

Hi again!

The implementation of coupling to the continuous phase should be possible, but IMO you have to dig into the code around the particle class which is not THAT top level..

Maybe you can find a starting point within the tutorials on extend-wiki and get to know the implementation of particles in OpenFOAM?

Best,

Astrid

Toorop November 18, 2011 09:28

Hi,

I'm investigating how to track particles within the fluid domain in OpenFOAM.

Initially, I thought that there's a simple method to perform one-way coupling with basic solvers (icoFoam, pisoFoam, pimpleFoam) - solidParticle class describes itself as a spherical particle class with one-way coupling with the continuous phase. Unfortunately didn't find anything. Instead, there's some tutorials about how to "hack" it into a desired solver. So is there an elegant interface where one can describe passive particle (parcel) cloud / emission?

At first, I thought that icoUncoupledKinematicParcelFoam can handle this sort of simulations - is it possible to couple this with another solver?

gara1988 January 18, 2013 05:01

Hello Toorop, Have you find a solution of you question? I have the same problem.

rama13 July 14, 2014 13:05

icoUncoupledKinematicParcelFoam
 
Hi Foamers,

I have a very simple question for you.

1) icoUncoupledKinematicParcelFoam solves for the interaction between particles as pointed out here (and if you look into the code no continuum phase is solved).

2) in the User Guide it is describerd as "Transient solver for the passive transport of a single kinematic particle could"

3) if you look into the case directory there is a 0/U field in which (my guess) you can set the velocity field at which your particles get convected away, and I think is what has been done in this nice video.

My question is: if particles get carried away by the fluid

1) they cannot bump into other particles since two streamlines does not collide (so no need to solve interaction)

2) even if they would, they will get a different momentum from the fluid particles they are going with, so they will be no more "passive":confused:?!

I hope someone more expert than me can point me out the clue:)!

Thanks for your attention,
Damiano

Tobi July 5, 2016 10:17

Hi,

old thread but due to the fact that other people may read it in feature too I will give a clearer answer.

icoUncoupledParcelFoam is a transient solver for passive parcel motion. That means that the particels do not influence the fluid but the parcels can interact between each other. If you think the particels are just moving along the streamlines, then you are wrong because for the particels we solve drag forces and so on that will finally change the direction of the particel. Just imagine a hydrocyclone. The particels will not follow the flow due to additional forces that act on the particels (like inertia). Depending on the particels properties (density, diameter and so forth), the parcels follow more or less the streamlines of the flow.

rama13 July 5, 2016 10:31

Thank you very much for your answer Toby!

Tobi July 5, 2016 10:36

Hi,

you 're welcome but I think you already knew it (: (after the long time)

rama13 July 5, 2016 10:42

All the same, a reliable confirmation is always useful, and a kind reply is always good accepted!! Thanks again!

randolph July 19, 2017 12:19

Quote:

Originally Posted by Tobi (Post 608077)
Hi,

old thread but due to the fact that other people may read it in feature too I will give a clearer answer.

icoUncoupledParcelFoam is a transient solver for passive parcel motion. That means that the particels do not influence the fluid but the parcels can interact between each other. If you think the particels are just moving along the streamlines, then you are wrong because for the particels we solve drag forces and so on that will finally change the direction of the particel. Just imagine a hydrocyclone. The particels will not follow the flow due to additional forces that act on the particels (like inertia). Depending on the particels properties (density, diameter and so forth), the parcels follow more or less the streamlines of the flow.

Hi, so in the source code of icoUncoupledParcelFoam. what's the function of
laminarTransport.correct();
mu = laminarTransport.nu()*rhoInfValue;
these two lines?

Thanks in advance

amuzeshi March 3, 2018 06:22

Quote:

Originally Posted by gara1988 (Post 402610)
Hello Toorop, Have you find a solution of you question? I have the same problem.

DPMFoam is what u need.

AKBALOM October 13, 2019 11:20

icoUncoupledKinematicParcelFoam droplet trajectories
 
Hi,
I want to simulate droplet trajectories analysis of airfoil profile.
I have already simulate flow field analysis with simpleFoam. So, I have velocity valıue for all domain mesh. After this step, ı want to simulate droplet trajectories with existence velocity flow field with lagrangian or eulerian approach. I hear that icoUncoupledKinematicParcelFoam with Lagrangian approach is useful for this approach.
But, ı colud not set up simulation cases. Is there any experience about this? Ho I can do it step by step for these calculation.
Thanks for listening and answering.

randolph October 13, 2019 11:49

Hi,

If you just simulate the particle transport on a "frozen" velocity field. You do not need to hassle yourself with the "solver".

Since you are dealing with the decoupled the simulation. You just simply use the ‘Pluggable’ solvers.

For lagrangian:
icoUncoupledKinematicCloud

For eulerian:
scalarTransport

If you are using RANS, pay attention to the handling of the "turbulence" diffusion.

If you are using wall function, pay attention to the near-wall interaction between your flow solution and particle transport.

Thanks,
Rdf

Mars409 June 16, 2020 09:09

Does anyone know a way to make icoUncoupledKinematicParcelFoam not recreate files for volume fields of the flow in every time directory? I would think to satisfy ParaView creating links to the volume fields under the 0/ directory would suffice.

Not sure how this disk space saving trick should work when using multiple processors. I assume both 'mpi' and 'reconstructPar' need to do likewise.

===============

Turns out 'reconstructPar' doesn't care as long as all the volume field files in the processor<n>/ directories are deleted beforehand.

I guess 'mpi' doesn't care either, as it's the application (here icoUncoupledKinematicParcelFoam) that is to decide whether or not to write out the volume fields.

So all is left is to find an option--if it exists--to stop the application from writing out the volume fields. This will not only save lots of disk space but speed up execution as well.

===========

A brute force way will be to write a Python or shell script to watch for new time directories being created and whenever it happens delete all volume field files in older time directories. This saves disk space on the fly but does not save disk write time though.

Tobi June 16, 2020 12:59

HI,



the simplest way is to stop the application to write out the field.



Code:

cd $FOAM_SOLVERS/lagrangian/icoUncoupledKinematicParcelFoam/
vim createFields.H


Change the following:


Code:

Info<< "Reading field U\n" << endl;                                           
volVectorField U                                                               
(                                                                             
    IOobject                                                                   
    (                                                                         
        "U",                                                                   
        runTime.timeName(),                                                   
        mesh,                                                                 
        IOobject::MUST_READ,                                                   
        IOobject::NO_WRITE                                                   
    ),                                                                         
    mesh                                                                       
);


And recompile:


Code:

wclean

wmake



Done. The solver does not write the velocity field anymore.
The problem here is, if you cancel the calculation and re-run the guy, it does not work as the velocity field is not there anymore. I am not sure but you can check the following:


Code:

volVectorField U                                                               
(                                                                             
    IOobject                                                                   
    (                                                                         
        "U",                                                                   
        "0",                                                   
        mesh,                                                                 
        IOobject::MUST_READ,                                                   
        IOobject::AUTO_WRITE                                                   
    ),                                                                         
    mesh                                                                       
);


amuzeshi June 16, 2020 14:57

Quote:

Originally Posted by Mars409 (Post 774744)
Does anyone know a way to make icoUncoupledKinematicParcelFoam not ....

Hello,
Compile this solver as a new one with the change shown below in RED in createFields.H:
Code:

Info<< "Reading field U\n" << endl;
volVectorField U
(
    IOobject
    (
        "U",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
    ),
    mesh
);


Mars409 June 16, 2020 23:54

Tobias, Ali, Thanks. It works!

This solver is such a great tool. I absolutely love it.

================

On the replacing 'runTime.timeName()' with "0", I guess you are right, though I haven't tried: runTime.timeName() returns the 'startFrom' time directory named in controlDict, and so if the controlDict has 'startFrom' set to 'latestTime' and the previous run's latest time directory doesn't have the velocity volume field then the solver will fail. I am guessing here, but got my confirmation from https://openfoamwiki.net/index.php/ScalarTransportFoam (found by search word 'runTime.timeName')
where it says
Quote:

runTime.timeName() defines from which time directory the file has to be read, according to what specified in controlDict by the user.
It seems that, in order to restart from time 0, the user can just set 'startFrom' value to 0 or 'startTime' in controlDict, instead of hard coding "0" in createField.H.

OTOH, if the user wants to resume simulation from the latest time (by setting startFrom to 'latestTime' in controlDict), just creating soft links in the latest time directory to link to the volume fields in the '0/' directory will do. So, in this instance, retaining "runTime.timeName()" in createField.h still has its use.

Tobi June 17, 2020 04:20

Hi, I disagree to you last statement:


  • if you run from 0 s to 10 s and stop the calculation and you re-run it with startTIme = 0, then you recalculate also the times from 0 s to 10 s which you probably would not want to do
  • Hence, I said that you could be add the change the U field with the "0" look-up folder
But in any case. I am happy that you are done.
By the way, you could also make the symbolic links within the solver itself. The workaround should be somehow like that:


Code:

if (runTime.write())
{
    ::symlink(const char  *name1, const char *name2);
}


Tobi

Mars409 June 17, 2020 06:47

I edited the last two paragraphs of my earlier reply to make them clearer.

Your suggestion to add symlink by the solver is neat. I'm not familiar with OpenFOAM's code structure so won't immediately try my hands making changes though, in case I might end up spending more time mopping up errors that I inject than getting the solver to automatically install symbolic links for the volume field files.

Tobi June 17, 2020 07:29

The best way is always to copy the solver completely:
Code:

cp -r icoUncoupledKinematicParcelFoam arbitraryName
vim arbitraryName/Make/files


Change the file accordingly:
Code:

icoUncoupledKinematicParcelFoam.C  // You can change this name - has to be the same as the source file
                                                                               
EXE = $(FOAM_USER_APPBIN)/yourNewSolverName


It is common practice to name the directory of the new solver, the source file of the new solver and the application name identically. A copy of the existing solver allows you to destroy the solver without losing the original files. Additionally, one can make a repository to have all changes in the history :)

Mars409 June 17, 2020 10:22

Thanks. That tip gives me the temerity to tinker.

As an aside, how does one extract origIds, seed positions and ages of particles that escape, from a MPPICFoam solver simulation? I will take that information and try to replicate in icoUncoupledKinematicParcelFoam for a closer look in isolation using fine output time intervals.

In ParaView, when viewing particles of MPPICFoam's Lagrangian fields, I often wish to "grab" the particles that escape and just replay the whole time sequence without the rest of the particles in order to pin down their trajectories, but I have had no luck so far in coming out with a simple way. All I could do was play with 'rescale to custom data range' repeatedly narrowing each time the range.

amuzeshi June 17, 2020 14:37

Quote:

Originally Posted by Mars409 (Post 774888)
Thanks. That tip gives me the temerity to tinker.

As an aside, how does one extract origIds, seed positions and ages of particles that escape...

Interesting; How to grab them without showing the rest of particles is a mystery :cool:.

Tobi June 18, 2020 02:03

You can use the objectFunction for such purpose. Simply add the following to your kinematicCloud properties file:
Code:

cloudFunctions
{
patchPostProcessing1
{
        type patchPostProcessing;
        maxStoredParcels 100;
        patches                    ( outlet particleOutlet_1  particleOutlet_2 );
}
}


Mars409 June 18, 2020 04:01

Thanks very much. This is great!!! Am developing a better feel for this suite of tools each time I get a tip-off from you.

Based on your tip-off, I searched by "patchPostProcessing," which turned up a few hits. I'm bookmarking them below so I will find them easily next time and likely other users would too.

(1) (23/12/2019) https://www.openfoam.com/releases/op...processing.php ;

(2) https://openfoam.org/release/2-3-0/physical-modelling/;

(3) https://www.cfd-online.com/Forums/op...-surface.html;

(4) https://www.cfd-online.com/Forums/op...gh-patch.html; and,

(5) https://www.cfd-online.com/Forums/op...rocessing.html

This will keep me busy for a day.

Mars409 June 19, 2020 12:23

Update:
The postprocessing output comes in the form of a text file for each of the patches named in the patchPostProcessing dictionary in each of the time directories, like below (1 escape parcel at time 0.7767173, age 0.0691692s, origId 867):
Quote:

# Time currentProc (coordinatesa coordinatesb coordinatesc coordinatesd) celli tetFacei tetPti facei stepFraction behind nBehind origProc origId active typeId nParticle d dTarget (Ux Uy Uz) rho age tTurb (UTurbx UTurby UTurbz)(UCorrectx UCorrecty UCorrectz)
0.7767173 0 (0 0.5762929 0.02546568 0.3982414) 19247 347318 2 347318 0.4735261 0 0 0 867 1 -1 33499.99 6.662183e-06 0 (-2.963849 -5.443226 -5.409991) 1000 0.0691692 0 (0 0 0) (0 0 0)
The above is from the outlet patch.

The inlet patch (with rebound for particles), is empty except for the first row (labels).

I was hoping the input patch post processing will report the origId and coordinates when the parcels are injected, which I then can use to set the injected parcel coordinates in icoKinematicCloudFoam. That hope is dashed.

==========================
Now, armed with the origId and Time of escape, I can step to the time(s) snapshots before escape and use Threshold filter to display just this parcel.

But it's just one snapshot.

What are my alternatives?

(1) Is there a function object to output origId and coordinates at much smaller time steps separate from the writeout time step? Since the number of parcels is only in the thousands, it seems not far fetched that this possibility exists in the source codes.

(2) Is there a function object to record the launch coordinates and origId for all particles injected? The data has to be somewhere. The question is how to get it out into a text file.

Would be very nice to have both.

===================

A 'band-aid' way of doing (1) is to re-run the Lagrangian solver at the much finer time steps for tracing the desired parcels but with writing of the volume fields all turned off to save disk space. As Tobias and Ali suggested above for a different solver through editing the createField.h header file to change 'AUTO_WRITE' to 'NO_WRITE' for the respective volume field's IOobject.

Compiling a 2nd version of the solver is necessary for this band-aid to work. Run the original version for the original, coarse write-out time step. Run the 2nd version for the new, finer write-out time step to write out Lagrangian fields only.

Of course it will better if in one run the solver can use two different write-out time steps, and let user control--through controlDict--what fields to use which write-out time steps.

==============

On 2nd thought, that band-aid for (1) will work only if the parcels are injected at exactly the same positions with the same velocities and the same particle diameters, etc., etc., everytime the simulation is re-run. But is it true? I have a feel it is controlled by a random variable, since I set the diameter to 'normal distribution'. Which is good, because a random process driven injector will help to discover something interesting that a pre-determined injector will miss.

I think I can just skip the first part of (1) -- i.e. the part about running first time to output volume fields at coarse time steps -- and straightaway go for the 2nd part -- i.e. writing out only the Lagrangian fields and doing so at the finer time step.

amuzeshi June 20, 2020 08:27

Quote:

Originally Posted by Mars409 (Post 775185)
...Now, armed with the origId and Time of escape, I can step to the time(s) snapshots before escape and use Threshold filter to display just this parcel....

By the way you would specify MIN and MAX in threshold filter; you can not specify what exact origIds you want to be shown, can you?

Mars409 June 20, 2020 09:55

Setting MIN=origID and MAX=origID does it.

amuzeshi June 20, 2020 23:55

Quote:

Originally Posted by Mars409 (Post 775286)
Setting MIN=origID and MAX=origID does it.

Therefore you watch your interested particles one-by-one, not as a list of specific particles at once; right?

Mars409 June 22, 2020 04:41

Quote:

Originally Posted by Tobi (Post 774788)
HI,



the simplest way is to stop the application to write out the field.



Code:

cd $FOAM_SOLVERS/lagrangian/icoUncoupledKinematicParcelFoam/
vim createFields.H

Change the following:


Code:

Info<< "Reading field U\n" << endl;                                           
volVectorField U                                                               
(                                                                             
    IOobject                                                                   
    (                                                                         
        "U",                                                                   
        runTime.timeName(),                                                   
        mesh,                                                                 
        IOobject::MUST_READ,                                                   
        IOobject::NO_WRITE                                                   
    ),                                                                         
    mesh                                                                       
);

And recompile:


Code:

wclean

wmake

Done. The solver does not write the velocity field anymore.
The problem here is, if you cancel the calculation and re-run the guy, it does not work as the velocity field is not there anymore. I am not sure but you can check the following:


Code:

volVectorField U                                                               
(                                                                             
    IOobject                                                                   
    (                                                                         
        "U",                                                                   
        "0",                                                   
        mesh,                                                                 
        IOobject::MUST_READ,                                                   
        IOobject::AUTO_WRITE                                                   
    ),                                                                         
    mesh                                                                       
);


It works perfectly with all volume fields, except k.bulk and nut.bulk.

Without this remaining obstacle, I can use even smaller writeout time steps.

The fields aren't named in any of the header and source files at any level below the DPM directory.

Anyone knows where to find them to turn off the write out?


=====================


For now, I use a one-line script to watch for new named files under time directories and delete them every 3 minutes:


Code:

watch -n 180 'find  proc*/?.*/*.bulk  -type f -mmin +3 -exec rm {} \;'
===================

Picking out and tracing escaped particles with fine time step works really well.

But still have to manually find under the postProcessing directory the time subdirectories where the ascii files' sizes are larger than the minimal--the minimal files just have the first row consisting of labels--, copy them out to a separate new directory, manually collect the data lines into a new text file, and pick out the particles' origId, ages, diameter, etc., etc., from the respective lines (particles), and then go back to manually threshold each origId in ParaView. I did all that.

But, going forward, I would like to automate this.

Without having to touch the source codes of ParaView, it seems the best way forward is to write a shell/Python script to automate all those manual steps, and then use the origIds thus collected to go back to prune the Lagrangian fields under kinematicCloud and kinematicCloudTracks directories to remove entries for all particles whose origIds don't belong among those collected.

I am looking for a ready code to convert the fields from binary to ascii. Utilities/miscellaneous/foamFormatConvert.C may be an example on how to do this.


=============


For now, I use a one-line shell script to collect all lines from all postprocessing files under directory 'postProcessing/lagrangian/kinematicCloud/patchPostProcessing1' for patch '*outlet.post'' larger than 300 characters into a file 'escapes.post':
Code:

find ./?.*/*outlet.post -type f -size +300c -exec ls -l {} \; -exec cat {} \; >> escapes.post
followed by processing the 'escapes.post' file with the following Perl script, ~/bin/foamPostGetTimeAge.pl < escapes.post >escapesTimeOrigidDAge.post



Code:

#!/usr/bin/perl

# OpenFOAM patchPostProcessing *.post file example lines:
# # Time currentProc (coordinatesa coordinatesb coordinatesc coordinatesd) celli tetFacei tetPti facei stepFraction behind nBehind origProc origId active typeId nParticle d dTarget  (Ux Uy Uz) rho age tTurb (UTurbx UTurby UTurbz)(UCorrectx UCorrecty UCorrectz)
# 1.110325 0 (0 0.1457283 0.431808 0.4224637) 45687 267113 2 267113 0.1538822 0 0 0 392 1 -1 90614.17 4.29153e-06 0 (1.816592 1.717728 -5.44917) 1000 0.3692077 0 (0 0 0) (0 0 0)


print "Time origId d age\n";

while ( my $line = <STDIN> ) {

    if ($line =~ /^(\d+\.\d+)\s+/) {
    #if ($line =~ /^(\d+\.\d+)\s+.+(\d+\.\d+)\d+\s+\(.+\)\(.+\)$/) {
        $Time = $1;

        # search 'age' from end of line, e.g. ' 0.3692077 0 (0 0 0) (0 0 0)'
        $line =~ /^(\d.+)\s+(\d+\.\d+)\s+\d+\s+\(\d+\s+\d+\s+\d+\)\s*\(\d+\s+\d+\s+\d+\)$/;
        $age = $2;

        # search the part of the string before ' age' for 'd', e.g. ' 4.29153e-06 0 (1.816592 1.717728 -5.44917) 1000'
        $1 =~ /^(\d.+)\s+(\d+\.\d+e\-\d+)\s+\d+\s+\(\-?\d+\.\d+\s+\-?\d+\.\d+\s+\-?\d+\.\d+\)\s+\d+$/;
        $d = $2;

        # search the part of the string before ' d' for 'origId', e.g. ' 392 1 -1 90614.17'
        $1 =~ /^(\d.+)\s+(\d+)\s+\d+\s+\-?\d+\s+\d+(\.\d+)?$/;
        $origId = $2;

        print "$Time $origId $d $age\n";
    }

}



All times are GMT -4. The time now is 18:30.