<?xml version="1.0" encoding="UTF-8"?>
<refentry version="5.0-subset Scilab" xml:id="gf_asm" xml:lang="en"
          xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xi="http://www.w3.org/2001/XInclude"
          xmlns:svg="http://www.w3.org/2000/svg"
          xmlns:mml="http://www.w3.org/1998/Math/MathML"
          xmlns:html="http://www.w3.org/1999/xhtml"
          xmlns:db="http://docbook.org/ns/docbook">
  <refnamediv>
    <refname>gf_asm</refname>
    <refpurpose>
  General assembly function.

  Many of the functions below use more than one mesh_fem: the main
  mesh_fem (mf_u) used for the main unknown, and data mesh_fem (mf_d)
  used for the data. It is always assumed that the Qdim of mf_d is
  equal to 1: if mf_d is used to describe vector or tensor data, you
  just have to "stack" (in fortran ordering) as many scalar fields as
  necessary.
</refpurpose>
  </refnamediv>

  <refsynopsisdiv>
    <title>Calling Sequence</title>

    <synopsis>M = gf_asm('mass matrix', mesh_im mim, mesh_fem mf1[, mesh_fem mf2[, boundary_num]])</synopsis>
    <synopsis>M = gf_asm('lsneuman matrix', mesh_im mim, mesh_fem mf1, mesh_fem mf2, levelset ls)</synopsis>
    <synopsis>M = gf_asm('nlsgrad matrix', mesh_im mim, mesh_fem mf1, mesh_fem mf2, levelset ls)</synopsis>
    <synopsis>M = gf_asm('stabilization patch matrix', @tm mesh, mesh_fem mf,  mesh_im mim, real ratio, real h)</synopsis>
    <synopsis>L = gf_asm('laplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)</synopsis>
    <synopsis>Le = gf_asm('linear elasticity', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec lambda_d, vec mu_d)</synopsis>
    <synopsis>TRHS = gf_asm('nonlinear elasticity', mesh_im mim, mesh_fem mf_u, vec U, string law, mesh_fem mf_d, mat params, {'tangent matrix'|'rhs'|'incompressible tangent matrix', mesh_fem mf_p, vec P|'incompressible rhs', mesh_fem mf_p, vec P})</synopsis>
    <synopsis>{K, B} = gf_asm('stokes', mesh_im mim, mesh_fem mf_u, mesh_fem mf_p, mesh_fem mf_d, vec nu)</synopsis>
    <synopsis>A = gf_asm('helmholtz', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec k)</synopsis>
    <synopsis>A = gf_asm('bilaplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)</synopsis>
    <synopsis>A = gf_asm('bilaplacian KL', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a, vec nu)</synopsis>
    <synopsis>V = gf_asm('volumic source', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec fd)</synopsis>
    <synopsis>B = gf_asm('boundary source', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec G)</synopsis>
    <synopsis>{HH, RR} = gf_asm('dirichlet', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat H, vec R [, threshold])</synopsis>
    <synopsis>Q = gf_asm('boundary qu term',int boundary_num, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat q)</synopsis>
    <synopsis>{...} = gf_asm('volumic' [,CVLST], expr [, mesh_ims, mesh_fems, data...])</synopsis>
    <synopsis>{...} = gf_asm('boundary', int bnum, string expr [, mesh_im mim, mesh_fem mf, data...])</synopsis>
    <synopsis>Mi = gf_asm('interpolation matrix', mesh_fem mf, mesh_fem mfi)</synopsis>
    <synopsis>Me = gf_asm('extrapolation matrix',mesh_fem mf, mesh_fem mfe)</synopsis>
    <synopsis>B = gf_asm('integral contact Uzawa projection', int bnum, mesh_im mim, mesh_fem mf_u, vec U, mesh_fem mf_lambda, vec vec_lambda, mesh_fem mf_obstacle, vec obstacle, scalar r [, {scalar coeff | mesh_fem mf_coeff, vec coeff} [, int option[, scalar alpha, vec W]]])</synopsis>
    <synopsis>B = gf_asm('level set normal source term', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_lambda, vec vec_lambda, mesh_fem mf_levelset, vec levelset)</synopsis>
  </refsynopsisdiv>

  <refsection>
    <title>Description</title>
    <para>
  General assembly function.

  Many of the functions below use more than one mesh_fem: the main
  mesh_fem (mf_u) used for the main unknown, and data mesh_fem (mf_d)
  used for the data. It is always assumed that the Qdim of mf_d is
  equal to 1: if mf_d is used to describe vector or tensor data, you
  just have to "stack" (in fortran ordering) as many scalar fields as
  necessary.
</para>
  </refsection>

  <refsection>
    <title>Command list</title>

    <itemizedlist>
    <listitem>
    <para><literal>M = gf_asm('mass matrix', mesh_im mim, mesh_fem mf1[, mesh_fem mf2[, boundary_num]])</literal></para>

    <para>       Assembly of a mass matrix.
    
    Return a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>M = gf_asm('lsneuman matrix', mesh_im mim, mesh_fem mf1, mesh_fem mf2, levelset ls)</literal></para>

    <para>         Assembly of a level set Neuman  matrix.
      
      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>M = gf_asm('nlsgrad matrix', mesh_im mim, mesh_fem mf1, mesh_fem mf2, levelset ls)</literal></para>

    <para>         Assembly of a nlsgrad matrix.
      
      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>M = gf_asm('stabilization patch matrix', @tm mesh, mesh_fem mf,  mesh_im mim, real ratio, real h)</literal></para>

    <para>         Assembly of stabilization patch matrix .
      
      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>L = gf_asm('laplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)</literal></para>

    <para>         Assembly of the matrix for the Laplacian problem.
      
      <latex style="text"><![CDATA[\nabla\cdot(a(x)\nabla u)]]></latex>  with <literal>a</literal> a scalar.
      
      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>Le = gf_asm('linear elasticity', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec lambda_d, vec mu_d)</literal></para>

    <para>       Assembles of the matrix for the linear (isotropic) elasticity problem.

    <latex style="text"><![CDATA[\nabla\cdot(C(x):\nabla u)]]></latex>
    with <latex style="text"><![CDATA[C]]></latex> defined via <literal>lambda_d</literal> and <literal>mu_d</literal>.
    
    Return a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>TRHS = gf_asm('nonlinear elasticity', mesh_im mim, mesh_fem mf_u, vec U, string law, mesh_fem mf_d, mat params, {'tangent matrix'|'rhs'|'incompressible tangent matrix', mesh_fem mf_p, vec P|'incompressible rhs', mesh_fem mf_p, vec P})</literal></para>

    <para>         Assembles terms (tangent matrix and right hand side) for nonlinear elasticity.
      
      The solution <literal>U</literal> is required at the current time-step. The <literal>law</literal>
      may be choosen among:
      
      - 'SaintVenant Kirchhoff':
      Linearized law, should be avoided). This law has the two usual
      Lame coefficients as parameters, called lambda and mu.
      - 'Mooney Rivlin':
      Only for incompressibility. This law has two parameters,
      called C1 and C2.
      - 'Ciarlet Geymonat':
      This law has 3 parameters, called lambda, mu and gamma, with
      gamma chosen such that gamma is in ]-lambda/2-mu, -mu[.
      
    The parameters of the material law are described on the mesh_fem <literal>mf_d</literal>.
    The matrix <literal>params</literal> should have <literal>nbdof(mf_d)</literal> columns, each row
    correspounds to a parameter.

    The last argument selects what is to be built: either the tangent
    matrix, or the right hand side. If the incompressibility is
    considered, it should be followed by a mesh_fem <literal>mf_p</literal>, for the
    pression.

    Return a spmat object (tangent matrix), vec object (right hand
    side), tuple of spmat objects (incompressible tangent matrix), or
    tuple of vec objects (incompressible right hand side).
    
    </para>
    </listitem>

    <listitem>
    <para><literal>{K, B} = gf_asm('stokes', mesh_im mim, mesh_fem mf_u, mesh_fem mf_p, mesh_fem mf_d, vec nu)</literal></para>

    <para>       Assembly of matrices for the Stokes problem.

    <latex style="text"><![CDATA[-\nu(x)\Delta u + \nabla p = 0]]></latex>
    <latex style="text"><![CDATA[\nabla\cdot u  = 0]]></latex>
    with <latex style="text"><![CDATA[\nu]]></latex> (<literal>nu</literal>), the fluid's dynamic viscosity.

    On output, <literal>K</literal> is the usual linear elasticity stiffness matrix with
    <latex style="text"><![CDATA[\lambda = 0]]></latex> and
    <latex style="text"><![CDATA[2\mu = \nu]]></latex>. <literal>B</literal> is a matrix
    corresponding to <latex style="text"><![CDATA[\int p\nabla\cdot\phi]]></latex>.

    <literal>K</literal> and <literal>B</literal> are spmat object's.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>A = gf_asm('helmholtz', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec k)</literal></para>

    <para>       Assembly of the matrix for the Helmholtz problem.

    <latex style="text"><![CDATA[\Delta u + k^2 u]]></latex> = 0,  with <literal>k</literal> complex scalar.

    Return a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>A = gf_asm('bilaplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)</literal></para>

    <para>         Assembly of the matrix for the Bilaplacian problem.

      <latex style="text"><![CDATA[\Delta(a(x)\Delta u) = 0]]></latex>   with <literal>a</literal> scalar.

      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>A = gf_asm('bilaplacian KL', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a, vec nu)</literal></para>

    <para>         Assembly of the matrix for the Bilaplacian problem with Kirchoff-Love formulation.

      <latex style="text"><![CDATA[\Delta(a(x)\Delta u) = 0]]></latex>   with <literal>a</literal> scalar.

      Return a spmat object.
      
    </para>
    </listitem>

    <listitem>
    <para><literal>V = gf_asm('volumic source', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec fd)</literal></para>

    <para>       Assembly of a volumic source term.

    Output a vector <literal>V</literal>, assembled on the mesh_fem <literal>mf_u</literal>, using the data
    vector <literal>fd</literal> defined on the data mesh_fem <literal>mf_d</literal>. <literal>fd</literal> may be real or
    complex-valued.

    Return a vec object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>B = gf_asm('boundary source', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec G)</literal></para>

    <para>       Assembly of a boundary source term.

    <literal>G</literal> should be a [Qdim x N] matrix, where N is the number of dof
    of <literal>mf_d</literal>, and Qdim is the dimension of the unkown u (that is set
    when creating the mesh_fem).

    Return a vec object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>{HH, RR} = gf_asm('dirichlet', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat H, vec R [, threshold])</literal></para>

    <para>       Assembly of Dirichlet conditions of type <literal>h.u = r</literal>.

    Handle <literal>h.u = r</literal> where h is a square matrix (of any rank) whose
    size is equal to the dimension of the unkown u. This matrix is
    stored in <literal>H</literal>, one column per dof in <literal>mf_d</literal>, each column containing
    the values of the matrix h stored in fortran order:

    .. math::

      <literal>H(:,j) = [h11(x_j) h21(x_j) h12(x_j) h22(x_j)]</literal>

    if u is a 2D vector field.

    Of course, if the unknown is a scalar field, you just have to set
    <literal>H = ones(1, N)</literal>, where N is the number of dof of <literal>mf_d</literal>.

    This is basically the same than calling gf_asm('boundary qu term')
    for <literal>H</literal> and calling gf_asm('neumann') for <literal>R</literal>, except that this
    function tries to produce a 'better' (more diagonal) constraints
    matrix (when possible).

    See also gf_spmat_get(spmat S, 'Dirichlet_nullspace').
    </para>
    </listitem>

    <listitem>
    <para><literal>Q = gf_asm('boundary qu term',int boundary_num, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat q)</literal></para>

    <para>       Assembly of a boundary qu term.

    <literal>q</literal> should be be a [Qdim x Qdim x N] array, where N is the number
    of dof of <literal>mf_d</literal>, and Qdim is the dimension of the unkown u (that
    is set when creating the mesh_fem).

    Return a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>{...} = gf_asm('volumic' [,CVLST], expr [, mesh_ims, mesh_fems, data...])</literal></para>

    <para>         Generic assembly procedure for volumic assembly.

      The expression <literal>expr</literal> is evaluated over the mesh_fem's listed in the
      arguments (with optional data) and assigned to the output arguments.
      For details about the syntax of assembly expressions, please refer
      to the getfem user manual (or look at the file getfem_assembling.h
      in the getfem++ sources).

      For example, the L2 norm of a field can be computed with::

        gf_compute('L2 norm') or with:

        gf_asm('volumic','u=data(#1); V()+=u(i).u(j).comp(Base(#1).Base(#1))(i,j)',mim,mf,U)

      The Laplacian stiffness matrix can be evaluated with::

        gf_asm('laplacian',mim, mf, A) or equivalently with:

        gf_asm('volumic','a=data(#2);M(#1,#1)+=sym(comp(Grad(#1).Grad(#1).Base(#2))(:,i,:,i,j).a(j))', mim,mf, A);
    </para>
    </listitem>

    <listitem>
    <para><literal>{...} = gf_asm('boundary', int bnum, string expr [, mesh_im mim, mesh_fem mf, data...])</literal></para>

    <para>         Generic boundary assembly.

      See the help for gf_asm('volumic').
    </para>
    </listitem>

    <listitem>
    <para><literal>Mi = gf_asm('interpolation matrix', mesh_fem mf, mesh_fem mfi)</literal></para>

    <para>       Build the interpolation matrix from a mesh_fem onto another mesh_fem.

    Return a matrix <literal>Mi</literal>, such that <literal>V = Mi.U</literal> is equal to
    gf_compute('interpolate_on',mfi). Useful for repeated interpolations.
    Note that this is just interpolation, no elementary integrations
    are involved here, and <literal>mfi</literal> has to be lagrangian. In the more
    general case, you would have to do a L2 projection via the mass
    matrix.

    <literal>Mi</literal> is a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>Me = gf_asm('extrapolation matrix',mesh_fem mf, mesh_fem mfe)</literal></para>

    <para>       Build the extrapolation matrix from a mesh_fem onto another mesh_fem.

    Return a matrix <literal>Me</literal>, such that <literal>V = Me.U</literal> is equal to
    gf_compute('extrapolate_on',mfe). Useful for repeated
    extrapolations.

    <literal>Me</literal> is a spmat object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>B = gf_asm('contact with friction Uzawa projection', int bnum, mesh_im mim, mesh_fem mf_u, vec U, mesh_fem mf_lambda, vec vec_lambda, mesh_fem mf_obstacle, vec obstacle, scalar r [, {scalar coeff | mesh_fem mf_coeff, vec coeff} [, int option[, scalar alpha, vec W]]])</literal></para>

    <para>       Specific assembly procedure for the use of an Uzawa algorithm to solve
      contact problems. Projects the term $-(\lambda - r (u_N-g))_-$ on the
      finite element space of $\lambda$.

    Return a vec object.
    
    </para>
    </listitem>

    <listitem>
    <para><literal>B = gf_asm('level set normal source term', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_lambda, vec vec_lambda, mesh_fem mf_levelset, vec levelset)</literal></para>

    <para>       Performs an assembly of the source term represented by <literal>vec_lambda</literal>
    on <literal>mf_lambda</literal> considered to be a component in the direction of the
    gradient of a levelset function (normal to the levelset) of a vector
    field defined on <literal>mf_u</literal> on the boundary <literal>bnum</literal>.

    Return a vec object.
    
    </para>
    </listitem>

    </itemizedlist>
  </refsection>

  <refsection>
    <title>See Also</title>
    <simplelist type="inline">
      <member><link linkend="getfem_types">getfem types</link></member>
    </simplelist>
  </refsection>

  <refsection>
    <title>Authors</title>
    <para>Y. Collette</para>
  </refsection>

</refentry>
