% FUNCTION [...] = gf_asm([operation [, args]])
%
%   
%   General assembly function.
%   
%   Many of the functions below use more than one mesh_fem: the main
%   mesh_fem (mf_u) used for the main unknow, 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.
%   
%
%   * M = gf_asm('mass matrix', mesh_im mim, mesh_fem mf1[, mesh_fem mf2])
%   Assembly of a mass matrix.
%   
%   Return a spmat object.
%   
%
%   * L = gf_asm('laplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)
%   Assembly of the matrix for the Laplacian problem.
%   
%   :math:`\nabla\cdot(a(x)\nabla u)`  with `a` a scalar.
%   
%   Return a spmat object.
%   
%
%   * Le = gf_asm('linear elasticity', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec lambda_d, vec mu_d)
%   Assembles of the matrix for the linear (isotropic) elasticity problem.
%   
%   :math:`\nabla\cdot(C(x):\nabla u)`
%   with :math:`C` defined via `lambda_d` and `mu_d`.
%   
%   Return a spmat object.
%   
%
%   * 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})
%   Assembles terms (tangent matrix and right hand side) for nonlinear elasticity.
%   
%   The solution `U` is required at the current time-step. The `law`
%   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 `mf_d`.
%   The matrix `params` should have `nbdof(mf_d)` 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 `mf_p`, 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).
%   
%
%   * {K, B} = gf_asm('stokes', mesh_im mim, mesh_fem mf_u, mesh_fem mf_p, mesh_fem mf_d, vec nu)
%   Assembly of matrices for the Stokes problem.
%   
%   :math:`-\nu(x)\Delta u + \nabla p = 0`
%   :math:`\nabla\cdot u  = 0`
%   with :math:`\nu` (`nu`), the fluid's dynamic viscosity.
%   
%   On output, `K` is the usual linear elasticity stiffness matrix with
%   :math:`\lambda = 0` and
%   :math:`2\mu = \nu`. `B` is a matrix
%   corresponding to :math:`\int p\nabla\cdot\phi`.
%   
%   `K` and `B` are spmat object's.
%   
%
%   * A = gf_asm('helmholtz', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec k)
%   Assembly of the matrix for the Helmholtz problem.
%   
%   :math:`\Delta u + k^2 u` = 0,  with `k` complex scalar.
%   
%   Return a spmat object.
%   
%
%   * A = gf_asm('bilaplacian', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec a)
%   Assembly of the matrix for the Bilaplacian problem.
%   
%   :math:`\Delta(a(x)\Delta u) = 0`   with `a` scalar.
%   
%   Return a spmat object.
%   
%
%   * V = gf_asm('volumic source', mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec fd)
%   Assembly of a volumic source term.
%   
%   Output a vector `V`, assembled on the mesh_fem `mf_u`, using the data
%   vector `fd` defined on the data mesh_fem `mf_d`. `fd` may be real or
%   complex-valued.
%   
%   Return a vec object.
%   
%
%   * B = gf_asm('boundary source', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, vec G)
%   Assembly of a boundary source term.
%   
%   `G` should be a [Qdim x N] matrix, where N is the number of dof
%   of `mf_d`, and Qdim is the dimension of the unkown u (that is set
%   when creating the mesh_fem).
%   
%   Return a vec object.
%   
%
%   * {HH, RR} = gf_asm('dirichlet', int bnum, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat H, vec R [, threshold])
%   Assembly of Dirichlet conditions of type `h.u = r`.
%   
%   Handle `h.u = r` 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 `H`, one column per dof in `mf_d`, each column containing
%   the values of the matrix h stored in fortran order:
%   
%   .. math::
%   
%   `H(:,j) = [h11(x_j) h21(x_j) h12(x_j) h22(x_j)]`
%   
%   if u is a 2D vector field.
%   
%   Of course, if the unknown is a scalar field, you just have to set
%   `H = ones(1, N)`, where N is the number of dof of `mf_d`.
%   
%   This is basically the same than calling gf_asm('boundary qu term')
%   for `H` and calling gf_asm('neumann') for `R`, except that this
%   function tries to produce a 'better' (more diagonal) constraints
%   matrix (when possible).
%   
%   See also gf_spmat_get(spmat S, 'Dirichlet_nullspace').
%
%   * Q = gf_asm('boundary qu term',int boundary_num, mesh_im mim, mesh_fem mf_u, mesh_fem mf_d, mat q)
%   Assembly of a boundary qu term.
%   
%   `q` should be be a [Qdim x Qdim x N] array, where N is the number
%   of dof of `mf_d`, and Qdim is the dimension of the unkown u (that
%   is set when creating the mesh_fem).
%   
%   Return a spmat object.
%   
%
%   * {...} = gf_asm('volumic' [,CVLST], expr [, mesh_ims, mesh_fems, data...])
%   Generic assembly procedure for volumic assembly.
%   
%   The expression `expr` 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);
%
%   * {...} = gf_asm('boundary', int bnum, string expr [, mesh_im mim, mesh_fem mf, data...])
%   Generic boundary assembly.
%   
%   See the help for gf_asm('volumic').
%
%   * Mi = gf_asm('interpolation matrix', mesh_fem mf, mesh_fem mfi)
%   Build the interpolation matrix from a mesh_fem onto another mesh_fem.
%   
%   Return a matrix `Mi`, such that `V = Mi.U` 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 `mfi` has to be lagrangian. In the more
%   general case, you would have to do a L2 projection via the mass
%   matrix.
%   
%   `Mi` is a spmat object.
%   
%
%   * Me = gf_asm('extrapolation matrix',mesh_fem mf, mesh_fem mfe)
%   Build the extrapolation matrix from a mesh_fem onto another mesh_fem.
%   
%   Return a matrix `Me`, such that `V = Me.U` is equal to
%   gf_compute('extrapolate_on',mfe). Useful for repeated
%   extrapolations.
%   
%   `Me` is a spmat object.
%   
%
%   * {Q, G, H, R, F} = gf_asm('pdetool boundary conditions', mf_u, mf_d, b, e[, f_expr])
%   Assembly of pdetool boundary conditions.
%   
%   `B` is the boundary matrix exported by pdetool, and `E` is the
%   edges array. `f_expr` is an optionnal expression (or vector) for
%   the volumic term. On return `Q, G, H, R, F` contain the assembled
%   boundary conditions (`Q` and `H` are matrices), similar to the
%   ones returned by the function ASSEMB from PDETOOL.
%   
%
%
function [varargout]=gf_asm(varargin)

  if (nargin>=1 & strcmpi(varargin{1},'pdetool boundary conditions')),
    [varargout{1:nargout}]=gf_asm_pdetoolbc(varargin{[1 3:nargin]}); return;
  end;
  
  if (nargout),
    [varargout{1:nargout}]=gf_matlab('asm', varargin{:});
  else
    gf_matlab('asm', varargin{:});
    if (exist('ans', 'var') == 1), varargout{1}=ans; end;
  end;
% autogenerated mfile;
