00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_BISECTION_LINE_SEARCH_H 00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_BISECTION_LINE_SEARCH_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 #include <OpenTissue/core/containers/grid/util/grid_gradient_at_point.h> 00013 00014 namespace OpenTissue 00015 { 00016 namespace grid 00017 { 00028 template<typename vector3_type,typename grid_type> 00029 inline vector3_type bisection_line_search(vector3_type q_a, vector3_type q_b, grid_type & phi, bool maximize = true) 00030 { 00031 using std::fabs; 00032 typedef typename vector3_type::value_type real_type; 00033 00034 real_type const precision = 10e-5;//OpenTissue::math::working_precision<real_type>(100); 00035 real_type const too_small_interval = sqr_length(q_b-q_a)*0.0001; //--- 1/100'th of distance! 00036 vector3_type n = unit(gradient_at_point(phi,q_a)); 00037 vector3_type r; 00038 00039 00040 real_type const sign = maximize? 1.0 : -1.0; 00041 00042 00043 bool forever = true; 00044 do 00045 { 00046 vector3_type q_c = (q_a + q_b)*.5; 00047 if( sqr_length(q_a - q_b) < too_small_interval ) 00048 { 00049 r = q_c; 00050 break; 00051 } 00052 vector3_type dir = unit(gradient_at_point(phi,q_c)); 00053 real_type n_dot_dir = inner_prod(n , dir)*sign; 00054 if(fabs(n_dot_dir) < precision) 00055 { 00056 r = q_c; 00057 break; 00058 } 00059 if(n_dot_dir > 0) 00060 { 00061 q_a = q_c; 00062 } 00063 if(n_dot_dir < 0) 00064 { 00065 q_b = q_c; 00066 } 00067 } 00068 while (forever); 00069 return r; 00070 } 00071 00072 } // namespace grid 00073 } // namespace OpenTissue 00074 00075 // OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_BISECTION_LINE_SEARCH_H 00076 #endif