📄 formlanguage.tex
字号:
\end{equation}If \texttt{v} is logically vector-valued, the result is a matrix withrows given by the gradients of each component:\begin{equation} \mbox{\texttt{grad(v)}}[i][j] \leftrightarrow \left(\mathrm{grad(v)}\right)_{ij} = \left(\nabla v\right)_{ij} = \frac{\partial v_i}{\partial x_j}.\end{equation}Thus, if \texttt{v} is scalar-valued, then \texttt{grad(grad(v))}returns the Hessian of \texttt{v}, and if \texttt{v} is vector-valued,then \texttt{grad(v)} is the Jacobian of \texttt{v}.\index{Hessian}\index{Jacobian}\subsection{Divergence: \texttt{div(v)}}\index{divergence}\index{\texttt{div}}The operator \texttt{div} accepts as argument a logicallyvector-valued expression and returns its divergence:\begin{equation} \mbox{\texttt{div(v)}} \leftrightarrow \mathrm{div} \, v = \nabla \cdot v = \sum_{i=0}^{d-1} \frac{\partial v_i}{\partial x_i}.\end{equation}Note that the length $n$ of the vector \texttt{v} must be equal to thedimension $d$ of the underlying shape of the \texttt{FiniteElement}defining the function space for~\texttt{v}.\subsection{Curl: \texttt{curl(v)}}\index{rotation}\index{curl}\index{\texttt{curl}}\index{\texttt{rot}}The operator \texttt{curl} accepts as argument a logicallyvector-valued expression and returns its curl:\begin{equation} \mbox{\texttt{curl(v)}} \leftrightarrow \mathrm{curl} \, v = \nabla \times v = (\frac{\partial v_2}{\partial x_1} - \frac{\partial v_1}{\partial x_2}, \frac{\partial v_0}{\partial x_2} - \frac{\partial v_2}{\partial x_0}, \frac{\partial v_1}{\partial x_0} - \frac{\partial v_0}{\partial x_1}).\end{equation}Note that this operator is only defined for vectors of length three.Alternatively, the name \texttt{rot} can be used for this operator.%------------------------------------------------------------------------------\section{Integrals}\index{integrals}Each term of a valid form expression must be a scalar-valuedexpression integrated exactly once. Integrals are expressed throughmultiplication with a measure, representing either an integral overthe interior of the domain $\Omega$ (cell integral), the boundary$\partial \Omega$ of $\Omega$ (exterior facet integral) or the set ofinterior facets (interior facet integral).\subsection{Cell integrals: \texttt{*dx}}\index{interior measure}\index{cell integral}A measure for integration over the interior of $\Omega$ is created asfollows:\begin{code}dx = Integral("cell")\end{code}For convenience, \ffc{} automatically declares the measure\texttt{dx} which can be used to define cell integrals.If \texttt{v} is a scalar-valued expression, then the integral of\texttt{v} over the interior of $\Omega$ is written as \texttt{v*dx}.\subsection{Exterior facet integrals: \texttt{*ds}}\index{boundary measure}\index{exterior facet integral}A measure for integration over the boundary of $\Omega$ is created asfollows:\begin{code}ds = Integral("exterior facet")\end{code}For convenience, \ffc{} automatically declares the measure \texttt{ds}which can be used to define cell integrals. If \texttt{v} is ascalar-valued expression, then the integral of \texttt{v} over theboundary of $\Omega$ is written as \texttt{v*ds}.\subsection{Interior facet integrals: \texttt{*dS}}\index{boundary measure}\index{interior facet integral}A measure for integration over the set of interior facets of $\Omega$ is created asfollows:\begin{code}dS = Integral("interior facet")\end{code}For convenience, \ffc{} automatically declares the measure\texttt{dS} which can be used to define cell integrals.If \texttt{v} is a scalar-valued expression, then the integral of\texttt{v} over the interior facets of $\Omega$ is written as \texttt{v*dS}.\subsection{Integrals over subsets}Integrals over multiple disjoint subdomains of $\Omega$ may be definedby specifying an additional argument for the number of the subdomainassociated with each integral. The different measures may then becombined to express a form as a sum of integrals over the differentsubdomains.\begin{code}dx0 = Integral("cell", 0)dx1 = Integral("cell", 1)ds0 = Integral("exterior facet", 0)ds1 = Integral("exterior facet", 1)ds2 = Integral("exterior facet", 2)dS0 = Integral("interior facet", 0)a = ...*dx0 + ...*dx1 + ...*ds0 + ...*ds1 + ...*ds2 + ...*dS0\end{code}%------------------------------------------------------------------------------\section{DG operators}\index{DG operators}\index{discontinuous Galerkin}\ffc{} provides operators for implementation of discontinuous Galerkinmethods. These include the evaluation of the jump and averageof a function (or in general an expression) over the interior facets(edges or faces) of a mesh.\subsection{Restriction: \texttt{v('+')} and \texttt{v('-')}}When integrating over interior facets (\texttt{*dS}), one may restrictexpressions to the positive or negative side of the facet:\begin{code}element = FiniteElement("Discontinuous Lagrange", "tetrahedron", 0)v = TestFunction(element)u = TrialFunction(element)f = Function(element)a = f('+')*dot(grad(v)('+'), grad(u)('-'))*dS\end{code}Restriction may be applied to functions of any finite element spacebut will only have effect when applied to expressions that arediscontinuous across facets.\subsection{Jump: \texttt{jump(v)}}The operator \texttt{jump} may be used to express the jump of afunction across a common facet of two cells. Two versions of the\texttt{jump} operator are provided.If called with only one argument, then the \texttt{jump} operatorevaluates to the difference between the restrictions of the givenexpression on the positive and negative sides of the facet:\begin{equation} \mbox{\texttt{jump(v)}} \leftrightarrow \llbracket v \rrbracket = v^+ - v^-.\end{equation}If the expression \texttt{v} is scalar, then \texttt{jump(v)} willalso be scalar, and if \texttt{v} is vector-valued, then \texttt{jump(v)}will also be vector-valued.If called with two arguments, \texttt{jump(v, n)} evaluates to thejump in \texttt{v} weighted by \texttt{n}. Typically, \texttt{n} willbe chosen to represent the unit outward normal of the facet (as seenfrom each of the two neighboring cells). If \texttt{v} is scalar, then\texttt{jump(v, n)} is given by\begin{equation} \mbox{\texttt{jump(v, n)}} \leftrightarrow \llbracket v \rrbracket_n = v^+ n^+ + v^- n^-.\end{equation}If \texttt{v} is vector-valued, then \texttt{jump(v, n)} is given by\begin{equation} \mbox{\texttt{jump(v, n)}} \leftrightarrow \llbracket v \rrbracket_n = v^+ \cdot n^+ + v^- \cdot n^-.\end{equation}Thus, if the expression \texttt{v} is scalar, then \texttt{jump(v, n)} willbe vector-valued, and if \texttt{v} is vector-valued, then\texttt{jump(v, n)} will be scalar.\subsection{Average: \texttt{avg(v)}}The operator \texttt{avg} may be used to express the average of afunction across a common facet of two cells:\begin{equation} \mbox{avg(v)} \leftrightarrow \langle v \rangle = \frac{1}{2} (v^+ + v^-).\end{equation}If the expression \texttt{v} is scalar, then \texttt{avg(v)} willalso be scalar, and if \texttt{v} is vector-valued, then \texttt{avg(v)}will also be vector-valued.%------------------------------------------------------------------------------\section{Special operators}\label{sec:specialoperators}\index{special operators}\index{inverse}\index{absolute value}\index{\texttt{abs}}\index{square root}\index{\texttt{sqrt}}\ffc{} provides a set of special operators for taking the inverse,absolute value and square root of an expression. These operators areinterpreted in a special way and should be used with care. Firstly,the operators are only valid on monomial expressions, that is,expressions that consist of only one term. Secondly, the operators areapplied directly to the \emph{coefficients} of the basis functionexpansion of the expression on which the operators are applied.Thus, if $v = \sum_i v_i \phi_i$, then $\mathrm{op}(v)$ isevaluated by\begin{equation} \mathrm{op}(v) = \sum_i \mathrm{op}(v_i) \phi_i.\end{equation}\subsection{Inverse: \texttt{1/v}}The inverse of a monomial expression (for example a product of one ormore functions) may be evaluated (in the sense described above) asfollows:\begin{code}w = 1/v\end{code}\subsection{Modulus: \texttt{modulus(v)}}The modulus, i.e. the absolute value, of a monomial expression (forexample a product of one or more functions) may be evaluated (in thesense described above) as follows:\begin{code}w = modulus(v)\end{code}\subsection{Square root: \texttt{sqrt(v)}}The square root of a monomial expression (for example a product of one ormore functions) may be evaluated (in the sense described above) asfollows:\begin{code}w = sqrt(v)\end{code}\subsection{Combining operators}The special operators may applied successively and repeatedly on anymonomial expression. Thus, the following expression is valid:\begin{code}v = Function(element)w = sqrt(abs(1/v))\end{code}%------------------------------------------------------------------------------\section{Index notation}\index{index notation}\ffc{} supports index notation, which is often a convenient way toexpress forms. The basic principle of index notation is that summationis implicit over indices repeated twice in each term of an expression.The following examples illustrate the index notation, assuming thateach of the variables \texttt{i} and \texttt{j} have been declared asa free \texttt{Index}:\begin{eqnarray} \mbox{\texttt{v[i]*w[i]}} &\leftrightarrow& \sum_{i=0}^{n-1} v_i w_i, \\ \mbox{\texttt{D(v, i)*D(w, i)}} &\leftrightarrow& \sum_{i=0}^{d-1} \frac{\partial v}{\partial x_i} \frac{\partial w}{\partial x_i} = \nabla v \cdot \nabla w, \\ \mbox{\texttt{D(v[i], i)}} &\leftrightarrow& \sum_{i=0}^{d-1} \frac{\partial v_i}{\partial x_i} = \nabla \cdot v, \\ \mbox{\texttt{D(v[i], j)*D(w[i], j)}} &\leftrightarrow& \sum_{i=0}^{n-1} \sum_{j=0}^{d-1} \frac{\partial v_i}{\partial x_j} \frac{\partial w_i}{\partial x_j}.\end{eqnarray}Index notation is used internally by \ffc{} to represent multilinearforms and \ffc{} will try to simplify forms by replacing sums withindex expressions.%------------------------------------------------------------------------------\section{User-defined operators}\label{sec:user-defined}\index{user-defined operators}A user may define new operators, using standard Python syntax. As anexample, consider the strain-rate operator $\epsilon$ of linear elasticity,defined by\begin{equation} \epsilon(v) = \frac{1}{2} (\nabla v + (\nabla v)^{\top}).\end{equation}This operator can be implemented as a function using the Python \texttt{def}keyword:\begin{code}def epsilon(v): return 0.5*(grad(v) + transp(grad(v)))\end{code}Alternatively, using the shorthand \texttt{lambda} notation, thestrain operator may be defined as follows:\begin{code}epsilon = lambda v: 0.5*(grad(v) + transp(grad(v)))\end{code}\index{def}\index{lambda}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -