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/)
-   -   Cloud::storeGlobalPositions has not been called - How to call it? (https://www.cfd-online.com/Forums/openfoam-programming-development/218828-cloud-storeglobalpositions-has-not-been-called-how-call.html)

mrishi July 5, 2019 07:04

Cloud::storeGlobalPositions has not been called - How to call it?
 
I am trying to implement a coupled Lagrangian-interFoam solver in OF-6 where I want to refine the mesh in two-phase interface region using the dynamicFvRefineMesh option.

However, I encounter the following fatal error as soon as the refinement is done before first timestep.

Code:

--> FOAM FATAL ERROR:
Global positions are not available. Cloud::storeGlobalPositions has not been called.

    From function void Foam::Cloud<ParticleType>::autoMap(const Foam::mapPolyMesh&) [with ParticleType = Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> >]
    in file /opt/openfoam6/src/lagrangian/basic/lnInclude/Cloud.C at line 349.

FOAM exiting

I tried to add the following lines to my solver loop:
Code:

          if (pimple.turbCorr())
            {
                turbulence->correct();
            }
        }

        Info<< "Evolving "<< kinematicCloud.name() <<endl;
        kinematicCloud.evolve();
      kinematicCloud.storeGlobalPositions();
        runTime.write();

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;

The code compiles but the same problem persists.
The function storeGlobalPositions() is defined in Cloud.H, which is referenced by basicKinematicCollidingCloud.H. If I try to call it like this:
Code:

Cloud::storeGlobalPositions();
The compiler throws an error that
Code:

interFlow.C:161:2: error: ‘template<class ParticleType> class Foam::Cloud’ used without template parameters
  Cloud::storeGlobalPositions();

I am new to the concept of templates so could someone help me understand and formulate the correct way to call the above function? The kinematicCloud object itself is defined like this in createFields.H:


Code:

//Initialize basicKinematicCollidingCloud

const word kinematicCloudName
(
    args.optionLookupOrDefault<word>("cloudName", "kinematicCloud")
);
Info<< "Constructing kinematic cloud "<< kinematicCloudName <<endl;

basicKinematicCollidingCloud kinematicCloud
(
    kinematicCloudName,
    rho,
    U,
    mu,
    g
);

Thanks for taking time to read this.

mrishi July 5, 2019 07:17

Interestingly, when I do not call the function at all, keeping my code as:
Code:

        Info<< "Evolving "<< kinematicCloud.name() <<endl;
        kinematicCloud.evolve();
        runTime.write();

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;

The code immediately crashes at the very start, when the first refinement is carried out before start of calculations.

Code:

PIMPLE: Iteration 1
Selected 522 cells for refinement out of 6003.
Refined from 6003 to 9657 cells.


--> FOAM FATAL ERROR:
Global positions are not available. Cloud::storeGlobalPositions has not been called.

    From function void Foam::Cloud<ParticleType>::autoMap(const Foam::mapPolyMesh&) [with ParticleType = Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> >]
    in file /opt/openfoam6/src/lagrangian/basic/lnInclude/Cloud.C at line 349.

FOAM exiting


