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

/export/development/ViennaFEM/viennafem/log/latex.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAFEM_LOG_LATEX_HPP
00002 #define VIENNAFEM_LOG_LATEX_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 
00018 #include <vector>
00019 #include <fstream>
00020 #include "viennafem/forwards.h"
00021 #include "viennafem/log/interface.hpp"
00022 #include "viennafem/cell_quan.hpp"
00023 
00024 #include "viennamath/manipulation/latex.hpp"
00025 
00030 namespace viennafem
00031 {
00032   template <typename InterfaceType>
00033   class latex_logger;
00034   
00035   namespace detail
00036   {
00037   
00038     template <typename EquationArray, typename InterfaceType>
00039     void write_strong_form(EquationArray const & pde_system,
00040                           latex_logger<InterfaceType> & log);
00041     
00042     template <typename EquationArray, typename InterfaceType>
00043     void write_weak_form(EquationArray const & weak_form,
00044                         latex_logger<InterfaceType> & log);
00045     
00046     template <typename EquationArray, typename InterfaceType>
00047     void write_coordinated_weak_form(EquationArray const & weak_form,
00048                                     latex_logger<InterfaceType> & log);
00049     
00050     template <typename EquationArray, typename InterfaceType>
00051     void write_transformed_weak_form(EquationArray const & weak_form,
00052                                     latex_logger<InterfaceType> & log);
00053 
00054     template <typename EquationArray, typename InterfaceType>
00055     void write_test_and_trial_space(EquationArray const & test_space,
00056                                     EquationArray const & trial_space,
00057                                     latex_logger<InterfaceType> & log);
00058     
00059     template <typename InterfaceType>
00060     void write_linear_solver_stats(latex_logger<InterfaceType> & log);
00061 
00062   }
00063   
00064 
00065   //
00066   // cell_quan_handler
00067   //
00073   template <typename CellType, typename InterfaceType>
00074   class rt_latex_dt_dx_processor : public viennamath::rt_latex_processor_interface<InterfaceType>
00075   {
00076       typedef typename InterfaceType::numeric_type              NumericType;
00077       typedef viennafem::cell_quan<CellType, InterfaceType>     CellQuanType;
00078     
00079     public:
00080       
00081       std::string process(InterfaceType const * ptr, bool use_parenthesis, viennamath::rt_latex_translator<InterfaceType> const & translator) const 
00082       {
00083         if (dynamic_cast< const CellQuanType * >(ptr) != NULL)
00084         {
00085           const CellQuanType * temp = dynamic_cast< const CellQuanType * >(ptr);
00086           return process_impl(*temp, use_parenthesis, translator);
00087         }
00088         
00089         return "";
00090       }
00091        
00092       bool customize(InterfaceType const * e, std::string const & str)
00093       {
00094         return false;
00095       }
00096       
00097     private:
00098 
00099       std::string process_impl(CellQuanType const & e, bool use_parenthesis, viennamath::rt_latex_translator<InterfaceType> const & translator) const 
00100       {
00101         typedef viennamath::expr      ExpressionType;
00102         
00103         std::stringstream ss;
00104         
00105         viennamath::variable x(0);
00106         viennamath::variable y(1);
00107         viennamath::variable z(2);
00108         
00109         std::auto_ptr< detail::cell_quan_interface<CellType> > temp(e.wrapper().clone());  //create a clone in order to dispatch with respect to the type
00110         
00111         if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<0,0>, ExpressionType> * >(temp.get()) != NULL
00112             || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<0,0>, NumericType> * >(temp.get()) != NULL)
00113         {
00114           ss << " \\frac{\\partial \\xi}{\\partial x} ";
00115         }
00116         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<1,0>, ExpressionType> * >(temp.get()) != NULL
00117                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<1,0>, NumericType> * >(temp.get()) != NULL)
00118         {
00119           ss << " \\frac{\\partial \\eta}{\\partial x} ";
00120         }
00121         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<2,0>, ExpressionType> * >(temp.get()) != NULL
00122                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<2,0>, NumericType> * >(temp.get()) != NULL)
00123         {
00124           ss << " \\frac{\\partial \\nu}{\\partial x} ";
00125         }
00126 
00127         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<0,1>, ExpressionType> * >(temp.get()) != NULL
00128                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<0,1>, NumericType> * >(temp.get()) != NULL)
00129         {
00130           ss << " \\frac{\\partial \\xi}{\\partial y} ";
00131         }
00132         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<1,1>, ExpressionType> * >(temp.get()) != NULL
00133                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<1,1>, NumericType> * >(temp.get()) != NULL)
00134         {
00135           ss << " \\frac{\\partial \\eta}{\\partial y} ";
00136         }
00137         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<2,1>, ExpressionType> * >(temp.get()) != NULL
00138                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<2,1>, NumericType> * >(temp.get()) != NULL)
00139         {
00140           ss << " \\frac{\\partial \\nu}{\\partial y} ";
00141         }
00142 
00143         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<0,2>, ExpressionType> * >(temp.get()) != NULL
00144                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<0,2>, NumericType> * >(temp.get()) != NULL)
00145         {
00146           ss << " \\frac{\\partial \\xi}{\\partial z} ";
00147         }
00148         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<1,2>, ExpressionType> * >(temp.get()) != NULL
00149                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<1,2>, NumericType> * >(temp.get()) != NULL)
00150         {
00151           ss << " \\frac{\\partial \\eta}{\\partial z} ";
00152         }
00153         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::dt_dx_key<2,2>, ExpressionType> * >(temp.get()) != NULL
00154                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::dt_dx_key<2,2>, NumericType> * >(temp.get()) != NULL)
00155         {
00156           ss << " \\frac{\\partial \\nu}{\\partial z} ";
00157         }
00158 
00159         else if (dynamic_cast< detail::cell_quan_expr<CellType, viennafem::det_dF_dt_key, ExpressionType> * >(temp.get()) != NULL
00160                  || dynamic_cast< detail::cell_quan_constant<CellType, viennafem::det_dF_dt_key, NumericType> * >(temp.get()) != NULL)
00161         {
00162           ss << " \\mathrm{det} F ";
00163         }
00164         else       
00165           std::cerr << "Warning: could not find string for cell_quan!" << std::endl;
00166 
00167         return ss.str();        
00168       }
00169       
00170   };
00171  
00172     
00173   
00178   template <typename InterfaceType>
00179   class latex_logger : public logger_interface<InterfaceType>
00180   {
00181       typedef logger_interface<InterfaceType>    BaseType;
00182       typedef typename BaseType::EquationType             EquationType;
00183     
00184     public:
00185       latex_logger(std::string const & filename) : stream_(filename.c_str()), filename_(filename), something_written(false)
00186       {
00187         viennamath::function_symbol u0(0, viennamath::unknown_tag<>());
00188         viennamath::function_symbol u1(1, viennamath::unknown_tag<>());
00189         viennamath::function_symbol u2(2, viennamath::unknown_tag<>());
00190         
00191         viennamath::function_symbol v0(0, viennamath::test_tag<>());
00192         viennamath::function_symbol v1(1, viennamath::test_tag<>());
00193         viennamath::function_symbol v2(2, viennamath::test_tag<>());
00194         
00195         translator_.customize(u0, "u_0");
00196         translator_.customize(u1, "u_1");
00197         translator_.customize(u2, "u_2");
00198         
00199         translator_.customize(v0, "v_0");
00200         translator_.customize(v1, "v_1");
00201         translator_.customize(v2, "v_2");        
00202       }
00203       
00204       latex_logger(const latex_logger & other) : stream_(other.filename_.c_str()),
00205                                                  filename_(other.filename_),
00206                                                  something_written(false),
00207                                                  translator_(other.translator_) {}
00208       
00209       ~latex_logger()
00210       { 
00211         //write footer:
00212         if (something_written)
00213           stream_ << "\\end{document}" << std::endl;
00214         
00215         stream_.close();
00216       }
00217       
00218       void write_strong_form(std::vector<EquationType> const & pdes) { viennafem::detail::write_strong_form(pdes, *this); }
00219       void write_weak_form(std::vector<EquationType> const & pdes) { viennafem::detail::write_weak_form(pdes, *this); }
00220       void write_coordinated_weak_form(std::vector<EquationType> const & pdes) { viennafem::detail::write_coordinated_weak_form(pdes, *this); }
00221       void write_transformed_weak_form(std::vector<EquationType> const & pdes) { viennafem::detail::write_transformed_weak_form(pdes, *this); }
00222       void write_test_and_trial_space(std::vector<viennamath::expr> const & test_space,
00223                                       std::vector<viennamath::expr> const & trial_space)
00224       {
00225         viennafem::detail::write_test_and_trial_space(test_space, trial_space, *this);
00226       }
00227 
00228 
00229       void write_header()
00230       {
00231         stream_ << "\\documentclass[11pt]{article}\n";
00232         stream_ << "\\usepackage{amsmath}\n";
00233         stream_ << "\\usepackage[cm]{fullpage}\n";
00234         stream_ << "\\title{ViennaFEM Protocol}\n";
00235         stream_ << "\n";
00236         stream_ << "\\begin{document}\n";
00237         stream_ << "\\begin{center}\n";
00238         stream_ << "\\LARGE ViennaFEM Protocol\n";
00239         stream_ << "\\end{center}\n";
00240         stream_ << "\n";
00241         
00242       }
00243 
00244       template <typename T>
00245       void stream(T const & t)
00246       {
00247         if (!something_written)
00248         {
00249           write_header();
00250           something_written = true;
00251         }
00252         stream_ << t;
00253       }
00254       void flush() {  }
00255 
00256       viennamath::latex_translator & translator() { return translator_; }
00257       
00258     private:
00259       latex_logger & operator=(latex_logger const & other);
00260       
00261       std::ofstream stream_;
00262       const std::string filename_;
00263       bool something_written;
00264       viennamath::latex_translator translator_;
00265   };
00266   
00268   template <typename InterfaceType, typename T>
00269   latex_logger<InterfaceType> & operator<<(latex_logger<InterfaceType> & logger, T const & t)
00270   {
00271      logger.stream(t);
00272      return logger;
00273   }
00274 
00275   
00276   
00277   namespace detail
00278   {
00279 
00281     template <typename EquationArray, typename InterfaceType>
00282     void write_strong_form(EquationArray const & pdes,
00283                           latex_logger<InterfaceType> & log)
00284     {
00285       log << "\\section{Strong Formulation}\n";
00286       log << "The strong formulation of the problem is to solve\n";
00287       log << "\\begin{align}\n";
00288       log << log.translator()(pdes[0]) << " \n";
00289       log << "\\end{align}\n";
00290       log << "in $\\Omega$ with suitable boundary conditions.\n";
00291     }
00292 
00294     template <typename EquationArray, typename InterfaceType>
00295     void write_weak_form(EquationArray const & weak_form,
00296                         latex_logger<InterfaceType> & log)
00297     {
00298       log << "\\section{Weak Formulation}\n";
00299       log << "After multiplication with a test function $v$, integration over $\\Omega$ and partial integration, the weak formulation of the problem is obtained as\n";
00300       log << "\\begin{align}\n";
00301       for (typename EquationArray::const_iterator it = weak_form.begin();
00302                                                   it != weak_form.end();
00303                                                 ++it)
00304         log << log.translator()(*it) << " \n";
00305       log << "\\end{align}\n";
00306       log << "for all test functions $v$.\n";
00307     }
00308 
00310     template <typename EquationArray, typename InterfaceType>
00311     void write_coordinated_weak_form(EquationArray const & weak_form,
00312                                     latex_logger<InterfaceType> & log)
00313     {
00314       log << "Written in coordinates for the underlying simulation domain, the weak form is \n";
00315       log << "\\begin{align}\n";
00316       for (typename EquationArray::const_iterator it = weak_form.begin();
00317                                                   it != weak_form.end();
00318                                                 ++it)
00319         log << log.translator()(*it) << " \n";
00320       log << "\\end{align}\n";
00321       log << "for all testfunctions $v$.\n";
00322     }
00323 
00325     template <typename EquationArray, typename InterfaceType>
00326     void write_transformed_weak_form(EquationArray const & weak_form,
00327                                     latex_logger<InterfaceType> & log)
00328     {
00329       // Restriction to the discrete space
00330       log << "\\section{Discrete Approximation by Finite Elements}\n";
00331       log << "The discrete approximation to the continuous problem is obtained by a Galerkin approach:\n";
00332       log << "\\begin{align}\n";
00333       log << " u_h = \\sum_j \\alpha_j \\varphi_j  \n";
00334       log << "\\end{align}\n";
00335       log << "with trial functions $\\varphi_j$.\n";
00336       //log << "Thus, instead of solving for the continuous function $u$, only the coefficients $\\alpha_i$ need to be computed.\n";
00337       log << "In a Galerkin approach, test functions $v$ are also chosen from a finite-dimensional space:\n";
00338       log << "\\begin{align}\n";
00339       log << " v_h = \\sum_i \\beta_i \\psi_i  \n";
00340       log << "\\end{align}\n";
00341       log << "Due to integral transformations, it is sufficient to define the trial and test functions on the reference cell.\n";
00342       log << "After transformation to the reference cell, the weak form on a cell reads\n";
00343       
00344       // give new name to local variables:
00345       viennamath::variable xi(0);
00346       viennamath::variable eta(1);
00347       viennamath::variable nu(2);
00348 
00349       log.translator().customize(xi, "\\xi");
00350       log.translator().customize(eta, "\\eta");
00351       log.translator().customize(nu, "\\nu");
00352       
00353       viennamath::function_symbol u0(0, viennamath::unknown_tag<>());
00354       viennamath::function_symbol u1(1, viennamath::unknown_tag<>());
00355       viennamath::function_symbol u2(2, viennamath::unknown_tag<>());
00356       
00357       viennamath::function_symbol v0(0, viennamath::test_tag<>());
00358       viennamath::function_symbol v1(1, viennamath::test_tag<>());
00359       viennamath::function_symbol v2(2, viennamath::test_tag<>());
00360       
00361       log.translator().customize(u0, "\\tilde{u}_0");
00362       log.translator().customize(u1, "\\tilde{u}_1");
00363       log.translator().customize(u2, "\\tilde{u}_2");
00364       
00365       log.translator().customize(v0, "\\tilde{v}_0");
00366       log.translator().customize(v1, "\\tilde{v}_1");
00367       log.translator().customize(v2, "\\tilde{v}_2");        
00368       
00369       log << "\\begin{align}\n";
00370       for (typename EquationArray::const_iterator it = weak_form.begin();
00371                                                   it != weak_form.end();
00372                                                 ++it)
00373         log << log.translator()(*it) << " \\  . \n";
00374       log << "\\end{align}\n";
00375     
00376       
00377       //
00378       //log << "write transformed weak form\n";
00379     }
00380 
00382     template <typename EquationArray, typename InterfaceType>
00383     void write_test_and_trial_space(EquationArray const & test_space,
00384                                     EquationArray const & trial_space,
00385                                     latex_logger<InterfaceType> & log)
00386     {
00387       log << "The trial functions used for the discrete approximation of $u_h$ on the reference element are \n";
00388       log << "\\begin{align*}\n";
00389       std::size_t func_index = 0;
00390       for (typename EquationArray::const_iterator it = trial_space.begin();
00391                                                   it != trial_space.end();
00392                                                 ++it)
00393       {
00394         if (func_index > 0) //finish previous line
00395           log << " \\ , \\\\ \n";
00396         
00397         log << "\\varphi_{" << func_index << "} &= " << log.translator()(*it);
00398         ++func_index;
00399       }
00400       log << " \\ . \n \\end{align*}\n";
00401       log << "The test functions on the reference element are\n";
00402       log << "\\begin{align*}\n";
00403       func_index = 0;
00404       for (typename EquationArray::const_iterator it = test_space.begin();
00405                                                   it != test_space.end();
00406                                                 ++it)
00407       {
00408         if (func_index > 0) //finish previous line
00409           log << " \\ , \\\\ \n";
00410         
00411         log << "\\psi_{" << func_index << "} &= " << log.translator()(*it);
00412         ++func_index;
00413       }
00414       log << " \\ . \n \\end{align*}\n";
00415       log << "\n";
00416     }
00417     
00419     template <typename InterfaceType>
00420     void write_linear_solver_stats(latex_logger<InterfaceType> & log)
00421     {
00422       log << "write linear solver stats\n";
00423     }
00424 
00425   } //namespace detail
00426 
00427 } //namespace viennafem
00428 
00429 #endif

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