Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_POISSON_SOLVER_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_POISSON_SOLVER_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <cmath>
00013
00014 #include <OpenTissue/core/containers/grid/util/grid_compute_sign_function.h>
00015 #include <OpenTissue/core/math/math_vector3.h>
00016
00017 namespace OpenTissue
00018 {
00019 namespace grid
00020 {
00021
00065 template < typename grid_type >
00066 inline void poisson_solver(
00067 grid_type & phi
00068 , grid_type const & W
00069 , size_t max_iterations = 10
00070 )
00071 {
00072 using std::min;
00073
00074 typedef typename grid_type::value_type value_type;
00075 typedef typename grid_type::const_iterator const_iterator;
00076 typedef typename grid_type::index_iterator index_iterator;
00077 typedef typename grid_type::math_types math_types;
00078 typedef typename math_types::real_type real_type;
00079
00080 size_t I = phi.I();
00081 size_t J = phi.J();
00082 size_t K = phi.K();
00083 real_type dx = phi.dx();
00084 real_type dy = phi.dy();
00085 real_type dz = phi.dz();
00086
00087 if(dx!=dy || dx!=dz || dy!=dz)
00088 {
00089
00090
00091 real_type a0 = dx*dx*dy*dy;
00092 real_type a1 = dx*dx*dz*dz;
00093 real_type a2 = dy*dy*dz*dz;
00094 real_type a3 = dx*dx*dy*dy*dz*dz;
00095 real_type a4 = 1.0/(2*(a0 + a1 + a2));
00096
00097 for(size_t iteration=0;iteration<max_iterations;++iteration)
00098 {
00099 index_iterator p = phi.begin();
00100 index_iterator p_end = phi.end();
00101 const_iterator w = W.begin();
00102 for(;p!=p_end;++p,++w)
00103 {
00104 size_t i = p.i();
00105 size_t j = p.j();
00106 size_t k = p.k();
00107 size_t im1 = ( i ) ? i - 1 : 0;
00108 size_t jm1 = ( j ) ? j - 1 : 0;
00109 size_t km1 = ( k ) ? k - 1 : 0;
00110 size_t ip1 = min( i + 1u, I - 1u );
00111 size_t jp1 = min( j + 1u, J - 1u );
00112 size_t kp1 = min( k + 1u, K - 1u );
00113
00114 size_t idx_im1 = ( k * J + j ) * I + im1;
00115 size_t idx_ip1 = ( k * J + j ) * I + ip1;
00116 size_t idx_jm1 = ( k * J + jm1 ) * I + i;
00117 size_t idx_jp1 = ( k * J + jp1 ) * I + i;
00118 size_t idx_km1 = ( km1 * J + j ) * I + i;
00119 size_t idx_kp1 = ( kp1 * J + j ) * I + i;
00120
00121 real_type vm00 = phi(idx_im1);
00122 real_type vp00 = phi(idx_ip1);
00123 real_type v0m0 = phi(idx_jm1);
00124 real_type v0p0 = phi(idx_jp1);
00125 real_type v00m = phi(idx_km1);
00126 real_type v00p = phi(idx_kp1);
00127 *p = ( a2*( vp00 + vm00 ) + a1*(v0p0+v0m0) + a0*(v00p + v00m) - a3*(*w)) * a4;
00128 }
00129 }
00130 }
00131 else
00132 {
00133
00134
00135 real_type a0 = dx*dx;
00136 real_type a1 = 1.0/8.0;
00137 for(size_t iteration=0;iteration<max_iterations;++iteration)
00138 {
00139 index_iterator p = phi.begin();
00140 index_iterator p_end = phi.end();
00141 const_iterator w = W.begin();
00142 for(;p!=p_end;++p,++w)
00143 {
00144 size_t i = p.i();
00145 size_t j = p.j();
00146 size_t k = p.k();
00147 size_t im1 = ( i ) ? i - 1 : 0;
00148 size_t jm1 = ( j ) ? j - 1 : 0;
00149 size_t km1 = ( k ) ? k - 1 : 0;
00150 size_t ip1 = min( i + 1u, I - 1u );
00151 size_t jp1 = min( j + 1u, J - 1u );
00152 size_t kp1 = min( k + 1u, K - 1u );
00153
00154 size_t idx_im1 = ( k * J + j ) * I + im1;
00155 size_t idx_ip1 = ( k * J + j ) * I + ip1;
00156 size_t idx_jm1 = ( k * J + jm1 ) * I + i;
00157 size_t idx_jp1 = ( k * J + jp1 ) * I + i;
00158 size_t idx_km1 = ( km1 * J + j ) * I + i;
00159 size_t idx_kp1 = ( kp1 * J + j ) * I + i;
00160
00161 real_type vm00 = phi(idx_im1);
00162 real_type vp00 = phi(idx_ip1);
00163 real_type v0m0 = phi(idx_jm1);
00164 real_type v0p0 = phi(idx_jp1);
00165 real_type v00m = phi(idx_km1);
00166 real_type v00p = phi(idx_kp1);
00167 *p = ( vp00 + vm00 + v0p0+v0m0 + v00p + v00m - a0*(*w) ) *a1;
00168 }
00169 }
00170 }
00171 }
00172
00173 }
00174 }
00175
00176
00177 #endif