/** @file poisson.h * @brief Structures and functions for the Poisson solver */ #ifndef _POISSON_H_ #include "cstream.h" #include "rz_array.h" #ifndef _GRID_H_ #include "grid.h" #endif typedef struct pois_grid_t pois_grid_t; struct pois_grid_t { RECT_COORDS; LEAF_FIELDS(pois_grid_t); int ext_bound; rz_array_t *phi; rz_array_t *charge; rz_array_t *error; }; /*!< With this structure we define a "problem" for the Poisson/Helmholtz solver. * Thus we differentiate between the electrostatic (Poisson) or the * photo-ionization (Helmholtz) uses. */ typedef struct pois_problem_t pois_problem_t; struct pois_problem_t { int max_level; int extra_levels; double max_error; int bnd_right; int bnd_top; int bnd_bottom; }; typedef struct pois_boundaries_t { REAL *left, *right, *top, *bottom; int r, z; } pois_boundaries_t; /*!< Note that the electric fields are computed here as the derivatives * of \f$\phi\f$, and not _minus_ the derivatives. * * This is because our \f$\phi\f$ is not actually the electrostatic potential * in its standard definition but its opposite. This simplifies the computations * since we can use the charge as the source of the Poisson equation. */ #define UNCHECK_ER_RZ(grid_, ir_, iz_) \ (((RZ(grid_->phi, (ir_) + 1, iz_) - RZ(grid_->phi, ir_, iz_)) \ / dr[grid_->level])) #define UNCHECK_EZ_RZ(grid_, ir_, iz_) \ (((RZ(grid_->phi, ir_, (iz_) + 1) - RZ(grid_->phi, ir_, iz_)) \ / dz[grid_->level])) /*!< The easiest way (and not too performance costly) is to check the * boundaries where the field can be calculated. * * Note that, if everything is OK, the 0 there that we set should never be * used again (and hence any number would be ok (use NaN for debugging) */ #define ER_RZ(grid_, ir_, iz_) \ (((ir_) < ((grid_)->r1 + 1) && ((ir_) > ((grid_)->r0 - 2)))? \ UNCHECK_ER_RZ(grid_, ir_, iz_): 0) #define EZ_RZ(grid_, ir_, iz_) \ (((iz_) < ((grid_)->z1 + 1) && ((iz_) > ((grid_)->z0 - 2)))? \ UNCHECK_EZ_RZ(grid_, ir_, iz_): 0) #define _POISSON_H_ #endif