CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Running, Solving & CFD

icoUncoupledKinematicParcelFoam

Register Blogs Community New Posts Updated Threads Search

Like Tree20Likes

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   June 17, 2020, 07:47
Default
  #21
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
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.
Mars409 is offline   Reply With Quote

Old   June 17, 2020, 08:29
Default
  #22
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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
amuzeshi likes this.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   June 17, 2020, 11:22
Default
  #23
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
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.
Mars409 is offline   Reply With Quote

Old   June 17, 2020, 15:37
Default
  #24
Senior Member
 
Ali Shayegh
Join Date: Oct 2015
Posts: 131
Rep Power: 11
amuzeshi is on a distinguished road
Quote:
Originally Posted by Mars409 View Post
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 .
amuzeshi is offline   Reply With Quote

Old   June 18, 2020, 03:03
Default
  #25
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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 ); 
} 
}
amuzeshi and Mars409 like this.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   June 18, 2020, 05:01
Default
  #26
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
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) Information about particles going through an internal surface

(4) How can I plot lagrangian particles leaving through a patch? and,

(5) Lagrangian data - particle velocity post processing

This will keep me busy for a day.
amuzeshi and sourav90 like this.
Mars409 is offline   Reply With Quote

Old   June 19, 2020, 13:23
Default
  #27
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
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.

Last edited by Mars409; June 20, 2020 at 08:56. Reason: Newer thoughts and doubts.
Mars409 is offline   Reply With Quote

Old   June 20, 2020, 09:27
Default
  #28
Senior Member
 
Ali Shayegh
Join Date: Oct 2015
Posts: 131
Rep Power: 11
amuzeshi is on a distinguished road
Quote:
Originally Posted by Mars409 View Post
...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?
amuzeshi is offline   Reply With Quote

Old   June 20, 2020, 10:55
Default
  #29
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
Setting MIN=origID and MAX=origID does it.
Mars409 is offline   Reply With Quote

Old   June 21, 2020, 00:55
Default
  #30
Senior Member
 
Ali Shayegh
Join Date: Oct 2015
Posts: 131
Rep Power: 11
amuzeshi is on a distinguished road
Quote:
Originally Posted by Mars409 View Post
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?
amuzeshi is offline   Reply With Quote

Old   June 22, 2020, 05:41
Default
  #31
Member
 
Join Date: May 2020
Posts: 31
Blog Entries: 1
Rep Power: 6
Mars409 is on a distinguished road
Quote:
Originally Posted by Tobi View Post
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";
    }

}

Last edited by Mars409; June 26, 2020 at 02:47. Reason: Additional kludges.
Mars409 is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On



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