00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef FEM_FEFUNCTIONINTERFACE_H
00010 #define FEM_FEFUNCTIONINTERFACE_H
00011
00012 #include <fem/Grid.hpp>
00013 #include <fem/FemKernel.hpp>
00014
00015
00016 namespace imaging
00017 {
00023 class FeFunctionInterface
00024 {
00025 public:
00026
00028 typedef float_t value_t;
00029
00031 template<class fem_types>
00032 float_t value(size_t integrator_node, const FemKernel<fem_types> fem_kernel) const;
00033
00040 template<class fem_types>
00041 bool sanity_check(const FemKernel<fem_types> & kernel, std::string & error_message) const { return true; }
00042 };
00043
00044
00050 template<class fem_types, class function_t>
00051 typename function_t::value_t integrate(const function_t & function, const Grid<fem_types> & grid)
00052 {
00053 typedef typename fem_types::integrator_t integrator_t;
00054 typedef typename fem_types::transform_t transform_t;
00055
00056 typedef typename function_t::value_t value_t;
00057
00058 integrator_t integrator;
00059
00060 FemKernel<fem_types> kernel(grid);
00061
00062 std::string sanity_check_message = "";
00063 if( ! function.sanity_check(kernel, sanity_check_message) )
00064 throw Exception("Exception: sanity check failed in integrate() with message '" + sanity_check_message + "'.");
00065
00066 if(grid.is_regular() && grid.n_elements() > 0)
00067 kernel.set_element(0);
00068
00069 value_t value = 0.0;
00070
00071 for(std::size_t element = 0; element < grid.n_elements(); ++element)
00072 {
00073
00074 if(grid.is_regular())
00075 kernel.lazy_set_element(element);
00076 else
00077 kernel.set_element(element);
00078
00079 for(std::size_t k = 0; k < integrator_t::n_nodes; ++k)
00080 value += function.value(k, kernel) *
00081 kernel.transform_determinant(k) *
00082 integrator.weight(k);
00083 }
00084
00085 return value;
00086 }
00087
00088
00094 template<class fem_types, class function_t>
00095 typename function_t::value_t maximum(const function_t & function, const Grid<fem_types> & grid)
00096 {
00097 typedef typename fem_types::integrator_t integrator_t;
00098 typedef typename fem_types::transform_t transform_t;
00099
00100 typedef typename function_t::value_t value_t;
00101
00102 integrator_t integrator;
00103 value_t value = 0.0;
00104
00105 FemKernel<fem_types> kernel(grid);
00106
00107 std::string sanity_check_message = "";
00108 if( ! function.sanity_check(kernel, sanity_check_message) )
00109 throw Exception("Exception: sanity check failed in maximum(() with message '" + sanity_check_message + "'.");
00110
00111 if(grid.n_elements() > 0)
00112 kernel.set_element(0);
00113
00114 if(integrator_t::n_nodes > 0)
00115 value = function.value(0, kernel);
00116
00117 for(std::size_t element = 0; element < grid.n_elements(); ++element)
00118 {
00119 if(grid.is_regular())
00120 kernel.lazy_set_element(element);
00121 else
00122 kernel.set_element(element);
00123
00124 for(std::size_t k = 0; k < integrator_t::n_nodes; ++k)
00125 value = max(value, function.value(k,kernel));
00126 }
00127
00128 return value;
00129 }
00130
00136 template<class fem_types, class function_t>
00137 typename function_t::value_t minimum(const function_t & function, const Grid<fem_types> & grid)
00138 {
00139 typedef typename fem_types::integrator_t integrator_t;
00140 typedef typename fem_types::transform_t transform_t;
00141
00142 typedef typename function_t::value_t value_t;
00143
00144 integrator_t integrator;
00145 value_t value = 0.0;
00146
00147 FemKernel<fem_types> kernel(grid);
00148
00149 std::string sanity_check_message = "";
00150 if( ! function.sanity_check(kernel, sanity_check_message) )
00151 throw Exception("Exception: sanity check failed in minimum(() with message '" + sanity_check_message + "'.");
00152
00153 if(grid.n_elements() > 0)
00154 kernel.set_element(0);
00155
00156 if(integrator_t::n_nodes > 0)
00157 value = function.value(0, kernel);
00158
00159 for(std::size_t element = 0; element < grid.n_elements(); ++element)
00160 {
00161 if(grid.is_regular())
00162 kernel.lazy_set_element(element);
00163 else
00164 kernel.set_element(element);
00165
00166 for(std::size_t k = 0; k < integrator_t::n_nodes; ++k)
00167 value = min(value, function.value(k,kernel));
00168 }
00169
00170 return value;
00171 }
00172
00173
00174
00180 template<class fem_types, class function_t>
00181 typename function_t::value_t average(const function_t & function, const Grid<fem_types> & grid)
00182 {
00183 typedef typename fem_types::integrator_t integrator_t;
00184 typedef typename fem_types::transform_t transform_t;
00185
00186 typedef typename function_t::value_t value_t;
00187
00188 integrator_t integrator;
00189
00190 FemKernel<fem_types> kernel(grid);
00191
00192 std::string sanity_check_message = "";
00193 if( ! function.sanity_check(kernel, sanity_check_message) )
00194 throw Exception("Exception: sanity check failed in average(() with message '" + sanity_check_message + "'.");
00195
00196 if(grid.is_regular() && grid.n_elements() > 0)
00197 kernel.set_element(0);
00198
00199 value_t value = 0.0;
00200 float_t area = 0.0;
00201
00202 for(std::size_t element = 0; element < grid.n_elements(); ++element)
00203 {
00204 if(grid.is_regular())
00205 kernel.lazy_set_element(element);
00206 else
00207 kernel.set_element(element);
00208
00209 for(std::size_t k = 0; k < integrator_t::n_nodes; ++k)
00210 {
00211 value += function.value(k, kernel) *
00212 kernel.transform_determinant(k) *
00213 integrator.weight(k);
00214 area += kernel.transform_determinant(k) *
00215 integrator.weight(k);
00216 }
00217 }
00218
00219 return value / area;
00220 }
00221 }
00222
00223
00224 #endif