• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaFEM/viennafem/pde_assembler.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAFEM_PDE_ASSEMBLER_HPP
00002 #define VIENNAFEM_PDE_ASSEMBLER_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaFEM - The Vienna Finite Element Method Library
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaFEM base directory
00015 ============================================================================ */
00016 
00017 //ViennaFEM includes:
00018 #include "viennafem/forwards.h"
00019 #include "viennafem/cell_quan.hpp"
00020 #include "viennafem/transform.hpp"
00021 #include "viennafem/bases/tetrahedron.hpp"
00022 #include "viennafem/bases/triangle.hpp"
00023 #include "viennafem/transform/dtdx_interval.hpp"
00024 #include "viennafem/transform/dtdx_triangle.hpp"
00025 #include "viennafem/transform/dtdx_tetrahedron.hpp"
00026 #include "viennafem/transform/dtdx_quadrilateral.hpp"
00027 #include "viennafem/transform/dtdx_hexahedron.hpp"
00028 #include "viennafem/weak_form.hpp"
00029 #include "viennafem/linear_pde_system.hpp"
00030 #include "viennafem/linear_pde_options.hpp"
00031 #include "viennafem/detail/assembler.hpp"
00032 #include "viennafem/log/api.hpp"
00033 
00034 
00036 #include "viennamath/manipulation/apply_coordinate_system.hpp"
00037 
00039 #include "viennadata/api.hpp"
00040 
00042 #include "viennagrid/domain.hpp"
00043 
00044 //#define VIENNAFEM_DEBUG
00045 
00050 namespace viennafem
00051 {
00052 
00053   namespace detail
00054   {
00056     template<typename MatrixT, typename VectorT>
00057     struct equation_wrapper
00058     {
00059       equation_wrapper(MatrixT& matrix, VectorT& vector) : matrix(matrix), vector(vector) {}
00060 
00061       template<typename IndexT>
00062       typename VectorT::value_type& operator()(IndexT i)
00063       {
00064         return vector(i);
00065       }
00066 
00067       template<typename IndexT, typename NumericT>
00068       inline void add(IndexT col, IndexT row, NumericT value)
00069       {
00070         matrix(col,row) += value;
00071       }
00072 
00073       MatrixT& matrix; 
00074       VectorT& vector;
00075     };
00076     
00077   } //namespace detail
00078 
00080   class pde_assembler
00081   {
00082     public:
00083       
00091       template <typename SystemType, typename DomainType, typename MatrixT, typename VectorT>  //template for operator()
00092       void operator()(SystemType pde_system,
00093                       DomainType & domain,
00094                       MatrixT    & system_matrix, 
00095                       VectorT    & load_vector
00096                      ) const
00097       {
00098         typedef typename DomainType::config_type              Config;
00099         typedef typename Config::cell_tag                     CellTag;
00100         
00101         typedef typename viennagrid::result_of::point<Config>::type                            PointType;
00102         typedef typename viennagrid::result_of::ncell<Config, CellTag::dim>::type   CellType;
00103 
00104         typedef typename viennagrid::result_of::ncell_range<DomainType, 0>::type                VertexContainer;
00105         typedef typename viennagrid::result_of::iterator<VertexContainer>::type                     VertexIterator;
00106 
00107         typedef typename viennagrid::result_of::ncell_range<DomainType, CellTag::dim>::type    CellContainer;
00108         typedef typename viennagrid::result_of::iterator<CellContainer>::type                                 CellIterator;
00109 
00110         typedef typename viennagrid::result_of::ncell_range<CellType, 0>::type                  VertexOnCellContainer;
00111         typedef typename viennagrid::result_of::iterator<VertexOnCellContainer>::type               VertexOnCellIterator;
00112         
00113         typedef typename SystemType::equation_type                  EquationType;
00114         typedef typename SystemType::equation_type::value_type      Expression;
00115         
00116      #ifdef VIENNAFEM_DEBUG
00117         std::cout << "Strong form: " << pde_system.pde(0) << std::endl;
00118      #endif
00119         log_strong_form(pde_system);
00120         EquationType weak_form_general = viennafem::make_weak_form(pde_system.pde(0));  
00121      #ifdef VIENNAFEM_DEBUG        
00122         std::cout << "* pde_solver::operator(): Using weak form general: " << weak_form_general << std::endl;
00123      #endif
00124         std::vector<EquationType> temp(1); temp[0] = weak_form_general;
00125         log_weak_form(temp, pde_system);
00126         EquationType weak_form = viennamath::apply_coordinate_system(viennamath::cartesian<Config::coordinate_system_tag::dim>(), weak_form_general);
00127         temp[0] = weak_form;
00128         log_coordinated_weak_form(temp, pde_system);
00129 
00130      #ifdef VIENNAFEM_DEBUG        
00131         std::cout << "* pde_solver::operator(): Using weak form " << weak_form << std::endl;
00132         std::cout << "* pde_solver::operator(): Write dt_dx coefficients" << std::endl;
00133      #endif
00134      
00135         typedef typename reference_cell_for_basis<CellTag, viennafem::lagrange_tag<1> >::type    ReferenceCell;
00136         
00137         //fill with cell quantities 
00138         CellContainer cells = viennagrid::ncells<CellTag::dim>(domain);
00139         for (CellIterator cell_iter = cells.begin();
00140             cell_iter != cells.end();
00141             ++cell_iter)
00142         {
00143           //cell_iter->print_short();
00144           //viennadata::access<example_key, double>()(*cell_iter) = i; 
00145           viennafem::dt_dx_handler<ReferenceCell>::apply(*cell_iter);
00146         }
00147 
00148      #ifdef VIENNAFEM_DEBUG        
00149         std::cout << "* pde_solver::operator(): Create Mapping:" << std::endl;
00150      #endif
00151         std::size_t map_index = create_mapping(pde_system, domain);
00152         
00153      #ifdef VIENNAFEM_DEBUG                
00154         std::cout << "* pde_solver::operator(): Assigned degrees of freedom in domain so far: " << map_index << std::endl;
00155      #endif        
00156         // resize global system matrix and load vector if needed:
00157         // TODO: This can be a performance bottleneck for large numbers of segments! (lots of resize operations...)
00158         if (map_index > system_matrix.size1())
00159         {
00160           MatrixT temp = system_matrix;
00162           system_matrix.resize(map_index, map_index, false);
00163           system_matrix.clear();
00164           system_matrix.resize(map_index, map_index, false);
00165           for (typename MatrixT::iterator1 row_it = temp.begin1();
00166                row_it != temp.end1();
00167                ++row_it)
00168           {
00169             for (typename MatrixT::iterator2 col_it = row_it.begin();
00170                  col_it != row_it.end();
00171                  ++col_it)
00172                  system_matrix(col_it.index1(), col_it.index2()) = *col_it;
00173           }
00174         }
00175         if (map_index > load_vector.size())
00176         {
00177           VectorT temp = load_vector;
00178        #ifdef VIENNAFEM_DEBUG                          
00179           std::cout << "Resizing load vector..." << std::endl;
00180        #endif
00181           load_vector.resize(map_index, false);
00182           load_vector.clear();
00183           load_vector.resize(map_index, false);
00184           for (std::size_t i=0; i<temp.size(); ++i)
00185             load_vector(i) = temp(i);
00186         }
00187 
00188      #ifdef VIENNAFEM_DEBUG                        
00189         std::cout << "* pde_solver::operator(): Transform to reference element" << std::endl;
00190      #endif
00191         EquationType transformed_weak_form = viennafem::transform_to_reference_cell<CellType>(weak_form, pde_system);
00192         temp[0] = transformed_weak_form;
00193         log_transformed_weak_form<CellType>(temp, pde_system);
00194         
00195         std::cout << "* pde_solver::operator(): Transformed weak form:" << std::endl;
00196         std::cout << transformed_weak_form << std::endl;
00197         //std::cout << std::endl;
00198 
00199      #ifdef VIENNAFEM_DEBUG                        
00200         std::cout << "* pde_solver::operator(): Assemble system" << std::endl;
00201      #endif
00202      
00203         typedef detail::equation_wrapper<MatrixT, VectorT>    wrapper_type;
00204         wrapper_type wrapper(system_matrix, load_vector);
00205      
00206         detail::pde_assembler_internal()(transformed_weak_form, pde_system, domain, wrapper);
00207 //        pde_assembler_internal()(transformed_weak_form, pde_system, domain, system_matrix, load_vector);
00208 
00209       }
00210       
00211   };
00212 
00213 }
00214 #endif

Generated on Wed Feb 29 2012 21:51:05 for ViennaFEM - The Vienna Finite Element Method Library by  doxygen 1.7.1