However, when I use the kinematicCloud.storeGlobalPositions(); line at the start of time loop, as so:
Code:


    while (runTime.run())
    {
        #include "readDyMControls.H"

        if (LTS)
        {
            #include "setRDeltaT.H"
        }
        else
        {
            #include "CourantNo.H"
            #include "alphaCourantNo.H"
            #include "setDeltaT.H"
        }

      kinematicCloud.storeGlobalPositions();
        runTime++;

        Info<< "Time = " << runTime.timeName() << nl << endl;

it runs for the first timestep and crashes after refinement at the start of second timestep, as follows:


Code:


PIMPLE: Not converged within 20 iterations
Evolving kinematicCloud

Solving 3-D cloud kinematicCloud
Cloud: kinematicCloud
    Current number of parcels      = 0
    Current mass in system          = 0
    Linear momentum                = (0 0 0)
  |Linear momentum|                = 0
    Linear kinetic energy          = 0
    model1:
        number of parcels added    = 0
        mass introduced            = 0
    Parcel fate (number, mass)      : patch wall
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch top
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch inlet
      - escape                      = 0, 0
      - stick                      = 0, 0
    Rotational kinetic energy      = 0

ExecutionTime = 1.13 s  ClockTime = 1 s

Courant Number mean: 1.91579e-10 max: 3.6554e-08
Interface Courant Number mean: 0 max: 0
deltaT = 1.44e-05
Time = 2.64e-05

PIMPLE: Iteration 1
Selected 2088 cells for refinement out of 9657.
Refined from 9657 to 24273 cells.

Followed by the same error as before, which indicates that the function call does achieve some purpose, except it does not propagate properly through the next step? But why would this be the case, since it is the same loop?


I would really appreciate help on this!! :(

clapointe July 5, 2019 08:42

This is a case when foam tells us what to do, but I guess the timing of the call can be a bit ambiguous. Try storing the global positions right before calling mesh.update().

Caelan

mrishi July 5, 2019 10:25

Quote:

Originally Posted by clapointe (Post 738091)
This is a case when foam tells us what to do, but I guess the timing of the call can be a bit ambiguous. Try storing the global positions right before calling mesh.update().

Caelan


Hi Caelan, thanks!
Following from your advice, I made some markers in the solver file to see how solution and function calls progress.

Code:


      while (pimple.loop())
      {

          kinematicCloud.storeGlobalPositions();
          Info<<"stored Global Positions"<<endl;
          if (pimple.firstIter() || moveMeshOuterCorrectors)
          {

                  mesh.update();
                  Info<<"Updated mesh"<<endl;

Calling it from within the firstIter() or from outside it, does not make a difference, except getting called every iteration.


Code:

Courant Number mean: 0 max: 0
Interface Courant Number mean: 0 max: 0
deltaT = 1.2e-05
Time = 1.2e-05

PIMPLE: Iteration 1
stored Global Positions
Selected 522 cells for refinement out of 6003.
Refined from 6003 to 9657 cells.
Selected 0 split points out of a possible 522.
Updated mesh
entered mesh.changing loop
Mesh.topoChanging

GAMGPCG:  Solving for pcorr, Initial residual = 0, Final residual = 0, No Iterations 0
GAMGPCG:  Solving for pcorr, Initial residual = 0, Final residual = 0, No Iterations 0
time step continuity errors : sum local = 0, global = 0, cumulative = 0
MULES: Solving for alpha.water
...
PIMPLE: Iteration 2
stored Global Positions
MULES: Solving for alpha.water
...
PIMPLE: Not converged within 20 iterations
Evolving kinematicCloud

Solving 3-D cloud kinematicCloud
Cloud: kinematicCloud
    Current number of parcels      = 0
    Current mass in system          = 0
    Linear momentum                = (0 0 0)
  |Linear momentum|                = 0
    Linear kinetic energy          = 0
    model1:
        number of parcels added    = 0
        mass introduced            = 0
    Parcel fate (number, mass)      : patch wall
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch top
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch inlet
      - escape                      = 0, 0
      - stick                      = 0, 0
    Rotational kinetic energy      = 0

Stored GlobalPositions post evolve.
ExecutionTime = 1.77 s  ClockTime = 2 s

Courant Number mean: 1.92618e-10 max: 3.67149e-08
Interface Courant Number mean: 0 max: 0
deltaT = 1.44e-05
Time = 2.64e-05

PIMPLE: Iteration 1
stored Global Positions
Selected 2088 cells for refinement out of 9657.
Refined from 9657 to 24273 cells.


--> FOAM FATAL ERROR:
Global positions are not available. Cloud::storeGlobalPositions has not been called.

    From function void Foam::Cloud<ParticleType>::autoMap(const Foam::mapPolyMesh&) [with ParticleType = Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> >]
    in file /opt/openfoam6/src/lagrangian/basic/lnInclude/Cloud.C at line 349.

FOAM exiting

From here it seems that the error is generated from within mesh.update(), whereas this was not a problem during the first timestep.

This same storeGlobalPositions function enables the solution to go through the first timestep, wouldn't that mean that it is being read by mesh.update()?

It seems there is some communication gap after kinematicCloud.evolve(). If I do the following, once again the error is thrown from within mesh.update.


Code:


  Info<< "Evolving "<< kinematicCloud.name() <<endl;
  kinematicCloud.evolve();
  kinematicCloud.storeGlobalPositions();
  Info<<"Stored GlobalPositions post evolve."<<endl;
  mesh.update();
  runTime.write();

  Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
      << "  ClockTime = " << runTime.elapsedClockTime() << " s"
      << nl << endl;


clapointe July 5, 2019 10:51

Well I am not immediately sure why this is happening, but I just did a quick search for "storeGlobalPositions()" and this solver came up : https://github.com/OpenFOAM/OpenFOAM...icParcelFoam.C. You might try comparing your solver to this one.

Caelan

mrishi July 5, 2019 11:46

Quote:

Originally Posted by clapointe (Post 738115)
Well I am not immediately sure why this is happening, but I just did a quick search for "storeGlobalPositions()" and this solver came up : https://github.com/OpenFOAM/OpenFOAM...icParcelFoam.C. You might try comparing your solver to this one.

Caelan


Thanks for the pointer! An almost exact code is implemented in OF-6 as a separate solver icoUncoupledKinematicParcelDyMFoam which takes the standard solver and adds the lines for storeGlobalPositions, mesh.update and mesh.change. I took that solver and set it up over my domain such that at each timestep, the entire domain gets refined 6000 => 48000 => 380,000 and so on..

Even here, while the first refinement works the solution collapses at the second timestep.


Code:



Time = 0.001

Selected 6003 cells for refinement out of 6003.
Refined from 6003 to 48024 cells.
Selected 0 split points out of a possible 6003.
Evolving kinematicCloud

Solving 3-D cloud kinematicCloud

Cloud: kinematicCloud injector: model1
    Added 2 new parcels

Cloud: kinematicCloud
    Current number of parcels      = 2
    Current mass in system          = 7.86984e-08
    Linear momentum                = (4.66267e-11 2.4542e-08 8.70437e-11)
  |Linear momentum|                = 2.45422e-08
    Linear kinetic energy          = 3.82683e-09
    model1:
        number of parcels added    = 2
        mass introduced            = 7.86984e-08
    Parcel fate (number, mass)      : patch wall
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch top
      - escape                      = 0, 0
      - stick                      = 0, 0
    Parcel fate (number, mass)      : patch inlet
      - escape                      = 0, 0
      - stick                      = 0, 0
    Rotational kinetic energy      = 0

ExecutionTime = 0.76 s  ClockTime = 1 s

Time = 0.002

Selected 48024 cells for refinement out of 48024.
Refined from 48024 to 384192 cells.


--> FOAM FATAL ERROR:
Global positions are not available. Cloud::storeGlobalPositions has not been called.

    From function void Foam::Cloud<ParticleType>::autoMap(const Foam::mapPolyMesh&) [with ParticleType = Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> >]
    in file /opt/openfoam6/src/lagrangian/basic/lnInclude/Cloud.C at line 349.

FOAM exiting

Although it seems to run okay with the tutorial case for this solver, where the mesh is dynamic in the sense that it is moving (not refining).

clapointe July 5, 2019 12:11

Have you tried running the tutorial with a dynamic mesh that changes the number of cells? We are quickly approaching the end of my (limited) knowledge of foam LPT, so I'm running out of ideas. Have you tried one of the other types of particle clouds?

Caelan

mrishi July 5, 2019 15:40

Quote:

Originally Posted by clapointe (Post 738120)
Have you tried running the tutorial with a dynamic mesh that changes the number of cells? We are quickly approaching the end of my (limited) knowledge of foam LPT, so I'm running out of ideas. Have you tried one of the other types of particle clouds?

Caelan


I haven't tried with other clouds, but I feel the problem would persist because both these functions storeGlobalPositions and autoMap are being inherited from the Cloud class (is that nomenclature correct?)

I did the refinement effect with the tutorial as for my own case. I replaced the moving dynamicMeshDict, with entries for refining. Same as before, I imposed conditions so as to refine the entire mesh, with nothing else happening.
The same error appeared at the end of first refine.


This is how the autoMap function is written, which throws the error.

Code:


template<class ParticleType>
void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
{
    if (!globalPositionsPtr_.valid())
    {
        FatalErrorInFunction
            << "Global positions are not available. "
            << "Cloud::storeGlobalPositions has not been called."
            << exit(FatalError);
    }

    // Ask for the tetBasePtIs to trigger all processors to build
    // them, otherwise, if some processors have no particles then
    // there is a comms mismatch.
    polyMesh_.tetBasePtIs();

    const vectorField& positions = globalPositionsPtr_();

    label i = 0;
    forAllIter(typename Cloud<ParticleType>, *this, iter)
    {
        iter().autoMap(positions[i], mapper);
        ++ i;
    }
}

And the storeGlobalPositions function:
Code:


template<class ParticleType>
void Foam::Cloud<ParticleType>::storeGlobalPositions() const
{
    // Store the global positions for later use by autoMap. It would be
    // preferable not to need this. If the mapPolyMesh object passed to autoMap
    // had a copy of the old mesh then the global positions could be recovered
    // within autoMap, and this pre-processing would not be necessary.

    globalPositionsPtr_.reset(new vectorField(this->size()));

    vectorField& positions = globalPositionsPtr_();

    label i = 0;
    forAllConstIter(typename Cloud<ParticleType>, *this, iter)
    {
        positions[i] = iter().position();
        ++ i;
    }
}

I have a few questions?

Is there some meaningful info we can extract after the second one is executed, so as to see what kind of information is actually getting stored? What sort of query would that be to get some sort of information printed for positions.size() or the globalPositionsPtr_(). That way we may be able to see how things are changing before and after evolve()


Secondly,
what is this argument being passed to autoMap - const mapPolyMesh& mapper? I could not understand how this function is getting called when mesh.update() is called, as there is no reference in the update() function to Cloud.autoMap().






I tried to check validity of globalPositionsPtr_ before mesh.update(), using:
Code:


  if (pimple.firstIter() || moveMeshOuterCorrectors)
  {
          kinematicCloud.storeGlobalPositions();
          Info<<"stored Global Positions"<<endl;
          if(kinematicCloud.globalPositionsPtr_.valid())
                  Info<<"Valid position"<< endl;
          else Info<<"Invalid position"<<endl;
          mesh.update();
          Info<<"Updated mesh"<<endl;


but I am unable to compile it as it declared as private:
Code:

/opt/openfoam6/src/lagrangian/basic/lnInclude/Cloud.H:82:38: note: declared private here
        mutable autoPtr<vectorField> globalPositionsPtr_;
                                      ^~~~~~~~~~~~~~~~~~~


raumpolizei July 6, 2019 04:11

hey mrishi,
I had some time to take a look at your issue. I have similar plans as you but I have not started yet so maybe we will have the possibility to have some knowledge exchange concerning this matter.
Regarding your problem, I took a look at the FatalError you are getting in your simulations and it looks like the error is coming from fvMesh::update calling fvMesh::mapFields calling the free function mapClouds, which is then calling the Cloud::autoMap function. From that you can reason that before updating the mesh, the globalPositionPtr_ member in Foam::Cloud has to be set. However in every Cloud::move call (function called during updates of the cloud, the globalPositionPtr_ is cleared, see the documentation: https://www.openfoam.com/documentati...8C_source.html). cloud.storeGlobalPositions() has therefore to be called after every cloud.evolve() (in your code kinematicCloud) for autoMap to function properly. In addition to that and depending on when the first mesh update is performed, the pointer to the global position field will have to be set directly after constructing the cloud (probably in your createClouds.H, looks better this way). I think this can make it work and these are the only assumptions I can make without seeing the part of the code containing the cloud and mesh updating function calls (as one part).
Hope this helps and sorry for not answering all of your questions. Good luck with your task!
RP

mrishi July 6, 2019 18:07

Hi Caelan,

I tried the same with a simpler basickinematicCloud instead of my earlier basicKinematicCollidingCloud (which did a lot of back and forth function calling between CollidingCloud and KinematicCloud)and the problem persists.

It seems that this issue will persist for all types deriving from Cloud.H as raumpolizei suggests - Cloud::move function clears globalPositionPtr_ , and following this it seems even when I try to restore it subsequently, it doesn't work properly.




Hi raumpolizei,
Thanks a lot for taking the time. These pointers are very useful.

Quote:

Originally Posted by raumpolizei (Post 738148)
it looks like the error is coming from fvMesh::update calling fvMesh::mapFields calling the free function mapClouds, which is then calling the Cloud::autoMap function.

I too traced the calls, it goes from dynamicFvRefineMesh::update -> dynamicFvRefineMesh::refine -> updateMesh(map) where map is defined after refinement by
Code:

224  autoPtr<mapPolyMesh> mapPtr = meshMod.changeMesh(*this, false);
225  mapPolyMesh& map = *mapPtr;

which I take it is a pointer between the old and new meshes (I remember something similar in meshToMesh or mapFields).

This is followed by meshUpdate(map) which I guess you referred as call to mapFields, although I can't locate the definition of this function, so that I could trace it to mapClouds/Cloud::autoMap. Infact nothing turns up with
grep -r "::meshUpdate" in $FOAM_SRC!!

That being said,

Quote:


From that you can reason that before updating the mesh, the globalPositionPtr_ member in Foam::Cloud has to be set. However in every Cloud::move call (function called during updates of the cloud, the globalPositionPtr_ is cleared, see the documentation: https://www.openfoam.com/documentati...8C_source.html). cloud.storeGlobalPositions() has therefore to be called after every cloud.evolve() (in your code kinematicCloud) for autoMap to function properly.

indeed the the trail on the cloud side goes from KinematicCloud::evolve -> KinematicCloud::solve -> KinematicCloud::evolveCloud ->KinematicCloud::motion -> Cloud::move (the base class)
where the globalPositionPtr_ gets reset...and then on to postEvolve and return.
Quote:

In addition to that and depending on when the first mesh update is performed, the pointer to the global position field will have to be set directly after constructing the cloud (probably in your createClouds.H, looks better this way). I think this can make it work and these are the only assumptions I can make without seeing the part of the code containing the cloud and mesh updating function calls (as one part).
Hope this helps and sorry for not answering all of your questions. Good luck with your task!
RP
I have tried inserting the call to storeGlobalPositions at various points : namely the main code before calling cloud.evolve(),
at the end of cloud::solve(),
at the end of cloud::motion()
but to no avail. :(

Code:

template<class CloudType>
template<class TrackCloudType>
void Foam::KinematicCloud<CloudType>::motion
(
    TrackCloudType& cloud,
    typename parcelType::trackingData& td
)
{
    td.part() = parcelType::trackingData::tpLinearTrack;
    CloudType::move(cloud, td, solution_.trackTime());
    Info<<"Cloud move"<<endl;
    updateMesh();
    updateCellOccupancy();
    CloudType::storeGlobalPositions(); //Taking hint from move() above

    this->storeGlobalPositions();          //Also seems valid, since cloud.storeGlobalPos seems to work in main code.

 }


mrishi July 6, 2019 18:30

OK, this is interesting.

Quote:

indeed the the trail on the cloud side goes from KinematicCloud::evolve -> KinematicCloud::solve -> KinematicCloud::evolveCloud ->KinematicCloud::motion -> Cloud::move (the base class)
where the globalPositionPtr_ gets reset...and then on to postEvolve and return.
I suppressed the call to Cloud::move (..which resets globalPositionsPtr_). and it turns out that I still get the error. So that eliminates this function as the culprit. This does not surprise me because if this was the source of error, then it would not interfere as I have been calling the storeGlobalPositions once again, just prior to mesh.update.


Two things are important here:
The problem appears from within kinematicCloud.evolve(). - if the call is suppressed, the refinement goes on, PROVIDED that there is a call to kinematicCloud.storeGlobalPositions() before mesh.update()
If the above is not called, then mesh.update fails, even in absence of evolve.


So, storeGlobalPositions() placed before mesh.update() seems to work as intended, while evolve() makes some change which fails the next call to storeGlobalPositions(), wherever that may be placed.



So I believe we need to look at the calls in evolve():



it just calls solve(), where we have :
preEvolve()
evolveCloud()
motion

and
postEvolve()

motion() doesn't really do anything except call move(), so that is harmless as we have established already.





On the other end of possibility we have autoMap unable to register that storeGlobalPositions() was called just before mesh.update().
If I setup my solver such that, I store the GlobalPositions at start of run (outside of runTime loop) and I am able to carry out one mesh.update(). I have specified in my dynamicMeshDict to allow only one level of refinement, which means that the first timestep runs as before, and after cloud.evolve() there is no more immediate call to mesh.update(). As a result the globalPositionPtr_ is not asked for and solution continues for a few timesteps, until when there has been substantial flow in the domain. Now fresh cells become candidates for their one level refinement and once again the error pops up.

clapointe July 6, 2019 18:44

Hi All,

I've been following along and agree with what's been said. What is odd is that some native solvers call storeGlobalPositions, so perhaps clearing of the pointer is anticipated and it is supposed to be a fix. However, it must not be functioning as it should -- or the autoMap doesn't register that it has indeed been called. So, I added statements to print globalPositionsPtr_.valid() in the storeGlobalPositions member function, as well as the autoMap function. Here's the output :

Code:

In storeGlobalPositions, globalPositionsPtr_.valid() : 1

Selected 960 cells for refinement out of 960.
Refined from 960 to 7680 cells.

In autoMap, globalPositionsPtr_.valid() : 0

.

So we see that it did get reset. Now, let us try adding the code from storeGlobalPositions to the autoMap bit. In the process of recompiling now, so will edit after that finishes with the result.

Code:

Selected 7680 cells for refinement out of 7680.
Refined from 7680 to 61440 cells.

In autoMap, globalPositionsPtr_.valid(), before reseting : 0


In autoMap, globalPositionsPtr_.valid(), after reseting : 1


In autoMap, globalPositionsPtr_.valid(), before reseting : 1


In autoMap, globalPositionsPtr_.valid(), after reseting : 1

Selected 0 split points out of a possible 7680.
Selected 0 total split points.
Selected 0 mutual split points.
Evolving kinematicCloud

Solving 3-D cloud kinematicCloud

The previous snippet is the result of adding the code from storeGlobalPositions member function to the autoMap member function. Apparently autoMap is called a few times, but the solver (icoUncoupledKinematicParcelFoam) did make it past the refinement step. While this is certainly not the most efficient solution, it does appear to be working...

Caelan

mrishi July 7, 2019 08:45

Hi All,
The method suggested by clapointe does avoid the error!

I'm running it to if the results make sense. But I have some reservations at this point. Here is the output surrounding three refinements (surrounding first two timesteps.)

At the start of first timestep...

Code:


PIMPLE: Iteration 1
In storeGlobalPositions initial globalPositionsPtr_.valid(): 0 //very first call at start of run, called from solver, it is redundant.
In storeGlobalPositions initial globalPosiitionPtr_.valid(): 1
Selected 522 cells for refinement out of 6003.
Refined from 6003 to 9657 cells.
In autoMap initial  globalPositionsPtr_.valid()1 //detected
size: 0 //size of cloud (number of parcel positions in the cloud)
In autoMap after storeGlobPos globalPosiitionPtr_.valid()1 //storePositions is added into autoMap code
Selected 0 split points out of a possible 522.

....first time step...

Code:

Time = 0.00263616

PIMPLE: Iteration 1
In storeGlobalPositions initial globalPositionsPtr_.valid(): 0//Reset by evolve()
In storeGlobalPositions initial globalPosiitionPtr_.valid(): 1
Selected 2088 cells for refinement out of 9657.
Refined from 9657 to 24273 cells.
In autoMap initial  globalPositionsPtr_.valid()1  //detects correctly
size: 2 //two parcels were injected in this timestep
In autoMap after storeGlobPos globalPosiitionPtr_.valid()1
In autoMap initial globalPositionsPtr_.valid()0 //a second call happens this time around where the pointer appears reset.
size: 0 //no parcels this time around
In autoMap after storeGlobPos globalPosiitionPtr_.valid()1
Selected 0 split points out of a possible 2088.

..the next timestep..


Code:

Courant Number mean: 1.10409e-06 max: 0.00336515
Interface Courant Number mean: 0 max: 0
deltaT = 0.00172256
Time = 0.00435873

PIMPLE: Iteration 1
In storeGlobalPositions initial globalPositionsPtr_.valid(): 0 //again reset by evolve()
In storeGlobalPositions initial globalPosiitionPtr_.valid(): 1
Selected 8352 cells for refinement out of 24273.
Refined from 24273 to 82737 cells.
In autoMap initial  globalPositionsPtr_.valid()1
size: 4 //4 parcels exist in the cloud at this time.
In autoMap after storeGlobPos globalPosiitionPtr_.valid()1
In autoMap initial globalPositionsPtr_.valid()1 //Not 0 like previous step!
size: 0
In autoMap after storeGlobPos globalPosiitionPtr_.valid()1

The functions involved are the same ..evolve which resets, store which restores, and autoMap which reads first, but then doesn't.. (but also does). I am concerned by this strange behaviour, as it could lead to erroneous positions.

I'll update this based on how the solution is evolving, because it seems that the parcel info is not completely lost between the two calls to map.

Things get pretty slow after refining at the interface (6000 -> 1lakh + cells)and I am facing a strange trouble with -parallel: the Courant number suddenly shoots up from 0.01 to 7+ over a single timestep(unrelated to mesh/cloud change). This doesn't happen in serial run. So, as of now working to fix that and waiting on the slowly chugging serial case to see what is happening there.

joaran September 20, 2019 14:58

Hi there! I'm facing the same issue here. Were you finally able to get correct results for the evolution of the particles? To be honest I'm kinda confused about how you solved the problem. Could you please summarize what you did?
Thank you!


Joa

mrishi September 21, 2019 14:48

Quote:

Originally Posted by joaran (Post 745122)
Hi there! I'm facing the same issue here. Were you finally able to get correct results for the evolution of the particles? To be honest I'm kinda confused about how you solved the problem. Could you please summarize what you did?
Thank you!


Joa


Hey Joa,


Check out the functions storeGlobalPositions and autoMap in Cloud.C.

What clapointe diagnosed and suggested is that these two are not communicating properly.

I used the storeGlobalPositions code as reference and explicitly added the snippet into the autoMap function. This corrected the tracking problem.

It did not fully solve the case though, but that is because when my refined mesh goes back to coarseing somewhere, it leads to problem of some particle getting unindexed. I have not given time to that part of the problem as I am working with some other aspects, but it seems fixable.


cheers!

OPFO November 18, 2019 05:29

Hello All,

I am trying to incorporate the dynamic mesh function into my custom solver based on icoReactingMultiphaseInterFoam.

For the Cloud.C file, can someone help me understand how exactly to add the snippet from storeGlobalPositions to the AutoMap function?

Would it be something like this?

template<class ParticleType>
void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
{

globalPositionsPtr_.reset(new vectorField(this->size())); // added this line (from storeGlobalPositions)

vectorField& positions = globalPositionsPtr_(); // added this line (from storeGlobalPositions)

if (!globalPositionsPtr_.valid())
{
FatalErrorInFunction
<< "Global positions are not available. "
<< "Cloud::storeGlobalPositions has not been called."
<< exit(FatalError);
}

// Ask for the tetBasePtIs to trigger all processors to build
// them, otherwise, if some processors have no particles then
// there is a comms mismatch.
polyMesh_.tetBasePtIs();

const vectorField& positions = globalPositionsPtr_();

label i = 0;
forAllIter(typename Cloud<ParticleType>, *this, iter)
{
positions[i] = iter().position(); // added this line (from storeGlobalPositions)
iter().autoMap(positions[i], mapper);
++ i;
}
}

template<class ParticleType>
void Foam::Cloud<ParticleType>::storeGlobalPositions() const
{
// Store the global positions for later use by autoMap. It would be
// preferable not to need this. If the mapPolyMesh object passed to autoMap
// had a copy of the old mesh then the global positions could be recovered
// within autoMap, and this pre-processing would not be necessary.

// globalPositionsPtr_.reset(new vectorField(this->size())); // commented out

// vectorField& positions = globalPositionsPtr_(); // commented out

//label i = 0; // commented out
//forAllConstIters(*this, iter) // commented out
//{ // commented out
//positions[i] = iter().position(); // commented out
//++i; // commented out
//} // commented out
}

This will compile my solver, but when I run it with a case, OF cannot properly handle the DTRMparticles which relies on Cloud.C so I'm pretty sure that something is not right in the way I combined storeGlobalPositions into AutoMap.

Thanks!

jairoandres January 28, 2021 19:46

Error when tracking a particle when the containing cell is unrefined
 
Dear Foamers, I have been experiencing a similar issue (tracking error) that happens when the cell containing the particle is unrefined. The error is FOAM FATAL ERROR: (openfoam-2012) Cell not found for particle position (-0.0056421567 -0.081679551 -0.0117107). :

I posted a ticket in OpenFOAM.com but if someone here has experienced something similar, I'd like to know how you dealt with this issue. The ticket is: https://develop.openfoam.com/Develop.../-/issues/1992

Thank you all.


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