Go to the documentation of this file.00001 #ifndef VIENNAMATH_WEAK_FORM_HPP
00002 #define VIENNAMATH_WEAK_FORM_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "viennamath/expression.hpp"
00020 #include "viennamath/manipulation/substitute.hpp"
00021
00026 namespace viennafem
00027 {
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 namespace detail
00041 {
00042
00047 template <typename InterfaceType>
00048 struct weak_form_checker : public viennamath::rt_traversal_interface<>
00049 {
00050 public:
00051 weak_form_checker() : is_weak_(false) {}
00052
00053 void operator()(InterfaceType const * e) const
00054 {
00055 if (viennamath::callback_if_castable< viennamath::rt_unary_expr<InterfaceType> >::apply(e, *this))
00056 return;
00057 }
00058
00059 void operator()(viennamath::rt_unary_expr<InterfaceType> const & unary_expr) const
00060 {
00061 typedef viennamath::op_unary<viennamath::op_rt_symbolic_integral<InterfaceType>, InterfaceType> SymbolicIntegrationType;
00062
00063 if (dynamic_cast<const SymbolicIntegrationType *>(unary_expr.op()) != NULL)
00064 is_weak_ = true;
00065 }
00066
00067 bool is_weak() const { return is_weak_; }
00068
00069 private:
00070 mutable bool is_weak_;
00071 };
00072
00073 }
00074
00076 template <typename InterfaceType>
00077 bool is_weak_form(viennamath::rt_equation<InterfaceType> const & strong_formulation)
00078 {
00079 detail::weak_form_checker<InterfaceType> * checker = new detail::weak_form_checker<InterfaceType>();
00080
00081 viennamath::rt_traversal_wrapper<> wrapped_checker( checker );
00082
00083 strong_formulation.lhs().get()->recursive_traversal( wrapped_checker );
00084 return checker->is_weak();
00085 }
00086
00087
00088
00089
00090
00091
00092 namespace detail
00093 {
00095 template <typename InterfaceType>
00096 struct weak_form_creator : public viennamath::rt_manipulation_interface<InterfaceType>
00097 {
00098 public:
00099 InterfaceType * operator()(InterfaceType const * e) const
00100 {
00101 if ( !viennamath::callback_if_castable< viennamath::rt_unary_expr<InterfaceType> >::apply(e, *this)
00102 && !viennamath::callback_if_castable< viennamath::rt_binary_expr<InterfaceType> >::apply(e, *this))
00103 {
00104
00105
00106
00107 viennamath::rt_function_symbol<InterfaceType> test_func(0, viennamath::test_tag<0>());
00108 viennamath::rt_expr<InterfaceType> temp(e->clone());
00109 integrated_expr = viennamath::integral(viennamath::symbolic_interval(), temp * test_func);
00110 }
00111
00112 return integrated_expr.get()->clone();
00113
00114 }
00115
00116 void operator()(viennamath::rt_unary_expr<InterfaceType> const & unary_expr) const
00117 {
00118 typedef typename InterfaceType::numeric_type NumericType;
00119 typedef viennamath::op_unary<viennamath::op_divergence<NumericType>, InterfaceType> DivergenceOperatorType;
00120
00121 if (dynamic_cast<const DivergenceOperatorType *>(unary_expr.op()) != NULL)
00122 {
00123
00124 viennamath::rt_expr<InterfaceType> minus1 = -1;
00125 viennamath::rt_expr<InterfaceType> lhs(unary_expr.lhs()->clone());
00126 viennamath::rt_expr<InterfaceType> rhs = viennamath::grad(viennamath::rt_function_symbol<InterfaceType>(0, viennamath::test_tag<0>()));
00127 integrated_expr = viennamath::integral(viennamath::symbolic_interval(),
00128 minus1 * (lhs * rhs)
00129 );
00130 }
00131 else
00132 throw "Cannot derive weak form!";
00133 }
00134
00135 void operator()(viennamath::rt_binary_expr<InterfaceType> const & bin) const
00136 {
00137 typedef typename InterfaceType::numeric_type NumericType;
00138 typedef viennamath::op_binary<viennamath::op_plus<NumericType>, InterfaceType> PlusOperatorType;
00139 typedef viennamath::op_binary<viennamath::op_minus<NumericType>, InterfaceType> MinusOperatorType;
00140 typedef viennamath::op_binary<viennamath::op_mult<NumericType>, InterfaceType> ProductOperatorType;
00141 typedef viennamath::op_binary<viennamath::op_div<NumericType>, InterfaceType> DivisionOperatorType;
00142
00143 if ( dynamic_cast<const PlusOperatorType *>(bin.op()) != NULL
00144 || dynamic_cast<const MinusOperatorType *>(bin.op()) != NULL)
00145 {
00146 viennamath::rt_manipulation_wrapper<InterfaceType> manipulator(new weak_form_creator<InterfaceType>());
00147
00148 integrated_expr = new viennamath::rt_binary_expr<InterfaceType>(bin.lhs()->recursive_manipulation(manipulator),
00149 bin.op()->clone(),
00150 bin.rhs()->recursive_manipulation(manipulator));
00151 }
00152 else if (dynamic_cast<const ProductOperatorType *>(bin.op()) != NULL
00153 || dynamic_cast<const DivisionOperatorType *>(bin.op()) != NULL)
00154 {
00155
00156
00157 if (bin.lhs()->is_constant())
00158 {
00159 viennamath::rt_manipulation_wrapper<InterfaceType> manipulator(new weak_form_creator<InterfaceType>());
00160
00161 integrated_expr = new viennamath::rt_binary_expr<InterfaceType>(bin.lhs()->clone(),
00162 bin.op()->clone(),
00163 bin.rhs()->recursive_manipulation(manipulator));
00164 }
00165 else if (bin.rhs()->is_constant())
00166 {
00167 viennamath::rt_manipulation_wrapper<InterfaceType> manipulator(new weak_form_creator<InterfaceType>());
00168
00169 integrated_expr = new viennamath::rt_binary_expr<InterfaceType>(bin.lhs()->recursive_manipulation(manipulator),
00170 bin.op()->clone(),
00171 bin.rhs()->clone());
00172 }
00173 else
00174 {
00175 throw "cannot derive weak form!";
00176 }
00177 }
00178 else
00179 {
00180
00181 viennamath::rt_function_symbol<InterfaceType> test_func(0, viennamath::test_tag<0>());
00182 integrated_expr = viennamath::integral(viennamath::symbolic_interval(),
00183 bin * test_func);
00184 }
00185 }
00186
00187 bool modifies(InterfaceType const * e) const { return true; }
00188
00189 private:
00190 mutable viennamath::rt_expr<InterfaceType> integrated_expr;
00191 };
00192
00193 }
00194
00195
00197 template <typename InterfaceType>
00198 viennamath::rt_equation<InterfaceType> make_weak_form(viennamath::rt_equation<InterfaceType> const & strong_formulation)
00199 {
00200 if (is_weak_form(strong_formulation))
00201 {
00202 std::cout << "ViennaFEM: make_weak_form(): Nothing to do, problem already in weak form!" << std::endl;
00203 return strong_formulation;
00204 }
00205
00206 viennamath::rt_manipulation_wrapper<InterfaceType> wrapped_checker( new detail::weak_form_creator<InterfaceType>() );
00207 viennamath::rt_expr<InterfaceType> weak_lhs(strong_formulation.lhs().get()->recursive_manipulation( wrapped_checker ));
00208 viennamath::rt_expr<InterfaceType> weak_rhs =
00209 viennamath::integral(viennamath::symbolic_interval(),
00210 strong_formulation.rhs() * viennamath::rt_function_symbol<InterfaceType>(0, viennamath::test_tag<0>())
00211 );
00212
00213 return viennamath::rt_equation<InterfaceType>(weak_lhs, weak_rhs);
00214
00215 }
00216
00217 }
00218
00219 #endif