Files
@ b7792cb187f7
Branch filter:
Location: MD/arcos/include/grid.h
b7792cb187f7
5.0 KiB
text/x-chdr
Edited file README via RhodeCode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | /** @file grid.h
* @brief Definitions for working with general grids.
*/
#ifndef _GRID_H_
#ifndef _TREE_H_
# include "tree.h"
#endif
#define RECT_COORDS int r0, r1, z0, z1, ntheta
/*!< Coordinate names for the grids */
#define BND_AT_R 0
#define BND_AT_Z 2
#define BND_MIN 0
#define BND_MAX 1
#define BND_LEFT (BND_AT_R | BND_MIN)
#define BND_RIGHT (BND_AT_R | BND_MAX)
#define BND_BOTTOM (BND_AT_Z | BND_MIN)
#define BND_TOP (BND_AT_Z | BND_MAX)
#define BND_MASK(B_) (1 << (B_))
#define BND_NONE 0
#define BND_MASK_LEFT BND_MASK(BND_LEFT)
#define BND_MASK_RIGHT BND_MASK(BND_RIGHT)
#define BND_MASK_BOTTOM BND_MASK(BND_BOTTOM)
#define BND_MASK_TOP BND_MASK(BND_TOP)
#define BND_MASK_ALL (BND_MASK_LEFT | BND_MASK_RIGHT\
| BND_MASK_BOTTOM | BND_MASK_TOP)
#define GRID_INSIDE (1 << (BND_TOP + 1))
/* Locations of the cell centers. */
#define r_at(r_, level_) (((double) (r_) + 0.5) * dr[level_])
#define z_at(z_, level_) (((double) (z_) + 0.5) * dz[level_])
#define theta_at(theta_) ((double) (theta_) * dtheta)
/* Locations of the electric field. */
#define er_r_at(i_, level_) ((i_ + 1) * dr[level_])
#define er_z_at(j_, level_) (((double) (j_) + 0.5) * dz[level_])
#define ez_r_at(i_, level_) (((double) (i_) + 0.5) * dr[level_])
#define ez_z_at(j_, level_) ((j_ + 1) * dz[level_])
#define etheta_theta_at(i_) (((double) (i_) + 0.5) * dtheta)
/** We can produce easily a true 2d code by replacing r when it appears
* due to the cylindrical coordinates by this macros. This has a rather
* large performance penalty, so it is better to do that in compile time
*/
/* Locations of the electric field. */
#ifdef TRUE2D
# define cyl_q(X_) 1
# define cyl_er_r_at(i_, level_) 1
# define cyl_r_at(r_, level_) 1
#else
# define cyl_q(X_) (X_)
# define cyl_er_r_at(i_, level_) er_r_at(i_, level_)
# define cyl_r_at(r_, level_) r_at(r_, level_)
#endif
/* These are shortcuts to make the iteration over grid cells easier.
* Note that it is important that the inner loop has the smallest
* stride to minimize the cache faults.
*/
#define iter_grid_z(grid_, iz_) \
for(iz_ = grid_->z0; iz_ < grid_->z1; iz_++)
#define iter_grid_r(grid_, ir_) \
for(ir_ = grid_->r0; ir_ < grid_->r1; ir_++)
#define iter_grid_theta(grid_, it_) \
for(it_ = 0; it_ < grid_->ntheta; it_++)
#define iter_grid(grid_, ir_, iz_) \
iter_grid_z(grid_, iz_) \
iter_grid_r(grid_, ir_)
#define iter_grid_3d(grid_, ir_, iz_, it_) \
iter_grid_theta(grid_, it_) \
iter_grid_z(grid_, iz_) \
iter_grid_r(grid_, ir_)
/* Functions to iterate over the grids _including_ 1 extra boundary */
#define iter_grid_z_1(grid_, iz_) \
for(iz_ = grid_->z0 - 1; iz_ < grid_->z1 + 1; iz_++)
#define iter_grid_r_1(grid_, ir_) \
for(ir_ = grid_->r0 - 1; ir_ < grid_->r1 + 1; ir_++)
#define iter_grid_1(grid_, ir_, iz_) \
iter_grid_z_1(grid_, iz_) \
iter_grid_r(grid_, ir_)
#define iter_grid_3d_1(grid_, ir_, iz_, it_) \
iter_grid_theta(grid_, it_) \
iter_grid_z_1(grid_, iz_) \
iter_grid_r_1(grid_, ir_)
/* These include n extra cells in the boundary. We avoid that when
* ntheta == 1 because we are in the 2D case and there are no boundaries
* in theta*/
#define iter_grid_theta_n(grid_, it_, n_) \
for(it_ = (grid_->ntheta == 1? 0: -n_); it_ < grid_->ntheta \
+ (grid_->ntheta == 1? 0: n_); it_++)
#define iter_grid_z_n(grid_, iz_, n_) \
for(iz_ = grid_->z0 - n_; iz_ < grid_->z1 + n_; iz_++)
#define iter_grid_r_n(grid_, ir_, n_) \
for(ir_ = grid_->r0 - n_; ir_ < grid_->r1 + n_; ir_++)
#define iter_grid_n(grid_, ir_, iz_, n_) \
iter_grid_z_n(grid_, iz_, n_) \
iter_grid_r_n(grid_, ir_, n_)
#define iter_grid_3d_n(grid_, ir_, iz_, it_, n_) \
iter_grid_theta_n(grid_, it_, n_) \
iter_grid_z_n(grid_, iz_, n_) \
iter_grid_r_n(grid_, ir_, n_)
/* Iter through the parent indices that fill one grid. */
#define iter_grid_parent(grid_, ir_, iz_) \
for(ir_ = (grid_->r0 >> 1) + (grid_->r0 % 2); \
ir_ < (grid_->r1 >> 1); ir_++) \
for(iz_ = (grid_->z0 >> 1) + (grid_->z0 % 2); \
iz_ < (grid_->z1 >> 1); iz_++)
/** @brief The cdr grids and poisson grids types are cdr_grid_t and
* pois_grid_t, defined in cdr.h and poisson.h.
*
* This structure contains the common parts of both structures and
* thus can be used in general routines that accept any kind of grid.
* The C standard promises that we can du this.
*/
typedef struct grid_t grid_t;
struct grid_t {
RECT_COORDS;
LEAF_FIELDS(grid_t);
/* ext_bound indicates which boundaries are external boundaries.
e.g. ext_bound & BND_LEFT_TOP tells us whether the left-top boundary
is an external one. */
int ext_bound;
};
/** @brief To ease typing, you can write e.g.
* printf ("Solving grid (" grid_printf_str ")\n", grid_printf_args(grid));
*/
#define grid_printf_str "{r0 = %d, z0 = %d, r1 = %d, z1 = %d, level = %d}"
#define grid_printf_args(G_) (G_)->r0, (G_)->z0, (G_)->r1, (G_)->z1, \
(G_)->level
#define _GRID_H_
#endif
|