Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_METAMORPHOSIS_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_METAMORPHOSIS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace grid
00015 {
00016
00028 template<
00029 typename grid_type
00030 >
00031 inline void metamorphosis_speed_function(
00032 grid_type const & phi
00033 , grid_type const & gamma
00034 , grid_type & F
00035 )
00036 {
00037 using std::min;
00038 using std::max;
00039 using std::sqrt;
00040
00041 typedef typename grid_type::value_type value_type;
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::math_types math_types;
00046 typedef typename math_types::real_type real_type;
00047
00048 size_t I = phi.I();
00049 size_t J = phi.J();
00050 size_t K = phi.K();
00051 real_type dx = phi.dx();
00052 real_type dy = phi.dy();
00053 real_type dz = phi.dz();
00054
00055 const_index_iterator end = phi.end();
00056 const_index_iterator u = phi.begin();
00057 index_iterator f = F.begin();
00058 const_index_iterator g = gamma.begin();
00059
00060 for(;u!=end; ++u,++g,++f)
00061 {
00062 size_t i = u.i();
00063 size_t j = u.j();
00064 size_t k = u.k();
00065
00066 size_t im1 = ( i ) ? i - 1 : 0;
00067 size_t jm1 = ( j ) ? j - 1 : 0;
00068 size_t km1 = ( k ) ? k - 1 : 0;
00069 size_t ip1 = min( i + 1u, I - 1u );
00070 size_t jp1 = min( j + 1u, J - 1u );
00071 size_t kp1 = min( k + 1u, K - 1u );
00072 size_t idx = ( k * J + j ) * I + i;
00073 size_t idx_im1 = ( k * J + j ) * I + im1;
00074 size_t idx_ip1 = ( k * J + j ) * I + ip1;
00075 size_t idx_jm1 = ( k * J + jm1 ) * I + i;
00076 size_t idx_jp1 = ( k * J + jp1 ) * I + i;
00077 size_t idx_km1 = ( km1 * J + j ) * I + i;
00078 size_t idx_kp1 = ( kp1 * J + j ) * I + i;
00079 real_type u_idx = phi(idx);
00080 real_type u_idx_im1 = phi(idx_im1);
00081 real_type u_idx_ip1 = phi(idx_ip1);
00082 real_type u_idx_jm1 = phi(idx_jm1);
00083 real_type u_idx_jp1 = phi(idx_jp1);
00084 real_type u_idx_km1 = phi(idx_km1);
00085 real_type u_idx_kp1 = phi(idx_kp1);
00086
00087 real_type Upx = (u_idx_ip1 - u_idx )/ dx;
00088 real_type Upy = (u_idx_jp1 - u_idx )/ dy;
00089 real_type Upz = (u_idx_kp1 - u_idx )/ dz;
00090 real_type Umx = (u_idx - u_idx_im1)/ dx;
00091 real_type Umy = (u_idx - u_idx_jm1)/ dy;
00092 real_type Umz = (u_idx - u_idx_km1)/ dz;
00093
00094 real_type Upx_min = min( Upx, 0.0);
00095 real_type Upx_max = max( Upx, 0.0);
00096 real_type Umx_min = min( Umx, 0.0);
00097 real_type Umx_max = max( Umx, 0.0);
00098
00099 real_type Upy_min = min( Upy, 0.0);
00100 real_type Upy_max = max( Upy, 0.0);
00101 real_type Umy_min = min( Umy, 0.0);
00102 real_type Umy_max = max( Umy, 0.0);
00103
00104 real_type Upz_min = min( Upz, 0.0);
00105 real_type Upz_max = max( Upz, 0.0);
00106 real_type Umz_min = min( Umz, 0.0);
00107 real_type Umz_max = max( Umz, 0.0);
00108
00109 if(-(*g)>=0)
00110 *f = (*g)*sqrt(
00111 Upx_min*Upx_min
00112 + Umx_max*Umx_max
00113 + Upy_min*Upy_min
00114 + Umy_max*Umy_max
00115 + Upz_min*Upz_min
00116 + Umz_max*Umz_max
00117 );
00118 else
00119 *f = (*g)*sqrt(
00120 Upx_max*Upx_max
00121 + Umx_min*Umx_min
00122 + Upy_max*Upy_max
00123 + Umy_min*Umy_min
00124 + Upz_max*Upz_max
00125 + Umz_min*Umz_min
00126 );
00127 }
00128
00129 }
00130
00131
00184 template<
00185 typename grid_type
00186 >
00187 inline void metamorphosis(
00188 grid_type & phi
00189 , grid_type const & gamma
00190 , typename grid_type::math_types::real_type const & dt
00191 )
00192 {
00193 typedef typename grid_type::value_type value_type;
00194 typedef typename grid_type::iterator iterator;
00195 typedef typename grid_type::index_iterator index_iterator;
00196 typedef typename grid_type::const_index_iterator const_index_iterator;
00197 typedef typename grid_type::math_types math_types;
00198 typedef typename math_types::real_type real_type;
00199
00200 using std::min;
00201 using std::max;
00202 using std::fabs;
00203
00204 real_type dx = phi.dx();
00205 real_type dy = phi.dy();
00206 real_type dz = phi.dz();
00207
00208 grid_type F = phi;
00209
00210 real_type min_delta = min ( dx, min( dy, dz));
00211 assert(min_delta>0 || !"metamorphosis(): minimum spacing was non-positive!");
00212 real_type max_gamma = max ( fabs( max(gamma)), fabs( min(gamma) ) );
00213 assert(max_gamma>0 || !"metamorphosis(): maximum absolute speed was non-positive!");
00214 real_type time = static_cast<real_type>(0.0);
00215
00216 while (time < dt)
00217 {
00218 metamorphosis_speed_function(phi,gamma,F);
00219
00220 real_type time_step = min( dt, min_delta / (3.0*max_gamma) );
00221 assert(time_step>0 || !"metamorphosis(): time_step was non-positive!");
00222 std::cout << "\ttime step = " << time_step << std::endl;
00223
00224 index_iterator end = phi.end();
00225 index_iterator u = phi.begin();
00226 index_iterator f = F.begin();
00227 for(;u!=end; ++u,++f)
00228 (*u) = (*u) + time_step *(*f);
00229
00230 time += time_step;
00231 }
00232 std::cout << "metamorphosis(): done..." << std::endl;
00233 }
00234
00235 }
00236 }
00237
00238
00239 #endif