Interpolation from finer grid to particle? #4931
|
How should I interpolate from finer grid to particle in following program? Now nothing seems to happen. If I change #define AMREX_SPACEDIM 3
#include "AMReX.H"
#include "AMReX_MultiFab.H"
#include "AMReX_ParticleContainer.H"
#include "AMReX_ParticleInterpolators.H"
using namespace std;
using namespace amrex;
using ParticleContainer_ = ParticleContainer<3, 0, 0, 0>;
using Particle_ = ParticleContainer_::ParticleType;
int main(int argc, char* argv[]) {
Initialize(argc, argv); {
Box
box_coarse{IntVect{0, 0, 0}, IntVect{2, 2, 2}},
box_fine{IntVect{2, 2, 2}, IntVect{3, 3, 3}};
Geometry
geom_c{box_coarse, RealBox({-1.5,-1.5,-1.5}, {1.5,1.5,1.5}),
CoordSys::cartesian, Array<int, 3>{0, 0, 0}},
geom_f{box_fine, RealBox({-0.5,-0.5,-0.5}, {0.5,0.5,0.5}),
CoordSys::cartesian, Array<int, 3>{0, 0, 0}};
geom_f.refine(IntVect{2});
BoxArray ba_c, ba_f;
ba_c.define(box_coarse); ba_f.define(box_fine);
DistributionMapping dm_c{ba_c}, dm_f{ba_f};
MultiFab mf_c{ba_c, dm_c, 3, 0}, mf_f{ba_f, dm_f, 3, 0};
for (amrex::MFIter iter(mf_c); iter.isValid(); ++iter) {
const auto& box = iter.validbox();
const auto& arr = mf_c.array(iter);
amrex::ParallelFor(box, [&](int i, int j, int k){
arr(i, j, k, 0) = i;
arr(i, j, k, 1) = j;
arr(i, j, k, 2) = k;
});
}
for (amrex::MFIter iter(mf_f); iter.isValid(); ++iter) {
const auto& box = iter.validbox();
const auto& arr = mf_f.array(iter);
amrex::ParallelFor(box, [&](int i, int j, int k){
arr(i, j, k, 0) = i;
arr(i, j, k, 1) = j;
arr(i, j, k, 2) = k;
});
}
ParticleContainer_ particle_container(
{geom_c, geom_f}, {dm_c, dm_f},
{ba_c, ba_f}, Vector<int>{2});
for (
auto iter = particle_container.MakeMFIter(0);
iter.isValid(); ++iter
) {
auto& particles = particle_container.GetParticles(0)[
std::make_pair(iter.index(), iter.LocalTileIndex())];
Particle_ particle;
particle.id() = 1;
for (int i = 0; i < 3; i++) {
particle.pos(i) = particle.rdata(i) = 0;
}
particles.push_back(particle);
}
particle_container.Redistribute();
for (
ParticleContainer_::ParIterType iter(particle_container, 0);
iter.isValid(); ++iter
) {
const auto& particles = iter.GetArrayOfStructs();
for (const auto& particle: particles) {
cout << "before:";
for (int i = 0; i < 3; i++) {
cout<<particle.pos(i)<<","<<particle.rdata(i)<<",";
} cout<<endl;
}
}
amrex::MeshToParticle(particle_container, mf_f, 1, [&](auto& particle1, const auto& data1){
amrex::ParticleInterpolator::Linear interp(
particle1, geom_f.ProbLoArray(), geom_f.InvCellSizeArray());
interp.MeshToParticle(particle1, data1, 0, 0, 3,
[](const auto& data2, int i, int j, int k, int comp){
return data2(i, j, k, comp);
},
[](auto& particle2, int comp, auto value){
particle2.rdata(comp) += value;
});
});
for (
ParticleContainer_::ParIterType iter(particle_container, 0);
iter.isValid(); ++iter
) {
const auto& particles = iter.GetArrayOfStructs();
for (const auto& particle: particles) {
cout << "after:";
for (int i = 0; i < 3; i++) {
cout<<particle.pos(i)<<","<<particle.rdata(i)<<",";
} cout<<endl;
}
}
} Finalize(); return 0;
} |
Answered by
WeiqunZhang
Feb 4, 2026
Replies: 1 comment 9 replies
|
The way how fine geometry is created is incorrect. The domain passed to the constructor should be the entire domain as if it's refined everywhere. It is almost always the case that the fine Geometry is just See #4907. |
9 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Looks like the answer to your last question might be it does not print anything because the Particle iterator you use is on level 0, not level 1. AI is usually very good at catching these bugs. Here is what it suggests.