Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_UPWIND_GRADIENT_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_UPWIND_GRADIENT_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
00029 template<typename grid_type, typename vector3_type>
00030 inline void upwind_gradient(
00031 grid_type const & phi
00032 , grid_type const & F
00033 , size_t i
00034 , size_t j
00035 , size_t k
00036 , vector3_type & gradient
00037 )
00038 {
00039 using std::min;
00040
00041 typedef typename grid_type::value_type value_type;
00042 typedef typename grid_type::math_types math_types;
00043 typedef typename math_types::real_type real_type;
00044
00045 size_t I = phi.I();
00046 size_t J = phi.J();
00047 size_t K = phi.K();
00048 real_type inv_dx = 1.0/phi.dx();
00049 real_type inv_dy = 1.0/phi.dy();
00050 real_type inv_dz = 1.0/phi.dz();
00051 real_type inv_2dx = 0.5/phi.dx();
00052 real_type inv_2dy = 0.5/phi.dy();
00053 real_type inv_2dz = 0.5/phi.dz();
00054
00055 size_t im1 = ( i ) ? i - 1 : 0;
00056 size_t jm1 = ( j ) ? j - 1 : 0;
00057 size_t km1 = ( k ) ? k - 1 : 0;
00058 size_t ip1 = min( i + 1u, I - 1u );
00059 size_t jp1 = min( j + 1u, J - 1u );
00060 size_t kp1 = min( k + 1u, K - 1u );
00061 size_t i000 = ( k * J + j ) * I + i;
00062 size_t im00 = ( k * J + j ) * I + im1;
00063 size_t ip00 = ( k * J + j ) * I + ip1;
00064 size_t i0m0 = ( k * J + jm1 ) * I + i;
00065 size_t i0p0 = ( k * J + jp1 ) * I + i;
00066 size_t i00m = ( km1 * J + j ) * I + i;
00067 size_t i00p = ( kp1 * J + j ) * I + i;
00068 real_type f = F(i000);
00069 real_type v000 = phi(i000);
00070 real_type vp00 = phi(ip00);
00071 real_type vm00 = phi(im00);
00072 real_type v0p0 = phi(i0p0);
00073 real_type v0m0 = phi(i0m0);
00074 real_type v00p = phi(i00p);
00075 real_type v00m = phi(i00m);
00076
00077
00078
00079 real_type nx = 0;
00080 real_type ny = 0;
00081 real_type nz = 0;
00082 if(f>0)
00083 {
00084 nx = (vp00 - v000 ) * inv_dx;
00085 ny = (v0p0 - v000 ) * inv_dy;
00086 nz = (v00p - v000 ) * inv_dz;
00087 }
00088 else if(f<0)
00089 {
00090 nx = (v000 - vm00) * inv_dx;
00091 ny = (v000 - v0m0) * inv_dy;
00092 nz = (v000 - v00m) * inv_dz;
00093 }
00094 else
00095 {
00096 nx = (vp00 - vm00) * inv_2dx;
00097 ny = (v0p0 - v0m0) * inv_2dy;
00098 nz = (v00p - v00m) * inv_2dz;
00099 }
00100 gradient = vector3_type(nx,ny,nz);
00101 }
00102
00103 }
00104 }
00105
00106
00107 #endif