comparison doc/doc.tex @ 199:b8bde50ffb44

Update description of classes.
author gedeone-octave <marcovass89@hotmail.it>
date Fri, 20 Dec 2013 11:08:10 +0100
parents 8fb754d059be
children 3f3db13d7bc2
comparison
equal deleted inserted replaced
198:8fb754d059be 199:b8bde50ffb44
1 \documentclass[a4paper,10pt]{book} 1 \documentclass[a4paper,11pt]{book}
2 \usepackage[utf8x]{inputenc} 2 \usepackage[utf8x]{inputenc}
3 \usepackage{graphicx} 3 \usepackage{graphicx}
4 \usepackage{amsmath} 4 \usepackage{amsmath}
5 \usepackage{amssymb} 5 \usepackage{amssymb}
6 \usepackage{caption} 6 \usepackage{caption}
81 {\large \today} 81 {\large \today}
82 82
83 \end{center} 83 \end{center}
84 \end{titlepage} 84 \end{titlepage}
85 85
86 \frontmatter
87
86 \tableofcontents 88 \tableofcontents
89
90 \mainmatter
87 91
88 \chapter{Introduction} 92 \chapter{Introduction}
89 Fem-fenics is an open source package (pkg) for the resolution of partial differential equations with Octave. 93 Fem-fenics is an open source package (pkg) for the resolution of partial differential equations with Octave.
90 The project has been developed during the Google Summer of Code 2013 with the help and the sustain of the GNU-Octave 94 The project has been developed during the Google Summer of Code 2013 with the help and the sustain of the GNU-Octave
91 community under the supervision of prof. De Falco. 95 community under the supervision of prof. De Falco.
107 \end{center} 111 \end{center}
108 while if you want to see how the project has grown during the time you can give a look at 112 while if you want to see how the project has grown during the time you can give a look at
109 \begin{center} 113 \begin{center}
110 \url{http://gedeone-gsoc.blogspot.com/} 114 \url{http://gedeone-gsoc.blogspot.com/}
111 \end{center} 115 \end{center}
112 Finally, the API is available as Appendix but also at the following address 116 The API is available as Appendix \ref{app} but also at the following address
113 \begin{center} 117 \begin{center}
114 \url{http://octave.sourceforge.net/fem-fenics/overview.html} 118 \url{http://octave.sourceforge.net/fem-fenics/overview.html}
119 \end{center}
120 and if you would like to contribute to the project or give a look to the source code
121 you can clone it from the following repository using mercurial
122 \begin{center}
123 \url{http://sourceforge.net/p/octave/fem-fenics/} .
115 \end{center} 124 \end{center}
116 125
117 \chapter{Introduction to Fem-fenics}\label{intr} 126 \chapter{Introduction to Fem-fenics}\label{intr}
118 127
119 \section{Installation} 128 \section{Installation}
392 \begin{itemize} 401 \begin{itemize}
393 \item keep the syntax as close as possible to the original one in Fenics (Python) 402 \item keep the syntax as close as possible to the original one in Fenics (Python)
394 \item make the interface as simple as possible. 403 \item make the interface as simple as possible.
395 \end{itemize} 404 \end{itemize}
396 405
397 \section{General layout of a class} 406 \section{General layout of a class}\label{class}
398 Seven new classes are implemented for dealing with FEniCS objects and for using them inside Octave: 407 Seven new classes are implemented for dealing with FEniCS objects and for using them inside Octave:
399 \begin{itemize} 408 \begin{itemize}
400 \item \textbf{boundarycondition} stores and builds a dolfin::DirichletBC 409 \item \textbf{boundarycondition} stores and builds a dolfin::DirichletBC
401 \item \textbf{coefficient} stores an expression object which is used for the 410 \item \textbf{coefficient} stores an expression object which is used for the
402 evaluation of user defined values 411 evaluation of user defined values
868 \end{center} 877 \end{center}
869 878
870 where the Finite Elements denoted with * are not yet fully supported inside FEniCS. 879 where the Finite Elements denoted with * are not yet fully supported inside FEniCS.
871 880
872 \section{General layout of a function} 881 \section{General layout of a function}
873 There are three general kinds of functions in the code: functions which create an abstract problem 882 There are two general kinds of functions in the code: functions which create an abstract problem
874 (wrappers to UFL), 883 (wrappers to UFL) and
875 functions which create the specific instance of a problem (wrapper to FEniCS) and functions 884 functions which create the specific instance of a problem and discretize it (wrapper to DOLFIN).
876 which discretize the problem and generate the matrices. 885 \section{Wrappers to UFL}
877 \subsection{Wrappers to UFL} 886 As stated in section \ref{genlayout}, a problem is divided in two files: a \texttt{.ufl} file
878 As stated in section \ref{genlayout}, a problem is divided in two files:a \textit{.ufl} file
879 where the abstract problem is described in Unified Form Language (UFL), 887 where the abstract problem is described in Unified Form Language (UFL),
880 and a script file \textit{.m} where a specific problem is implemented and solved. 888 and a script file \texttt{.m} where a specific problem is implemented and solved.
881 We suppose that they are called Poisson.ufl and Poisson.m . 889 We suppose that they are called \texttt{Poisson.ufl} and \texttt{Poisson.m} .
882 In order to use the information stored in the UFL file, i.e. the bilinear and the linear form, 890 In order to use the information stored in the UFL file, i.e. the bilinear and the linear form,
883 they have to be imported inside Octave. 891 they have to be ``imported'' inside Octave. This is done using the
884 When the UFL file is compiled using the ffc compiler, a header file \textit{Poisson.h} is generated. 892 functions \texttt{import\_ufl\_BilinearForm, import\_ufl\_LinearForm, ...} .
893 \subsection{Generation of code on the fly}
894 When a UFL file is compiled using the ffc compiler, a header file \texttt{Poisson.h} is generated.
885 In this header file, it is defined the Poisson class, which derives from dolfin::Form, 895 In this header file, it is defined the Poisson class, which derives from dolfin::Form,
886 and the constructor for the bilinear and linear form are set. 896 and the constructor for the bilinear and linear form are set.
887 This file is thus available only at compilation time, but it has to be included somehow 897 This file is thus available only at compilation time, but it has to be included somehow
888 in the wrapper function for the Bilinear and the Linear form. 898 in the wrapper function for the Bilinear and the Linear form.
889 An easy solution would have been to write a set of pre established problems where the user could only 899 An easy solution would have been to write a set of pre established problems where the user could only
890 change the values of the coefficient for a specific problem; 900 change the values of the coefficient for a specific problem;
891 but, as we want to let the user free to write his own 901 but, as we want to let the user free to write his own
892 variational problem, a different approach has been adopted. 902 variational problem, a different approach has been adopted.
893 The ufl file is compiled at run time and generates a header file. 903 The \texttt{ufl} file is compiled at run time and generates its header file.
894 Then, a Poisson.cc file is written from a template which takes as input the name 904 Then, a Poisson.cc file is written from a template which takes as input the name
895 of the header file and is compiled including the Poisson.h file; 905 of the header file and is compiled including the Poisson.h file;
896 now the corresponding octave functions for the specific problem is available and will be used from 906 now the corresponding Octave functions for the specific problem are available and
897 BilinearForm, LinearForm, FunctionSpace, ... . 907 will be later used from
908 \texttt{BilinearForm, LinearForm, FunctionSpace, ...} .
898 As an example it is presented the import\_ufl\_BilinearForm function. 909 As an example it is presented the import\_ufl\_BilinearForm function.
899 910
900 \begin{lstlisting}[language=Octave] 911 \begin{lstlisting}[language=Octave]
901 function import_ufl_BilinearForm (var_prob) 912 function import_ufl_BilinearForm (var_prob)
902 913
903 ... 914 ...
904 915
905 %the function which writes the var-prob.cc file 916 %the function which writes the var_prob.cc file (see below)
906 generate_rhs (var_prob); 917 generate_rhs (var_prob);
907 918
908 %the function which writes the makefile 919 %the function which writes the makefile
909 generate_makefile (var_prob, private); 920 generate_makefile (var_prob, private);
910 921
954 965
955 endfunction 966 endfunction
956 \end{lstlisting} 967 \end{lstlisting}
957 968
958 969
959 \subsection{Wrappers to DOLFIN} 970 \section{Wrappers to DOLFIN}
960 The general layout of a function is very simple and it is composed of 4 steps which we describe using an example: 971 The general layout of a function is very simple and it is composed of 4 steps which we describe using an example:
961 \begin{lstlisting} 972 \begin{lstlisting}
962 DEFUN_DLD (fem_fs, args, , "initialize a fs from a mesh") 973 DEFUN_DLD (FunctionSpace, args, , "initialize a FunctionSpace from a mesh")
963 { 974 {
964 // 1 read data 975 // 1 read data
965 const mesh & msho = static_cast<const mesh&> (args(0).get_rep ()); 976 const mesh & msho = static_cast<const mesh&> (args(0).get_rep ());
966 // 2 convert the data from octave to dolfin 977
978 // 2 extract the data stored in the Octave class as a DOLFIN object
967 const dolfin::Mesh & mshd = msho.get_msh (); 979 const dolfin::Mesh & mshd = msho.get_msh ();
968 // 3 build the new object using dolfin 980
981 // 3 build a new object or extract the information needed using DOLFIN
969 boost::shared_ptr <const dolfin::FunctionSpace> g (new Laplace::FunctionSpace (mshd)); 982 boost::shared_ptr <const dolfin::FunctionSpace> g (new Laplace::FunctionSpace (mshd));
970 // 4 convert the new object from dolfin to Octave and return it 983
984 // 4 convert the new object from DOLFIN to Octave and return it
971 octave_value retval = new functionspace(g); 985 octave_value retval = new functionspace(g);
972 return retval; 986 return retval;
973 } 987 }
974 \end{lstlisting} 988 \end{lstlisting}
975 All the functions presented above follow this general structure, and thus here we present 989 All the functions presented above follow this general structure, and thus here we present
976 in detail only functions which present some differences. 990 in detail only functions which present some differences.
977 \subsubsection{Sparse Matrices} 991
978 \subsubsection{Polymorphism} 992 \subsection{DirichletBC and Coefficient}
979 \subsubsection{DirichletBC and Coefficient}
980 These two functions take as input a function handle which cannot be directly evaluated by 993 These two functions take as input a function handle which cannot be directly evaluated by
981 a dolfin function to set, respectively, the value on the boundary or the value of the coefficient. 994 a dolfin function to set, respectively, the value on the boundary or the value of the coefficient.
982 It has thus been derived from dolfin::Expression a class "expression" which has as private member 995 It has thus been derived from dolfin::Expression a class "expression" which has as private member
983 an octave function handle and which overloads the function eval(). In this way, an object of 996 an octave function handle and which overloads the function eval(). In this way, an object of
984 the class expression can be initialized throughout a function handle and can be used inside dolfin because 997 the class expression can be initialized throughout a function handle and can be used inside dolfin because
1021 The coefficient of the variational problem can be specified using either a Coefficient 1034 The coefficient of the variational problem can be specified using either a Coefficient
1022 or a Function. They are different objects which behave in different ways: a Coefficient, as exlained above, 1035 or a Function. They are different objects which behave in different ways: a Coefficient, as exlained above,
1023 overloads the \verb$eval()$ method of the dolfin::Expression class and it is evaluated at 1036 overloads the \verb$eval()$ method of the dolfin::Expression class and it is evaluated at
1024 run time using the octave function \verb$feval()$. A Function instead doesn't need to be evaluated 1037 run time using the octave function \verb$feval()$. A Function instead doesn't need to be evaluated
1025 because it is assembled copying element-by-element the values contained in the input vector. 1038 because it is assembled copying element-by-element the values contained in the input vector.
1039
1040 \subsection{Sparse Matrices}
1041 The \texttt{assemble} function discretize the continuos problem and
1042 return a sparse matrix. To deal with problems of big size, they are stored
1043 using a compressed technique \cite{Formaggia_matr} both in DOLFIN and in Octave.
1044 Unfortunately, DOLFIN uses row major orientation while Octave uses
1045 column major orientation. They have thus to be converted efficiently from
1046 one type to the other.
1047 \begin{lstlisting}[language=C++]
1048
1049 #include "form.h"
1050 #include "boundarycondition.h"
1051
1052 DEFUN_DLD (assemble, args, nargout, " ")
1053 {
1054 int nargin = args.length ();
1055 octave_value_list retval;
1056
1057 if (! boundarycondition_type_loaded)
1058 {
1059 boundarycondition::register_type ();
1060 boundarycondition_type_loaded = true;
1061 mlock ();
1062 }
1063
1064 if (! form_type_loaded)
1065 {
1066 form::register_type ();
1067 form_type_loaded = true;
1068 mlock ();
1069 }
1070
1071 ...
1072
1073 // Extract form object from the input
1074 const form & frm = static_cast<const form&> (args(0).get_rep ());
1075
1076 const dolfin::Form & a = frm.get_form ();
1077 a.check ();
1078
1079 ...
1080
1081 // Assemble the Matrix in DOLFIN
1082 dolfin::parameters["linear_algebra_backend"] = "uBLAS";
1083 dolfin::Matrix A;
1084 dolfin::assemble (A, a);
1085
1086 // Extract BC from input and apply BC
1087 ...
1088 const boundarycondition & bc
1089 = static_cast<const boundarycondition&> (args(i).get_rep ());
1090
1091 const std::vector<boost::shared_ptr <const dolfin::DirichletBC> >
1092 & pbc = bc.get_bc ();
1093
1094 for (std::size_t j = 0; j < pbc.size (); ++j)
1095 pbc[j]->apply(A);
1096
1097
1098 // Get capacity of the dolfin sparse matrix
1099 boost::tuples::tuple<const std::size_t*,
1100 const std::size_t*,
1101 const double*, int>
1102 aa = A.data ();
1103
1104 // Create the Matrix for Octave
1105
1106 ...
1107
1108 for (std::size_t i = 0; i < nr; ++i)
1109 {
1110 A.getrow (i, cidx_tmp, data_tmp);
1111 nz += cidx_tmp.size ();
1112
1113 for (octave_idx_type j = 0;
1114 j < cidx_tmp.size (); ++j)
1115 {
1116 orow [ii + j] = i;
1117 oc [ii + j] = cidx_tmp [j];
1118 ov [ii + j] = data_tmp [j];
1119 }
1120
1121 ii = nz;
1122 }
1123
1124 dims(0) = ii;
1125 ridx.resize (dims);
1126 cidx.resize (dims);
1127 data.resize (dims);
1128
1129 SparseMatrix sm (data, ridx, cidx, nr, nc);
1130 retval(0) = sm;
1131
1132 ...
1133
1134 return retval;
1135 }
1136 \end{lstlisting}
1137
1138
1139 \subsection{Polymorphism}
1140 The objects which belong to the new classes presented in section \ref{class}
1141 have to overload some of the methods already available in Octave.
1142 For example, we want to be able to \texttt{plot} a \texttt{Mesh} or a \texttt{function}, to \texttt{save} it
1143 and to evaluate it at a specific point in the space (\texttt{feval}).
1144 As Octave is a dynamically typed language it could be a difficult task to achieve, but hopefully
1145 the Octave interpreter takes care of it and it is enough to put the polymorphic function
1146 in a folder named as the type. For example, in the \texttt{@function} folder
1147 inside the Fem-fenics directory we can find the \texttt{plot, save, feval} functions.
1148
1026 \iffalse 1149 \iffalse
1027 1150
1028 \paragraph{other function} 1151 \paragraph{other function}
1029 1152
1030 1153
1052 we can instead use the command \verb$assemble_system$ (). Finally, if we are solving a non-linear problem 1175 we can instead use the command \verb$assemble_system$ (). Finally, if we are solving a non-linear problem
1053 and we need to apply essential BC, we should provide to the function also the vector with the 1176 and we need to apply essential BC, we should provide to the function also the vector with the
1054 tentative solution in order to modify the entries corresponding to the boundary values. 1177 tentative solution in order to modify the entries corresponding to the boundary values.
1055 This will be illustrated below in the HyperElasticity example. 1178 This will be illustrated below in the HyperElasticity example.
1056 \fi 1179 \fi
1057
1058 \subsection{Wrapper to FEniCS}
1059
1060 \subsection{Code on the fly}
1061
1062 \iffalse
1063 For the creation on the fly of the code from the header file,
1064 Juan Pablo provided me a python code which makes a great job. I have spent some
1065 time adapting it to my problem, but when I finally got a working code, we realized
1066 that it was probably enough to use the functions available inside Octave because
1067 the problem was rather simple. The pyton code is however available here, while the
1068 final solution adopted can be found there.
1069 \fi
1070
1071 1180
1072 1181
1073 \chapter{More Advanced Examples}\label{exem} 1182 \chapter{More Advanced Examples}\label{exem}
1074 In this chapter more examples are provided. 1183 In this chapter more examples are provided.
1075 At the beginning of each section, the problem is briefly presented and then 1184 At the beginning of each section, the problem is briefly presented and then
1137 # File MixedPoisson.ufl 1246 # File MixedPoisson.ufl
1138 # a = (dot(sigma, tau) + div(tau)*u + div(sigma)*v)*dx 1247 # a = (dot(sigma, tau) + div(tau)*u + div(sigma)*v)*dx
1139 # L = - f*v*dx 1248 # L = - f*v*dx
1140 a = BilinearForm ('MixedPoisson', V, V); 1249 a = BilinearForm ('MixedPoisson', V, V);
1141 L = LinearForm ('MixedPoisson', V, f); 1250 L = LinearForm ('MixedPoisson', V, f);
1251
1252
1142 1253
1143 1254
1144 1255
1145 1256
1146 1257
1296 # we can also use the msh pkg to generate the L-shape domain 1407 # we can also use the msh pkg to generate the L-shape domain
1297 # as showed above 1408 # as showed above
1298 1409
1299 mesh = Mesh ('lshape.xml'); 1410 mesh = Mesh ('lshape.xml');
1300 1411
1301 # Define function spaces (P2-P1). From ufl file 1412 # Define function spaces (P2-P1). UFL file
1302 # V = VectorElement("CG", triangle, 2) 1413 # V = VectorElement("CG", triangle, 2)
1303 # Q = FiniteElement("CG", triangle, 1) 1414 # Q = FiniteElement("CG", triangle, 1)
1304 V = FunctionSpace ('VelocityUpdate', mesh); 1415 V = FunctionSpace ('VelocityUpdate', mesh);
1305 Q = FunctionSpace ('PressureUpdate', mesh); 1416 Q = FunctionSpace ('PressureUpdate', mesh);
1306 1417
1442 p = TrialFunction(Q) 1553 p = TrialFunction(Q)
1443 v = TestFunction(V) 1554 v = TestFunction(V)
1444 q = TestFunction(Q) 1555 q = TestFunction(Q)
1445 1556
1446 # Set parameter values 1557 # Set parameter values
1558 nu = 0.01
1447 dt = 0.01 1559 dt = 0.01
1448 T = 3 1560 T = 3
1449 nu = 0.01
1450 1561
1451 # Define time-dependent pressure BC 1562 # Define time-dependent pressure BC
1452 p_in = Expression("sin(3.0*t)", t=0.0) 1563 p_in = Expression("sin(3.0*t)", t=0.0)
1453 1564
1454 # Define boundary conditions 1565 # Define boundary conditions
1482 1593
1483 1594
1484 # Velocity update 1595 # Velocity update
1485 a3 = inner(u, v)*dx 1596 a3 = inner(u, v)*dx
1486 L3 = inner(u1, v)*dx - k*inner(grad(p1), v)*dx 1597 L3 = inner(u1, v)*dx - k*inner(grad(p1), v)*dx
1487
1488 1598
1489 1599
1490 # Assemble matrices 1600 # Assemble matrices
1491 A1 = assemble(a1) 1601 A1 = assemble(a1)
1492 A2 = assemble(a2) 1602 A2 = assemble(a2)
1712 # Create Dirichlet boundary conditions 1822 # Create Dirichlet boundary conditions
1713 bcl = DirichletBC (V, @(x,y,z) [0; 0; 0], 1); 1823 bcl = DirichletBC (V, @(x,y,z) [0; 0; 0], 1);
1714 bcr = DirichletBC (V, Rotation, 2); 1824 bcr = DirichletBC (V, Rotation, 2);
1715 bcs = {bcl, bcr}; 1825 bcs = {bcl, bcr};
1716 1826
1717
1718 # Define source and boundary traction functions 1827 # Define source and boundary traction functions
1719
1720 B = Constant ('B', [0.0; -0.5; 0.0]); 1828 B = Constant ('B', [0.0; -0.5; 0.0]);
1721 T = Constant ('T', [0.1; 0.0; 0.0]); 1829 T = Constant ('T', [0.1; 0.0; 0.0]);
1722 1830
1723 1831
1724 1832
1922 2030
1923 \colplacechunks 2031 \colplacechunks
1924 \end{parcolumns} 2032 \end{parcolumns}
1925 \end{changemargin} 2033 \end{changemargin}
1926 2034
2035 \iffalse
1927 \section{Fictitious Domain} 2036 \section{Fictitious Domain}
1928 A penalization method to take into account obstacles in incompressible viscous flows 2037 A penalization method to take into account obstacles in incompressible viscous flows
1929 2038 \fi
1930 \newpage 2039 \newpage
2040
2041 \backmatter
2042
1931 \appendix 2043 \appendix
1932 \chapter{API reference} 2044 \chapter{API reference}\label{app}
1933 2045
1934 \section{Import problem defined with ufl} 2046 \section{Import problem defined with ufl}
1935 \subsection*{import\_ufl\_BilinearForm} 2047 \subsection*{import\_ufl\_BilinearForm}
1936 \subimport{latex/}{API/import_ufl_BilinearForm.tex} 2048 \subimport{latex/}{API/import_ufl_BilinearForm.tex}
1937 \subsection*{import\_ufl\_LinearForm} 2049 \subsection*{import\_ufl\_LinearForm}
2042 #endif 2154 #endif
2043 return 0; 2155 return 0;
2044 } 2156 }
2045 2157
2046 \end{lstlisting} 2158 \end{lstlisting}
2159 \iffalse
2047 \paragraph {Warning} If in the Makefile.in you write something like 2160 \paragraph {Warning} If in the Makefile.in you write something like
2048 \begin{lstlisting}[language=make] 2161 \begin{lstlisting}[language=make]
2049 HAVE_DOLFIN_H = @HAVE_DOLFIN_H@ 2162 HAVE_DOLFIN_H = @HAVE_DOLFIN_H@
2050 ifdef HAVE_DOLFIN_H 2163 ifdef HAVE_DOLFIN_H
2051 CPPFLAGS += -DHAVE_DOLFIN_H 2164 CPPFLAGS += -DHAVE_DOLFIN_H
2052 LIBS += -ldolfin 2165 LIBS += -ldolfin
2053 endif 2166 endif
2054 \end{lstlisting} 2167 \end{lstlisting}
2055 it doesn't work because the variable \verb$HAVE_DOLFIN_H$ seems to be always defined, even if the header is not available. 2168 it doesn't work because the variable \verb$HAVE_DOLFIN_H$ seems to be always defined, even if the header is not available.
2169 \fi
2056 2170
2057 \bibliographystyle{unsrt} 2171 \bibliographystyle{unsrt}
2058 \bibliography{doc} 2172 \bibliography{doc}
2059 \end{document} 2173 \end{document}