FeFunctionInterface.hpp

00001 // This file is part of the imaging2 class library.
00002 //
00003 // University of Innsbruck, Infmath Imaging, 2009.
00004 // http://infmath.uibk.ac.at
00005 //
00006 // All rights reserved.
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

Generated on Tue Feb 10 10:01:30 2009 for imaging2 by  doxygen 1.5.5