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

/export/development/ViennaFEM/viennafem/transform.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAFEM_TRANSFORM_HPP
00002 #define VIENNAFEM_TRANSFORM_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 #include "viennafem/forwards.h"
00018 #include "viennafem/cell_quan.hpp"
00019 
00020 #include "viennamath/expression.hpp"
00021 #include "viennamath/manipulation/substitute.hpp"
00022 #include "viennamath/manipulation/diff.hpp"
00023 
00024 #include "viennagrid/topology/triangle.hpp"
00025 #include "viennagrid/topology/tetrahedron.hpp"
00026 
00027 
00032 namespace viennafem
00033 {
00034 
00035   namespace detail
00036   {
00038     template <typename CellType, typename InterfaceType>
00039     void wrap_jacobian(viennafem::cell_quan<CellType, InterfaceType> & det_dF_dt, viennafem::unit_interval)
00040     {
00041       det_dF_dt.wrap_constant( viennafem::det_dF_dt_key() );
00042     }
00043 
00045     template <typename CellType, typename InterfaceType>
00046     void wrap_jacobian(viennafem::cell_quan<CellType, InterfaceType> & det_dF_dt, viennafem::unit_triangle)
00047     {
00048       det_dF_dt.wrap_constant( viennafem::det_dF_dt_key() );
00049     }
00050 
00052     template <typename CellType, typename InterfaceType>
00053     void wrap_jacobian(viennafem::cell_quan<CellType, InterfaceType> & det_dF_dt, viennafem::unit_tetrahedron)
00054     {
00055       det_dF_dt.wrap_constant( viennafem::det_dF_dt_key() );
00056     }
00057 
00059     template <typename CellType, typename InterfaceType>
00060     void wrap_jacobian(viennafem::cell_quan<CellType, InterfaceType> & det_dF_dt, viennafem::unit_square)
00061     {
00062       det_dF_dt.wrap_expr( viennafem::det_dF_dt_key() );
00063     }
00064 
00066     template <typename CellType, typename InterfaceType>
00067     void wrap_jacobian(viennafem::cell_quan<CellType, InterfaceType> & det_dF_dt, viennafem::unit_cube)
00068     {
00069       det_dF_dt.wrap_expr( viennafem::det_dF_dt_key() );
00070     }
00071     
00073     template <typename CellType, typename InterfaceType, typename ReferenceCellTag>
00074     struct jacobian_adder : public viennamath::rt_manipulation_interface<InterfaceType>
00075     {
00076       public:
00077         typedef typename InterfaceType::numeric_type        numeric_type;
00078         
00079         InterfaceType * operator()(InterfaceType const * e) const 
00080         {
00081           const viennamath::rt_unary_expr<InterfaceType> * integral_expression = dynamic_cast<const viennamath::rt_unary_expr<InterfaceType> *>(e);
00082           
00083           if (integral_expression != NULL)
00084           {
00085             typedef viennamath::op_unary<viennamath::op_rt_symbolic_integral<InterfaceType>, InterfaceType>    SymbolicIntegrationOperation;
00086 
00087             const SymbolicIntegrationOperation * op_symb_tmp = dynamic_cast<const SymbolicIntegrationOperation *>(integral_expression->op());
00088 
00089             viennafem::cell_quan<CellType, InterfaceType> det_dF_dt;
00090             detail::wrap_jacobian(det_dF_dt, ReferenceCellTag());
00091             
00092             if (op_symb_tmp != NULL)
00093             {
00094               return new viennamath::rt_unary_expr<InterfaceType>(
00095                           new viennamath::rt_binary_expr<InterfaceType>(integral_expression->lhs()->clone(),
00096                                                                         new viennamath::op_binary<viennamath::op_mult<numeric_type>, InterfaceType>(),
00097                                                                         det_dF_dt.clone()),
00098                           op_symb_tmp->clone());
00099             }
00100           }
00101           
00102           return e->clone();
00103         }
00104         
00105         bool modifies(InterfaceType const * e) const
00106         {
00107           const viennamath::rt_unary_expr<InterfaceType> * integral_expression = dynamic_cast<const viennamath::rt_unary_expr<InterfaceType> *>(e);
00108           
00109           if (integral_expression != NULL)
00110           {
00111             typedef viennamath::op_unary<viennamath::op_rt_symbolic_integral<InterfaceType>, InterfaceType>    SymbolicIntegrationOperation;
00112 
00113             const SymbolicIntegrationOperation * op_symb_tmp = dynamic_cast<const SymbolicIntegrationOperation *>(integral_expression->op());
00114             
00115             if (op_symb_tmp != NULL)
00116               return true;
00117           }
00118           return false;
00119         }
00120     };
00121 
00122     
00123     
00125     template <long i, long j, typename CellType, typename InterfaceType>
00126     void wrap_dt_dx(viennafem::cell_quan<CellType, InterfaceType> & dt_dx, viennafem::unit_interval)
00127     {
00128       dt_dx.wrap_constant( viennafem::dt_dx_key<i,j>() );
00129     }
00130     
00132     template <long i, long j, typename CellType, typename InterfaceType>
00133     void wrap_dt_dx(viennafem::cell_quan<CellType, InterfaceType> & dt_dx, viennafem::unit_triangle)
00134     {
00135       dt_dx.wrap_constant( viennafem::dt_dx_key<i,j>() );
00136     }
00137 
00139     template <long i, long j, typename CellType, typename InterfaceType>
00140     void wrap_dt_dx(viennafem::cell_quan<CellType, InterfaceType> & dt_dx, viennafem::unit_tetrahedron)
00141     {
00142       dt_dx.wrap_constant( viennafem::dt_dx_key<i,j>() );
00143     }
00144 
00146     template <long i, long j, typename CellType, typename InterfaceType>
00147     void wrap_dt_dx(viennafem::cell_quan<CellType, InterfaceType> & dt_dx, viennafem::unit_square)
00148     {
00149       dt_dx.wrap_expr( viennafem::dt_dx_key<i,j>() );
00150     }
00151 
00153     template <long i, long j, typename CellType, typename InterfaceType>
00154     void wrap_dt_dx(viennafem::cell_quan<CellType, InterfaceType> & dt_dx, viennafem::unit_cube)
00155     {
00156       dt_dx.wrap_expr( viennafem::dt_dx_key<i,j>() );
00157     }
00158     
00160     
00161     //
00162     // Line:
00163     //
00165     template <typename CellType, typename EquationType, typename PDESystemType, typename ReferenceCellTag>
00166     EquationType transform_to_reference_cell_1d(EquationType const & weak_form,
00167                                                 PDESystemType const & pde_system,
00168                                                 ReferenceCellTag)
00169     {
00170       typedef typename EquationType::interface_type             InterfaceType;
00171       typedef typename InterfaceType::numeric_type              numeric_type;
00172       typedef viennamath::rt_function_symbol<InterfaceType>   FunctionSymbol;
00173       typedef viennamath::rt_expr<InterfaceType>              Expression;
00174       typedef viennamath::rt_unary_expr<InterfaceType>        UnaryExpression;
00175       typedef viennamath::rt_variable<InterfaceType>          Variable;
00176       typedef viennamath::op_unary<viennamath::op_partial_deriv<viennamath::default_numeric_type>, InterfaceType >   d_dx;
00177       
00178       
00179       
00180       FunctionSymbol  u(0, viennamath::unknown_tag<>());
00181       FunctionSymbol  v(0, viennamath::test_tag<>());
00182       Variable        r(0);
00183       
00184       //using local coordinates (r, s) and global coordinates (x, y)
00185       viennafem::cell_quan<CellType, InterfaceType>  dr_dx; detail::wrap_dt_dx<0,0>(dr_dx, ReferenceCellTag());
00186       
00187       Expression new_lhs = weak_form.lhs();
00188       Expression new_rhs = weak_form.rhs();
00189       
00190       //std::cout << "New lhs init: " << std::endl;
00191       //std::cout << new_lhs << std::endl;
00192       
00193       std::vector<Expression> search_types(2);
00194       search_types[0] = UnaryExpression(u.clone(), new d_dx(0));
00195       search_types[1] = UnaryExpression(v.clone(), new d_dx(0));
00196       
00197       std::vector<Expression> replace_types(2);
00198       replace_types[0] = viennamath::diff(u, r) * dr_dx;
00199       replace_types[1] = viennamath::diff(v, r) * dr_dx;
00200       
00201       //substitute expressions in lhs and rhs:
00202       new_lhs = viennamath::substitute(search_types, replace_types, weak_form.lhs());
00203       new_rhs = viennamath::substitute(search_types, replace_types, weak_form.rhs());
00204       
00205       viennamath::rt_manipulation_wrapper<InterfaceType> jacobian_manipulator( new detail::jacobian_adder<CellType, InterfaceType, ReferenceCellTag>() );
00206       Expression new_lhs_with_jacobian(new_lhs.get()->recursive_manipulation(jacobian_manipulator));
00207       Expression new_rhs_with_jacobian(new_rhs.get()->recursive_manipulation(jacobian_manipulator));
00208       
00209       return EquationType(new_lhs_with_jacobian, new_rhs_with_jacobian);
00210     }
00211     
00212     
00214     
00215     
00216     //
00217     // Triangles and Quadrilaterals:
00218     //
00220     template <typename CellType, typename EquationType, typename PDESystemType, typename ReferenceCellTag>
00221     EquationType transform_to_reference_cell_2d(EquationType const & weak_form,
00222                                                 PDESystemType const & pde_system,
00223                                                 ReferenceCellTag)
00224     {
00225       typedef typename EquationType::interface_type             InterfaceType;
00226       typedef typename InterfaceType::numeric_type              numeric_type;
00227       typedef viennamath::rt_function_symbol<InterfaceType>   FunctionSymbol;
00228       typedef viennamath::rt_expr<InterfaceType>              Expression;
00229       typedef viennamath::rt_unary_expr<InterfaceType>        UnaryExpression;
00230       typedef viennamath::rt_variable<InterfaceType>          Variable;
00231       typedef viennamath::op_unary<viennamath::op_partial_deriv<viennamath::default_numeric_type>, InterfaceType >   d_dx;
00232       
00233       
00234       
00235       FunctionSymbol  u(0, viennamath::unknown_tag<>());
00236       FunctionSymbol  v(0, viennamath::test_tag<>());
00237       Variable        r(0);
00238       Variable        s(1);
00239       
00240       //using local coordinates (r, s) and global coordinates (x, y)
00241       viennafem::cell_quan<CellType, InterfaceType>  dr_dx; detail::wrap_dt_dx<0,0>(dr_dx, ReferenceCellTag());
00242       viennafem::cell_quan<CellType, InterfaceType>  ds_dx; detail::wrap_dt_dx<1,0>(ds_dx, ReferenceCellTag());
00243       
00244       viennafem::cell_quan<CellType, InterfaceType>  dr_dy; detail::wrap_dt_dx<0,1>(dr_dy, ReferenceCellTag());
00245       viennafem::cell_quan<CellType, InterfaceType>  ds_dy; detail::wrap_dt_dx<1,1>(ds_dy, ReferenceCellTag());
00246       
00247       Expression new_lhs = weak_form.lhs();
00248       Expression new_rhs = weak_form.rhs();
00249       
00250       //std::cout << "New lhs init: " << std::endl;
00251       //std::cout << new_lhs << std::endl;
00252       
00253       std::vector<Expression> search_types(4);
00254       search_types[0] = UnaryExpression(u.clone(), new d_dx(0));
00255       search_types[1] = UnaryExpression(u.clone(), new d_dx(1));
00256       search_types[2] = UnaryExpression(v.clone(), new d_dx(0));
00257       search_types[3] = UnaryExpression(v.clone(), new d_dx(1));
00258       
00259       std::vector<Expression> replace_types(4);
00260       replace_types[0] = viennamath::diff(u, r) * dr_dx + viennamath::diff(u, s) * ds_dx;
00261       replace_types[1] = viennamath::diff(u, r) * dr_dy + viennamath::diff(u, s) * ds_dy;
00262       
00263       replace_types[2] = viennamath::diff(v, r) * dr_dx + viennamath::diff(v, s) * ds_dx;
00264       replace_types[3] = viennamath::diff(v, r) * dr_dy + viennamath::diff(v, s) * ds_dy;
00265       
00266       //substitute expressions in lhs and rhs:
00267       new_lhs = viennamath::substitute(search_types, replace_types, weak_form.lhs());
00268       new_rhs = viennamath::substitute(search_types, replace_types, weak_form.rhs());
00269       
00270       viennamath::rt_manipulation_wrapper<InterfaceType> jacobian_manipulator( new detail::jacobian_adder<CellType, InterfaceType, ReferenceCellTag>() );
00271       Expression new_lhs_with_jacobian(new_lhs.get()->recursive_manipulation(jacobian_manipulator));
00272       Expression new_rhs_with_jacobian(new_rhs.get()->recursive_manipulation(jacobian_manipulator));
00273       
00274       return EquationType(new_lhs_with_jacobian, new_rhs_with_jacobian);
00275     }
00276 
00277 
00278 
00279 
00281 
00282     //
00283     // Tetrahedra and Hexahedra
00284     //
00286     template <typename CellType, typename EquationType, typename PDESystemType, typename ReferenceCellTag>
00287     EquationType transform_to_reference_cell_3d(EquationType const & weak_form,
00288                                                 PDESystemType const & pde_system,
00289                                                 ReferenceCellTag)
00290     {
00291       typedef typename EquationType::interface_type             InterfaceType;
00292       typedef viennamath::rt_function_symbol<InterfaceType>   FunctionSymbol;
00293       typedef viennamath::rt_expr<InterfaceType>              Expression;
00294       typedef viennamath::rt_unary_expr<InterfaceType>        UnaryExpression;
00295       typedef viennamath::rt_variable<InterfaceType>          Variable;
00296       typedef viennamath::op_unary<viennamath::op_partial_deriv<viennamath::default_numeric_type>, InterfaceType >   d_dx;
00297 
00298       
00299       //FunctionSymbol  u(0, viennamath::unknown_tag<>());
00300       //FunctionSymbol  v(0, viennamath::test_tag<>());
00301       
00302       std::size_t num_components = pde_system.unknown(0).size();
00303       std::cout << "Number of components: " << num_components << std::endl;
00304       std::vector< FunctionSymbol > u(num_components);
00305       for (std::size_t i=0; i<num_components; ++i)
00306         u[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::unknown_tag<>());
00307 
00308       std::vector< FunctionSymbol > v(num_components);
00309       for (std::size_t i=0; i<num_components; ++i)
00310         v[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::test_tag<>());
00311       
00312       Variable      r(0);
00313       Variable      s(1);
00314       Variable      t(2);
00315       
00316       //using local coordinates (r, s) and global coordinates (x, y)
00317       viennafem::cell_quan<CellType, InterfaceType>  dr_dx; detail::wrap_dt_dx<0,0>(dr_dx, ReferenceCellTag());
00318       viennafem::cell_quan<CellType, InterfaceType>  ds_dx; detail::wrap_dt_dx<1,0>(ds_dx, ReferenceCellTag());
00319       viennafem::cell_quan<CellType, InterfaceType>  dt_dx; detail::wrap_dt_dx<2,0>(dt_dx, ReferenceCellTag());
00320       
00321       viennafem::cell_quan<CellType, InterfaceType>  dr_dy; detail::wrap_dt_dx<0,1>(dr_dy, ReferenceCellTag());
00322       viennafem::cell_quan<CellType, InterfaceType>  ds_dy; detail::wrap_dt_dx<1,1>(ds_dy, ReferenceCellTag());
00323       viennafem::cell_quan<CellType, InterfaceType>  dt_dy; detail::wrap_dt_dx<2,1>(dt_dy, ReferenceCellTag());
00324 
00325       viennafem::cell_quan<CellType, InterfaceType>  dr_dz; detail::wrap_dt_dx<0,2>(dr_dz, ReferenceCellTag());
00326       viennafem::cell_quan<CellType, InterfaceType>  ds_dz; detail::wrap_dt_dx<1,2>(ds_dz, ReferenceCellTag());
00327       viennafem::cell_quan<CellType, InterfaceType>  dt_dz; detail::wrap_dt_dx<2,2>(dt_dz, ReferenceCellTag());
00328       
00329       Expression new_lhs = weak_form.lhs();
00330       Expression new_rhs = weak_form.rhs();
00331 
00332       
00333       std::vector<Expression> search_types(2 * 3 * num_components);
00334       std::size_t current_index = 0;
00335       for (std::size_t i=0; i<num_components; ++i)
00336       {
00337         search_types[current_index++] = UnaryExpression(u[i].clone(), new d_dx(0));
00338         search_types[current_index++] = UnaryExpression(u[i].clone(), new d_dx(1));
00339         search_types[current_index++] = UnaryExpression(u[i].clone(), new d_dx(2));
00340       
00341         search_types[current_index++] = UnaryExpression(v[i].clone(), new d_dx(0));
00342         search_types[current_index++] = UnaryExpression(v[i].clone(), new d_dx(1));
00343         search_types[current_index++] = UnaryExpression(v[i].clone(), new d_dx(2));
00344       }
00345       
00346       std::vector<Expression> replace_types(2 * 3 * num_components);
00347       current_index = 0;
00348       for (std::size_t i=0; i<num_components; ++i)
00349       {
00350         replace_types[current_index++] = viennamath::diff(u[i], r) * dr_dx + viennamath::diff(u[i], s) * ds_dx + viennamath::diff(u[i], t) * dt_dx;
00351         replace_types[current_index++] = viennamath::diff(u[i], r) * dr_dy + viennamath::diff(u[i], s) * ds_dy + viennamath::diff(u[i], t) * dt_dy;
00352         replace_types[current_index++] = viennamath::diff(u[i], r) * dr_dz + viennamath::diff(u[i], s) * ds_dz + viennamath::diff(u[i], t) * dt_dz;
00353         
00354         replace_types[current_index++] = viennamath::diff(v[i], r) * dr_dx + viennamath::diff(v[i], s) * ds_dx + viennamath::diff(v[i], t) * dt_dx;
00355         replace_types[current_index++] = viennamath::diff(v[i], r) * dr_dy + viennamath::diff(v[i], s) * ds_dy + viennamath::diff(v[i], t) * dt_dy;
00356         replace_types[current_index++] = viennamath::diff(v[i], r) * dr_dz + viennamath::diff(v[i], s) * ds_dz + viennamath::diff(v[i], t) * dt_dz;
00357       }
00358       
00359       //substitute expressions in lhs and rhs:
00360       new_lhs = viennamath::substitute(search_types, replace_types, weak_form.lhs());
00361       new_rhs = viennamath::substitute(search_types, replace_types, weak_form.rhs());
00362       
00363       viennamath::rt_manipulation_wrapper<InterfaceType> jacobian_manipulator( new detail::jacobian_adder<CellType,
00364                                                                                                           InterfaceType,
00365                                                                                                           ReferenceCellTag>() );
00366       Expression new_lhs_with_jacobian(new_lhs.get()->recursive_manipulation(jacobian_manipulator));
00367       Expression new_rhs_with_jacobian(new_rhs.get()->recursive_manipulation(jacobian_manipulator));
00368       
00369       return EquationType(new_lhs_with_jacobian, new_rhs_with_jacobian);
00370     }
00371 
00372   } //namespace detail
00373   
00374 
00376   
00377   // TODO: This can be more automatic/generative -> arbitrary dimensions!
00378 
00379   // 1d
00380 
00382   template <typename CellType, typename EquationType, typename PDESystemType>
00383   EquationType transform_to_reference_cell(EquationType const & weak_form,
00384                                            PDESystemType const & pde_system,
00385                                            viennafem::unit_interval)
00386   {
00387     return  detail::transform_to_reference_cell_1d<CellType>(weak_form, pde_system, viennafem::unit_interval());
00388   }
00389 
00390   // 2d
00391 
00393   template <typename CellType, typename EquationType, typename PDESystemType>
00394   EquationType transform_to_reference_cell(EquationType const & weak_form,
00395                                            PDESystemType const & pde_system,
00396                                            viennafem::unit_square)
00397   {
00398     return  detail::transform_to_reference_cell_2d<CellType>(weak_form, pde_system, viennafem::unit_square());
00399   }
00400 
00402   template <typename CellType, typename EquationType, typename PDESystemType>
00403   EquationType transform_to_reference_cell(EquationType const & weak_form,
00404                                            PDESystemType const & pde_system,
00405                                            viennafem::unit_triangle)
00406   {
00407     return  detail::transform_to_reference_cell_2d<CellType>(weak_form, pde_system, viennafem::unit_triangle());
00408   }
00409 
00410   // 3d
00411 
00413   template <typename CellType, typename EquationType, typename PDESystemType>
00414   EquationType transform_to_reference_cell(EquationType const & weak_form,
00415                                            PDESystemType const & pde_system,
00416                                            viennafem::unit_cube)
00417   {
00418     return  detail::transform_to_reference_cell_3d<CellType>(weak_form, pde_system, viennafem::unit_cube());
00419   }
00420 
00422   template <typename CellType, typename EquationType, typename PDESystemType>
00423   EquationType transform_to_reference_cell(EquationType const & weak_form,
00424                                            PDESystemType const & pde_system,
00425                                            viennafem::unit_tetrahedron)
00426   {
00427     return  detail::transform_to_reference_cell_3d<CellType>(weak_form, pde_system, viennafem::unit_tetrahedron());
00428   }
00429 
00430 
00431   // entry point:
00433   template <typename CellType, typename EquationType, typename PDESystemType>
00434   EquationType transform_to_reference_cell(EquationType const & weak_form,
00435                                            PDESystemType const & pde_system)
00436   {
00437     typedef typename CellType::tag        CellTag;
00438     
00439     return  transform_to_reference_cell<CellType>(weak_form, 
00440                                                   pde_system,
00441                                                   typename reference_cell_for_basis<CellTag, viennafem::lagrange_tag<1> >::type());
00442   }
00443   
00444   
00445   
00446   
00447   
00448   
00449   
00450   
00452   
00453 
00454 
00465   template <typename EquationType, typename PDESystemType, typename ExpressionType>
00466   EquationType insert_test_and_trial_functions(EquationType weak_form,
00467                                                PDESystemType const & pde_system,
00468                                                std::vector<ExpressionType> test_func,
00469                                                std::vector<ExpressionType> trial_func
00470                                                )
00471   {
00472     typedef typename EquationType::interface_type             InterfaceType;
00473     typedef viennamath::rt_expr<InterfaceType>              Expression;
00474     typedef viennamath::rt_function_symbol<InterfaceType>   FunctionSymbol;
00475     typedef viennamath::rt_unary_expr<InterfaceType>        UnaryExpression;
00476     typedef viennamath::rt_variable<InterfaceType>          Variable;
00477     typedef viennamath::op_unary<viennamath::op_partial_deriv<viennamath::default_numeric_type>, InterfaceType >   d_dx;
00478     
00479     std::vector< FunctionSymbol > u(trial_func.size());
00480     for (std::size_t i=0; i<trial_func.size(); ++i)
00481       u[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::unknown_tag<>());
00482 
00483     std::vector< FunctionSymbol > v(test_func.size());
00484     for (std::size_t i=0; i<test_func.size(); ++i)
00485       v[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::test_tag<>());
00486 
00487     Variable r(0);
00488     Variable s(1);
00489     Variable t(2);
00490     
00491     std::vector<Expression> search_keys(4 * (test_func.size() + trial_func.size()));
00492     std::size_t current_index = 0;
00493     for (std::size_t i=0; i<trial_func.size(); ++i)
00494     {      
00495       search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(0));
00496       search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(1));
00497       search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(2));
00498       search_keys[current_index++] = u[i];
00499     }
00500     
00501     for (std::size_t i=0; i<test_func.size(); ++i)
00502     {      
00503       search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(0));
00504       search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(1));
00505       search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(2));
00506       search_keys[current_index++] = v[i];
00507     }
00508     
00509     
00510     std::vector<Expression> replacements(4 * (test_func.size() + trial_func.size()));
00511     current_index = 0;
00512     for (std::size_t i=0; i<trial_func.size(); ++i)
00513     {      
00514       replacements[current_index++] = viennamath::diff(trial_func[i], r);
00515       replacements[current_index++] = viennamath::diff(trial_func[i], s);
00516       replacements[current_index++] = viennamath::diff(trial_func[i], t);
00517       replacements[current_index++] = trial_func[i];
00518     }
00519     
00520     for (std::size_t i=0; i<test_func.size(); ++i)
00521     {      
00522       replacements[current_index++] = viennamath::diff(test_func[i], r);
00523       replacements[current_index++] = viennamath::diff(test_func[i], s);
00524       replacements[current_index++] = viennamath::diff(test_func[i], t);
00525       replacements[current_index++] = test_func[i];
00526     }
00527     
00528     ExpressionType new_lhs = viennamath::substitute(search_keys, replacements, weak_form.lhs());
00529     ExpressionType new_rhs = viennamath::substitute(search_keys, replacements, weak_form.rhs());
00530     
00531     //std::cout << "Old rhs: " << weak_form.rhs() << std::endl;
00532     //std::cout << "New rhs: " << new_rhs << std::endl;
00533     
00534     return EquationType(new_lhs, new_rhs);
00535   }
00536   
00537 
00538 
00539 /* deprecated:
00540   template <typename EquationType, typename PDESystemType, typename ExpressionType>
00541   EquationType insert_test_and_trial_functions_vector(EquationType weak_form,
00542                                                PDESystemType const & pde_system,
00543                                                ExpressionType test_func,
00544                                                ExpressionType trial_func,
00545                                                std::size_t index_i,
00546                                                std::size_t index_j
00547                                                )
00548   {
00549     typedef typename EquationType::interface_type             InterfaceType;
00550     typedef viennamath::rt_expr<InterfaceType>              Expression;
00551     typedef viennamath::rt_function_symbol<InterfaceType>   FunctionSymbol;
00552     typedef viennamath::rt_unary_expr<InterfaceType>        UnaryExpression;
00553     typedef viennamath::rt_variable<InterfaceType>          Variable;
00554     typedef viennamath::op_unary<viennamath::op_partial_deriv<viennamath::default_numeric_type>, InterfaceType >   d_dx;
00555     
00556     std::vector< FunctionSymbol > u(3);
00557     for (std::size_t i=0; i<3; ++i)
00558     {
00559       u[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::unknown_tag<>());
00560       //std::cout << "ID of u at location " << i << ": " << pde_system.unknown(0)[i].id() << std::endl;
00561     }
00562 
00563     std::vector< FunctionSymbol > v(3);
00564     for (std::size_t i=0; i<3; ++i)
00565     {
00566       v[i] = FunctionSymbol(pde_system.unknown(0)[i].id(), viennamath::test_tag<>());
00567       //std::cout << "ID of v at location " << i << ": " << pde_system.unknown(0)[i].id() << std::endl;
00568     }
00569 
00570     Variable r(0);
00571     Variable s(1);
00572     Variable t(2);
00573     
00574     std::vector<Expression> search_keys(4 * (2 + 2));
00575     std::size_t current_index = 0;
00576     for (std::size_t i=0; i<3; ++i)
00577     {      
00578       if (i != index_j)
00579       {  
00580         search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(0));
00581         search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(1));
00582         search_keys[current_index++] = UnaryExpression(u[i].clone(), new d_dx(2));
00583         search_keys[current_index++] = u[i];
00584       }
00585     }
00586     
00587     for (std::size_t i=0; i<3; ++i)
00588     {      
00589       if (i != index_i)
00590       {  
00591         search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(0));
00592         search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(1));
00593         search_keys[current_index++] = UnaryExpression(v[i].clone(), new d_dx(2));
00594         search_keys[current_index++] = v[i];
00595       }
00596     }
00597     
00598     
00599     std::vector<Expression> replacements(4 * (2 + 2));
00600     current_index = 0;
00601     viennamath::rt_constant<double, InterfaceType> c0(0);
00602     for (std::size_t i=0; i<3; ++i)
00603     {      
00604       if (i != index_j)
00605       {
00606         replacements[current_index++] = c0;
00607         replacements[current_index++] = c0;
00608         replacements[current_index++] = c0;
00609         replacements[current_index++] = c0;
00610       }
00611     }
00612     
00613     for (std::size_t i=0; i<3; ++i)
00614     {      
00615       if (i != index_i)
00616       {
00617         replacements[current_index++] = c0;
00618         replacements[current_index++] = c0;
00619         replacements[current_index++] = c0;
00620         replacements[current_index++] = c0;
00621       }
00622     }
00623     
00624     ExpressionType new_lhs = viennamath::substitute(search_keys, replacements, weak_form.lhs());
00625     ExpressionType new_rhs = viennamath::substitute(search_keys, replacements, weak_form.rhs());
00626     
00627     return EquationType(new_lhs, new_rhs);
00628   }
00629   */
00630 
00631 }
00632 #endif

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