AMReX-Codes / amrex

AMReX: Software Framework for Block Structured AMR
https://amrex-codes.github.io/amrex
Other
536 stars 343 forks source link

Question about clear AMReX Particle #3942

Closed S-Explorer closed 4 months ago

S-Explorer commented 4 months ago

Dear developers: I have been using AMReX recently to develop a program for my needs. However, I encountered an issue related to AMReX::Particle. My computational program requires clearing the particles before each calculation and then generating new particle information based on the current state. To achieve this, I iterated through all the particle tiles, resized them to 0, and I also executed particleContainer::clearParticles(), but the calculation results seem to be not what I intended. Could you please advise me on how to correctly clear all particle information and then add new particle information afterwards?

atmyers commented 4 months ago

In what way is the calculation result not as intended? Calling clearParticles() will resize all the particle tiles to zero and clear the empty tiles from the underlying map. Are you seeing particles left over after calling this method? Or is the issue with adding the new ones afterwards?

S-Explorer commented 4 months ago

Thanks! @WeiqunZhang Thank you for your reply. @atmyers Currently, my particle generation call is as follows (pseudo-code):

ParticleContainer mContainer;

for(time_steps)
{
    bool hasResize = false;
    for(MFIter mfi = mContainer->MakeMFIter(LOCAL_LEVEL); mfi.isValid(); ++mfi){
        //get p_tile by gid pid
        auto& particle_tile = mContainer->GetParticles(LOCAL_LEVEL)[std::make_pair(mfi.index(), mfi.tileIndex())];
        //initial particle on IO proc
        if(ParallelDescriptor::MyProc() == ParallelDescriptor::IOProcessorNumber() && !hasResize){
            //change label
            hasResize = true;
            //resize particle tile to p_num
            particle_tile.resize(p_num);
            //get particle data pointer
            auto* pstruct = particle_tile.GetArrayOfStructs()().data();
            auto arrdata = particle_tile.GetStructOfArrays().realarray();
            amrex::ParallelFor(p_num, [=] 
                AMREX_GPU_DEVICE (int i){
                    //deal pstruct and arrdata
                    //Change postion id cpu ...
                }
            );
        }else{
            particle_tile.resize(0);
        }
    }
    //sync
    amrex::ParallelDescriptor::Barrier();
    mContainer->Redistribute();

    calForce_Particle();
    calMoment_particle();
}

I'm not sure if I'm using it correctly.

Regarding the previous errors, I will verify them. I'm not sure if they were caused by the issue of resize(count)

S-Explorer commented 4 months ago

I replaced this solution with clearParticles, and the issue was resolved.

However, I have a question about this comment in the code:

Clear all the particles in this container. This does not free memory.

do not free memory affect subsequent calculations?

atmyers commented 4 months ago

If you want to free the memory, you can call ParticleContainer::ShrinkToFit. But, if you're adding new particles back in, it's probably best not to do this. The old memory will be reused by the new particles.