Go to the documentation of this file.00001 #ifndef VIENNAFEM_PDE_ASSEMBLER_HPP
00002 #define VIENNAFEM_PDE_ASSEMBLER_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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 }
00078
00080 class pde_assembler
00081 {
00082 public:
00083
00091 template <typename SystemType, typename DomainType, typename MatrixT, typename VectorT>
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
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
00144
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
00157
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
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
00208
00209 }
00210
00211 };
00212
00213 }
00214 #endif