Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_UPWIND_GRADIENT_FIELD_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_UPWIND_GRADIENT_FIELD_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <cmath>
00013
00014 namespace OpenTissue
00015 {
00016 namespace grid
00017 {
00018
00022 template < typename grid_type >
00023 inline void upwind_gradient_field(
00024 grid_type const & phi
00025 , grid_type const & F
00026 , grid_type & Nx
00027 , grid_type & Ny
00028 , grid_type & Nz
00029 )
00030 {
00031 using std::min;
00032
00033 typedef OpenTissue::math::Vector3< typename grid_type::value_type> vector3_type;
00034
00035 typedef typename grid_type::value_type value_type;
00036 typedef typename grid_type::iterator iterator;
00037 typedef typename grid_type::const_iterator const_iterator;
00038 typedef typename grid_type::const_index_iterator const_index_iterator;
00039 typedef typename grid_type::math_types math_types;
00040 typedef typename math_types::real_type real_type;
00041
00042 size_t I = phi.I();
00043 size_t J = phi.J();
00044 size_t K = phi.K();
00045 real_type inv_dx = 1.0/phi.dx();
00046 real_type inv_dy = 1.0/phi.dy();
00047 real_type inv_dz = 1.0/phi.dz();
00048
00049 real_type inv_2dx = 0.5/phi.dx();
00050 real_type inv_2dy = 0.5/phi.dy();
00051 real_type inv_2dz = 0.5/phi.dz();
00052
00053 iterator nx = Nx.begin();
00054 iterator ny = Ny.begin();
00055 iterator nz = Nz.begin();
00056 const_iterator f = F.begin();
00057 const_index_iterator pbegin = phi.begin();
00058 const_index_iterator pend = phi.end();
00059 const_index_iterator p = pbegin;
00060
00061 for(;p!=pend; ++f,++p,++nx,++ny,++nz)
00062 {
00063 size_t i = p.i();
00064 size_t j = p.j();
00065 size_t k = p.k();
00066
00067 size_t im1 = ( i ) ? i - 1 : 0;
00068 size_t jm1 = ( j ) ? j - 1 : 0;
00069 size_t km1 = ( k ) ? k - 1 : 0;
00070 size_t ip1 = min( i + 1u, I - 1u );
00071 size_t jp1 = min( j + 1u, J - 1u );
00072 size_t kp1 = min( k + 1u, K - 1u );
00073 size_t i000 = ( k * J + j ) * I + i;
00074 size_t im00 = ( k * J + j ) * I + im1;
00075 size_t ip00 = ( k * J + j ) * I + ip1;
00076 size_t i0m0 = ( k * J + jm1 ) * I + i;
00077 size_t i0p0 = ( k * J + jp1 ) * I + i;
00078 size_t i00m = ( km1 * J + j ) * I + i;
00079 size_t i00p = ( kp1 * J + j ) * I + i;
00080 real_type v000 = phi(i000);
00081 real_type vp00 = phi(ip00);
00082 real_type vm00 = phi(im00);
00083 real_type v0p0 = phi(i0p0);
00084 real_type v0m0 = phi(i0m0);
00085 real_type v00p = phi(i00p);
00086 real_type v00m = phi(i00m);
00087
00088
00089
00090 if((*f)>0)
00091 {
00092 *nx = (vp00 - v000 ) * inv_dx;
00093 *ny = (v0p0 - v000 ) * inv_dy;
00094 *nz = (v00p - v000 ) * inv_dz;
00095 }
00096 else if((*f)<0)
00097 {
00098 *nx = (v000 - vm00) * inv_dx;
00099 *ny = (v000 - v0m0) * inv_dy;
00100 *nz = (v000 - v00m) * inv_dz;
00101 }
00102 else
00103 {
00104 *nx = (vp00 - vm00) * inv_2dx;
00105 *ny = (v0p0 - v0m0) * inv_2dy;
00106 *nz = (v00p - v00m) * inv_2dz;
00107 }
00108 }
00109 }
00110
00111 }
00112 }
00113
00114
00115 #endif