ComputationalRadiationPhysics / picongpu

Performance-Portable Particle-in-Cell Simulations for the Exascale Era :sparkles:
https://picongpu.readthedocs.io
Other
692 stars 218 forks source link

Discrete particle distribution #3150

Closed cbontoiu closed 1 year ago

cbontoiu commented 4 years ago

I am investigating the possibility to generate ordered discrete distribution of atoms and for now I managed to produce something like in the picture attached (yx)

electrons

using

using [struct_name] = EveryNthCellImpl< mCT::UInt32< 20, 20, 10 > >;

in the density.param file.

My next goal is to generate atoms in a circle as shown below.

circle

I am aware of the possibility to generate charge density regions using geometrical parameters such as radius and sector angles but what I want is to place a single atom in a reasonably accurate position. The [Functor] in

using [struct_name] = FreeFormulaImpl< [Functor] >;

would need to use EveryNthCellImpl< mCT::UInt32< 1, 1, 1 > > for the maximum resolution, but really fill the cell with a particle (Carbon atom with 5 bound electrons and 1 free electron) only where required by the geometrical arguments. I imagine I could fill up a matrix with 0 or 1 first and then link it to Functor such that EveryNthCellImpl is replaced with something like EveryNthCellImplIfTrue.

Could anyone help me with this please? Thank you

sbastrakov commented 4 years ago

Hello @cbontoiu .

I believe using EveryNthCellImpl or something derived from it would actually make it more complicated since it inherently generates a Cartesian axis-aligned pattern, which is not what's needed here. However, I believe it is rather straightforward to implement this logic with a custom functor (probably best in the same .param file of your setup) and provide it as argument to FreeFormulaImpl. Inside the functor for operator() you get a cell index as input. Based on that, and parameters of your tube location and how many particles you need "per circle" (as shown in your picture) you decide whether this particular cell has a macroparticle in it or not, and return the corresponding zero or non-zero density. This is structurally what EveryNthCellImpl does, just your condition is a little more complicated.

You plug it in as the first template parameter of CreateDensity for the corresponding particle species (please see this example which uses densityProfiles::ProbeEveryFourthCell in this place). This part would generate macroparticles in the right cells. For exact positioning of generated macroparticles inside the cells, this template has the second parameter. The linked example just puts all of them to the cell origin. In case you only have a macroparticle per several cells (as shown) this might be enough. Fine-tuning for precise positioning is possible with more programming effort. We could assist with it, however I believe it is better to first set up just having macroparticles in the right cells and only then refine the positioning inside the cells.

cbontoiu commented 3 years ago

Hello,

I would kindly ask a few questions on this topic. Suppose I only want to distribute Carbon ions + and an electron for each every 4 or 16 cells in each of the x and y directions. The easiest way to achieve this is by using in the density.param file the EveryNthCellImpl<> functor

image

then in the speciesInitialization.param file I have

image

The model compiles and I can see my Carbon ions and electrons:

image

My questions are:

  1. Do I get a single carbon ion - electron pair every 4 or 16 cells, or I get lumps of charge density?
  2. Why do I still need to define BASE_DENSITY_SI since I only place particles so density is not defined directly?

My calculation shows that indeed I get an electron each location

image

but I just need to make sure.

Thank you very much, As always, greatly appreciated Cristian

sbastrakov commented 3 years ago

I am not sure I understand question 1. What you will get with such a Carbon density is a carbon macroparticfle each 16 cells (in both directions). That is due to CreateDensity in your InitPipeline. Then you derive positions of macroelectrons from positions of macrocarbon.

  1. You always have to define BASE_DENSITY. In such a use case, i think it is logically redundant. However it is technically needed for internal normalizations and to calculate weights of macroparticles.
pordyna commented 3 years ago

@cbontoiu, so EveryNthCellImpl will return a relative density 1 on every Nth cell and 0 on all other cells. This number is multiplied for each cell by BASE_DENSITY_SI * CELL_WIDTH_SI * CELL*HEIGHT_SI * CELL_DEPTH_SI to get a number of real particles in that particular cell. The number of macro particles per cell is defined within the startPosition functor (this is set in particle.param). Then each particle in this cell should have the weighting: #real particles / #macro particles . So if you want to have one macro particle that represents one physical particle in every Nth cell you could set the number of macro particles per cell to 1 and also set BASE_DENSITY_SI to 1.0 / CELL_WIDTH_SI * CELL*HEIGHT_SI * CELL_DEPTH_SI

sbastrakov commented 3 years ago

As a small clarification, the relative density is not 1 or 0. It is in your case 16*16 in 1 cell out of 256 or 0 in the remaining 255 cells.

cbontoiu commented 3 years ago

Thank you both. I understand better now but in my case this particle located at every Nth cell is a Carbon + ion and together with it, there should be an electron. I guess we still talk about 1 macro particle. Then the Carbon+ ion, is ionized by laser and there can be 6 electrons for each C+6 ion. Will the 1 PPC (macro particle) be enough to track the system of charges?

cbontoiu commented 3 years ago

I am trying to simulate the graphene hexagons https://en.wikipedia.org/wiki/Graphene

cbontoiu commented 3 years ago

I am exploring how to distribute atoms in a 2D plane such that I end up with an array of hexagons like the one shown below image This requires two EveryNthCellImpl<mCT::UInt32<nx, ny>>:

I would be grateful if anyone could show me how to mingle if() statements based on coordinates or cell indices with EveryNthCellImpl<mCT::UInt32<nx, ny>>. Otherwise, I can provide the x,y coordinates of the atoms, but I don't know which PIConGPU method should be used to position them.

Thank you. Cristian

BrianMarre commented 1 year ago

Thank you both. I understand better now but in my case this particle located at every Nth cell is a Carbon + ion and together with it, there should be an electron. I guess we still talk about 1 macro particle. Then the Carbon+ ion, is ionized by laser and there can be 6 electrons for each C+6 ion. Will the 1 PPC (macro particle) be enough to track the system of charges?

In your setup the you will initially have one carbon macro-ion and one macro-electron at every of your specified locations, ionization at runtime will then spawn new macro-electrons, with, I believe, ADK/BSI spawning one for every ionization step and Thomas fermi spawning additional macro-electrons each time step to increase the ionization to the expected mean ionization. Therefore the number of macro-electrons will not stay constant over time. Therefore the electron representation is not usually a issue, outside of some special corner cases, more problematic is usually the charge state distribution representation, since the number of macro-ions will not change over time, disregarding movement, and usually the rule of thumb is to at least have a ppc equal o the number of charge states up form you initial state, to allow at least some representation of the charge state distribution.

BrianMarre commented 1 year ago

Secondly the error you got was basically that you were trying to return a c++ type, but declared that you would be returning float_X, you are probably missing an operator call at the end of the line 25.

BrianMarre commented 1 year ago

If you have no further questions, or this issue is no longer relevant, please remember to close it ;)