Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_EXTRAPOLATION_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_EXTRAPOLATION_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/gradient.h>
00015 #include <OpenTissue/core/containers/grid/util/grid_compute_sign_function.h>
00016 #include <OpenTissue/core/math/math_vector3.h>
00017
00018 namespace OpenTissue
00019 {
00020 namespace grid
00021 {
00022
00028 template < typename grid_type >
00029 inline void extrapolation(
00030 grid_type & S
00031 , grid_type const & phi
00032 , size_t max_iterations = 10
00033
00034 )
00035 {
00036 using std::min;
00037 using std::max;
00038 using std::fabs;
00039
00040 typedef OpenTissue::math::Vector3< typename grid_type::value_type> vector3_type;
00041
00042 typedef typename grid_type::iterator iterator;
00043 typedef typename grid_type::index_iterator index_iterator;
00044 typedef typename grid_type::const_index_iterator const_index_iterator;
00045 typedef typename grid_type::value_type value_type;
00046 typedef typename grid_type::math_types math_types;
00047 typedef typename math_types::real_type real_type;
00048
00049 Gradient<vector3_type> gradient;
00050
00051 size_t I = S.I();
00052 size_t J = S.J();
00053 size_t K = S.K();
00054
00055 real_type dx = S.dx();
00056 real_type dy = S.dy();
00057 real_type dz = S.dz();
00058
00059 value_type zero = static_cast<value_type>(0.0);
00060
00061 grid_type F = S;
00062 grid_type sign_phi;
00063 compute_sign_function(phi,sign_phi);
00064
00065 iterator fbegin = F.begin();
00066 index_iterator sbegin = S.begin();
00067 index_iterator send = S.end();
00068
00069 size_t iteration = 0;
00070 bool steady_state = false;
00071
00072 while (!steady_state)
00073 {
00074 value_type max_F = zero;
00075 const_index_iterator p = phi.begin();
00076 iterator s_phi = sign_phi.begin();
00077 iterator f = fbegin;
00078 index_iterator s = sbegin;
00079 for(;s!=send; ++s,++f,++s_phi,++p)
00080 {
00081 size_t i = s.i();
00082 size_t j = s.j();
00083 size_t k = s.k();
00084
00085 vector3_type n = gradient(p);
00086
00087 size_t im1 = ( i ) ? i - 1 : 0;
00088 size_t jm1 = ( j ) ? j - 1 : 0;
00089 size_t km1 = ( k ) ? k - 1 : 0;
00090 size_t ip1 = min( i + 1u, I - 1u );
00091 size_t jp1 = min( j + 1u, J - 1u );
00092 size_t kp1 = min( k + 1u, K - 1u );
00093 size_t idx = ( k * J + j ) * I + i;
00094 size_t idx_im1 = ( k * J + j ) * I + im1;
00095 size_t idx_ip1 = ( k * J + j ) * I + ip1;
00096 size_t idx_jm1 = ( k * J + jm1 ) * I + i;
00097 size_t idx_jp1 = ( k * J + jp1 ) * I + i;
00098 size_t idx_km1 = ( km1 * J + j ) * I + i;
00099 size_t idx_kp1 = ( kp1 * J + j ) * I + i;
00100 value_type s_idx = S(idx);
00101 value_type s_idx_im1 = S(idx_im1);
00102 value_type s_idx_ip1 = S(idx_ip1);
00103 value_type s_idx_jm1 = S(idx_jm1);
00104 value_type s_idx_jp1 = S(idx_jp1);
00105 value_type s_idx_km1 = S(idx_km1);
00106 value_type s_idx_kp1 = S(idx_kp1);
00107 value_type Spx = (s_idx_ip1 - s_idx )/ dx;
00108 value_type Spy = (s_idx_jp1 - s_idx )/ dy;
00109 value_type Spz = (s_idx_kp1 - s_idx )/ dz;
00110 value_type Smx = (s_idx - s_idx_im1)/ dx;
00111 value_type Smy = (s_idx - s_idx_jm1)/ dy;
00112 value_type Smz = (s_idx - s_idx_km1)/ dz;
00113
00114 *f = max( (*s_phi)*n(0) , zero)*Smx
00115 + min( (*s_phi)*n(0) , zero)*Spx
00116 + max( (*s_phi)*n(1) , zero)*Smy
00117 + min( (*s_phi)*n(1) , zero)*Spy
00118 + max( (*s_phi)*n(2) , zero)*Smz
00119 + min( (*s_phi)*n(2) , zero)*Spz;
00120
00121 max_F = max(max_F, fabs(*f));
00122 }
00123 value_type time_step = static_cast<value_type>( 1.0 / (max_F + 1.0) );
00124 for(s=sbegin, f=fbegin;s!=send;++s,++f)
00125 (*s) = (*s) - time_step * (*f);
00126 ++iteration;
00127 if(iteration> max_iterations)
00128 steady_state = true;
00129 }
00130 }
00131
00132 }
00133 }
00134
00135
00136 #endif