% FUNCTION M = gf_model_set(cmd, [, args])
%   Modify a model object.
% 
%   * gf_model_set(mds,'variable', string name, vec V[, int niter])
%   Set the value of a variable or data.
% 
%   * gf_model_set(mds,'clear')
%   Clear the model.
% 
%   * gf_model_set(mds,'add_fem_variable', string name, MeshFem mf[, int niter])
%   Add a variable to the model linked to a MeshFem. `name` is the variable name
%   and `niter` is the optional number of copy of the variable for time
%   integration schemes.
% 
%   * gf_model_set(mds,'add_variable', string name, int size[, int niter])
%   Add a variable to the model of constant size. `name` is the variable name and
%   `niter` is the optional number of copy of the variable for time integration
%   schemes.
% 
%   * gf_model_set(mds,'add_multiplier', string name, MeshFem mf, string
%   primalname[, int niter])
%   Add a particular variable linked to a fem being a multiplier with respect to a
%   primal variable. The dof will be filtered with the gmm::range_basis function
%   applied on the terms of the model which link the multiplier and the primal
%   variable. This in order to retain only linearly independant constraints on the
%   primal variable. Optimized for boundary multipliers. niter is the number of
%   version of the data stored, for time integration schemes.
% 
%   * gf_model_set(mds,'add_fem_data', string name, MeshFem mf[, int qdim, int
%   niter])
%   Add a data to the model linked to a MeshFem. `name` is the data name, `qdim`
%   is the optional dimension of the data over the MeshFem and `niter` is the
%   optional number of copy of the data for time integration schemes.
% 
%   * gf_model_set(mds,'add_initialized_fem_data', string name, MeshFem mf, vec V)
%   Add a data to the model linked to a MeshFem. `name` is the data name. The data
%   is initiakized with `V`. The data can be a scalar or vector field.
% 
%   * gf_model_set(mds,'add_data', string name, int size[, int niter])
%   Add a data to the model of constant size. `name` is the data name and `niter`
%   is the optional number of copy of the data for time integration schemes.
% 
%   * gf_model_set(mds,'add_initialized_data', string name, V)
%   Add a fixed size data to the model linked to a MeshFem. `name` is the data
%   name, `V` is the value of the data.
% 
%   * gf_model_set(mds,'to_variables', vec V)
%   Set the value of the variables of the model with the vector `V`. Typically,
%   the vector `V` results of the solve of the tangent linear system (usefull to
%   solve your problem with you own solver).
% 
%   * ind = gf_model_set(mds,'add Laplacian brick', MeshIm mim, string varname[, int
%   region])
%   add a Laplacian term to the model relatively to the variable `varname`. If
%   this is a vector valued variable, the Laplacian term is added componentwise.
%   `region` is an optional mesh region on which the term is added. If it is not
%   specified, it is added on the whole mesh.
% 
%   * ind = gf_model_set(mds,'add_generic_elliptic_brick', MeshIm mim, string
%   varname, string dataname[, int region])
%   add a generic elliptic term to the model relatively to the variable `varname`.
%   The shape of the elliptic term depends both on the variable and the data. This
%   corresponds to a term $-\text{div}(a\nabla u)$ where $a$ is the data and $u$
%   the variable. The data can be a scalar, a matrix or an order four tensor. The
%   variable can be vector valued or not. If the data is a scalar or a matrix and
%   the variable is vector valued then the term is added componentwise. An order
%   four tensor data is allowed for vector valued variable only. The data can be
%   constant or describbed on a fem. Of course, when the data is a tensor describe
%   on a finite element method (a tensor field) the data can be a huge vector. The
%   components of the matrix/tensor have to be stored with the fortran order
%   (columnwise) in the data vector (compatibility with blas). The symmetry of the
%   given matrix/tensor is not verified (but assumed). If this is a vector valued
%   variable, the Laplacian term is added componentwise. `region` is an optional
%   mesh region on which the term is  added. If it is not specified, it is added
%   on the whole mesh.
% 
%   * ind = gf_model_set(mds,'add_source_term_brick', MeshIm mim, string varname,
%   string dataname[, int region])
%   add a source term to the model relatively to the variable `varname`. The
%   source term is represented by the data `dataname` which could be constant or
%   described on a fem.  `region` is an optional mesh region on which the term is
%   added. An additional optional data `directdataname` can be provided. The
%   corresponding data vector will be directly added to the right hand side
%   without assembly.
% 
%   * ind = gf_model_set(mds,'add_normal_source_term_brick', MeshIm mim, string
%   varname, string dataname[, int region])
%   add a source term on the variable `varname` on a boundary `region`. The source
%   term is represented by the data `dataname` which could be constant or
%   described on a fem. A scalar product with the outward normal unit vector to
%   the boundary is performed. The main aim of this brick is to represent a
%   Neumann condition with a vector data without performing the scalar product
%   with the normal as a pre-processing.
% 
%   * ind = gf_model_set(mds,'add Dirichlet condition with multipliers', MeshIm mim,
%   string varname, mult_description, int region[, string dataname])
%   Add a Dirichlet condition on the variable `varname` and the mesh region
%   `region`. This region should be a boundary. The Dirichlet condition is
%   prescribed with a multiplier variable described by `mult_description`. If
%   `mult_description` is a string this is assumed to be the variable name
%   correpsonding to the multiplier (which should be first declared as a
%   multiplier  variable on the mesh region in the model). If it is a finite
%   element method (mesh_fem object) then a multiplier variable will be added to
%   the model and build on this finite element method (it will be restricted to
%   the mesh region `region` and eventually some conflicting dofs with some other
%   multiplier variables will be suppressed). If it is an integer, then a
%   multiplier variable will be added to the model and build on a classical finite
%   element of degree that integer. `dataname` is the optional right hand side of
%   the Dirichlet condition. It could be constant or described on a fem; scalar or
%   vector valued, depending on the variable on which the Dirichlet condition is
%   prescribed. Return the brick index in the model.
% 
%   * ind = gf_model_set(mds,'add Dirichlet condition with penalization', MeshIm
%   mim, string varname, scalar coeff, int region[, string dataname])
%   Add a Dirichlet condition on the variable `varname` and the mesh region
%   `region`. This region should be a boundary. The Dirichlet condition is
%   prescribed with penalization. The penalization coefficient is intially `coeff`
%   and will be added to the data of the model. `dataname` is the optional right
%   hand side of  the Dirichlet condition. It could be constant or described on a
%   fem; scalar or vector valued, depending on the variable on which the Dirichlet
%   condition is prescribed. Return the brick index in the model.
% 
%   * gf_model_set(mds,'change_penalization_coeff', int ind_brick, scalar coeff)
%   Change the penalization coefficient of a Dirichlet condition with penalization
%   brick. If the brick is not of this kind, this function has an undefined
%   behavior.
% 
%   * ind = gf_model_set(mds,'add Helmholtz brick', MeshIm mim, string varname,
%   string dataname[, int region])
%   add a Helmholtz term to the model relatively to the variable `varname`.
%   `dataname` should contain the wave number. `region` is an optional mesh region
%   on which the term is added. If it is not specified, it is added on the whole
%   mesh.
% 
%   * ind = gf_model_set(mds,'add Fourier Robin brick', MeshIm mim, string varname,
%   string dataname, int region)
%   add a Fourier-Robin term to the model relatively to the variable `varname`.
%   this corresponds to a weak term of the form $\int (qu).v$. `dataname` should
%   contain the parameter $q$ of the Fourier-Robin condition. `region` is the mesh
%   region on which the term is added.
% 
%   * ind = gf_model_set(mds,'add_constraint_with_multipliers', string varname,
%   string multname, mat B, vec L)
%   Add an additional explicit constraint on the variable `varname` thank to a
%   multiplier `multname` peviously added to the model (should be a fixed size
%   variable). The constraint is $BU=L$ with `B` being a rectangular sparse
%   matrix. It is possible to change the constraint at any time whith the methods
%   gf_model_set(mds,'set_private_matrix') and gf_model_set(mds,'set_private_rhs')
% 
%   * ind = gf_model_set(mds,'add_constraint_with_penalization', string varname,
%   scalar coeff, mat B, vec L)
%   Add an additional explicit penalized constraint on the variable `varname`. The
%   constraint is $BU=L$ with `B` being a rectangular sparse matrix. Be aware that
%   `B` should not contain a palin row, otherwise the whole tangent matrix will be
%   plain. It is possible to change the constraint at any time whith the methods
%   gf_model_set(mds,'set_private_matrix') and
%   gf_model_set(mds,'set_private_rhs'). The method
%   gf_model_set(mds,'change_penalization_coeff') can be used.
% 
%   * ind = gf_model_set(mds,'add_explicit_matrix', string varname1, string
%   varname2, mat B[, int issymmetric[, int iscoercive]])
%   Add a brick reprenting an explicit matrix to be added to the tangent linear
%   system relatively to the variables 'varname1' and 'varname2'. The given matrix
%   should have has many rows as the dimension of 'varname1' and as many columns
%   as the dimension of 'varname2'. If the two variables are different and if
%   `issymmetric' is set to 1 then the transpose of the matrix is also added to
%   the tangent system (default is 0). set `iscoercive` to 1 if the term does not
%   affect the coercivity of the tangent system (default is 0). The matrix can be
%   changed by the command gf_model_set(mds,'set_private_matrix').
% 
%   * ind = gf_model_set(mds,'add_explicit_rhs', string varname, vec L)
%   Add a brick reprenting an explicit right hand side to be added to the right
%   hand side of the tangent linear system relatively to the variable 'varname'.
%   The given rhs should have the same size than the dimension of 'varname'. The
%   rhs can be changed by the command gf_model_set(mds,'set_private_rhs').
% 
%   * gf_model_set(mds,'set_private_matrix', int indbrick, mat B)
%   For some specific bricks having an internal sparse matrix (explicit bricks:
%   'constraint brick' and 'explicit matrix brick'), set this matrix.
% 
%   * gf_model_set(mds,'set_private_rhs', int indbrick, vec B)
%   For some specific bricks having an internal right hand side vector (explicit
%   bricks: 'constraint brick' and 'explicit rhs brick'), set this rhs.
% 
%   * gf_model_set(mds,'disable_bricks', ivec bricks_indices)
%   Disable a brick (the brick will no longer participate to the building of the
%   tangent linear system).
% 
%   * gf_model_set(mds,'unable_bricks', ivec bricks_indices)
%   Unable a disabled brick.
% 
%   * ind = gf_model_set(mds,'add_isotropic_linearized_elasticity_brick', MeshIm
%   mim, string varname, string dataname_lambda, string dataname_mu[, int region])
%   add an isotropic linearized elasticity term to the model relatively to the
%   variable `varname`. `dataname_lambda` and `dataname_mu` should contain the
%   Lam\'e coefficients. `region` is an optional mesh region on which the term is
%   added. If it is not specified, it is added on the whole mesh.
% 
%   * ind = gf_model_set(mds,'add_linear_incompressibility_brick', MeshIm mim,
%   string varname, string multname_pressure[, int region[, string
%   dataname_coeff]])
%   add an linear incompressibility condition on `variable`. `multname_pressure`
%   is a variable which represent the pressure. Be aware that an inf-sup condition
%   between the finite element method describing the rpressure and the primal
%   variable has to be satisfied. `region` is an optional mesh region on which the
%   term is added. If it is not specified, it is added on the whole mesh.
%   `dataname_coeff` is an optional penalization coefficient for nearly
%   incompressible elasticity for instance. In this case, it is the inverse of the
%   Lam\'e coefficient $\lambda$.
% 
%   * ind = gf_model_set(mds,'add_mass_brick', MeshIm mim, string varname[, string
%   dataname_rho[, int region]])
%   add mass term to the model relatively to the variable `varname`. If specified,
%   the data `dataname_rho` should contain the density (1 if omitted). `region` is
%   an optional mesh region on which the term is added. If it is not specified, it
%   is added on the whole mesh.
% 
%   * ind = gf_model_set(mds,'add_basic_d_on_dt_brick', MeshIm mim, string varnameU,
%   string dataname_dt[, string dataname_rho[, int region]])
%   Add the standard discretization of a first order time derivative on
%   `varnameU`. The parameter $rho$ is the density which could be omitted (the
%   defaul value is 1). This brick should be used in addition to a time dispatcher
%   for the other terms.
% 
%   * ind = gf_model_set(mds,'add basic d2 on dt2 brick', MeshIm mim, string
%   varnameU,  string datanameV, string dataname_dt, string dataname_alpha,[,
%   string dataname_rho[, int region]])
%   Add the standard discretization of a second order time derivative on
%   `varnameU`. `datanameV` is a data represented on the same finite element
%   method as U which represents the time derivative of U. The parameter $rho$ is
%   the density which could be omitted (the defaul value is 1). This brick should
%   be used in addition to a time dispatcher for the other terms. The time
%   derivative $v$ of the variable $u$ is preferably computed as a post-traitement
%   which depends on each scheme. The parameter `dataname_alpha` depends on the
%   time integration scheme.
% 
%   * gf_model_set(mds,'add_theta_method_dispatcher', ivec bricks_indices, string
%   theta)
%   Add a theta-method time dispatcher to a list of bricks. For instance, a matrix
%   term $K$ will be replaced by $\theta K U^{n+1} + (1-\theta) K U^{n}$.
% 
%   * gf_model_set(mds,'velocity_update_for_order_two_theta_method', string
%   varnameU,  string datanameV, string dataname_dt, string dataname_theta)
%   Function which udpate the velocity $v^{n+1}$ after the computation of the
%   displacement $u^{n+1}$ and before the next iteration. Specific for theta-
%   method and when the velocity is included in the data of the model.
% 
%   * gf_model_set(mds,'add_midpoint_dispatcher', ivec bricks_indices)
%   Add a midpoint time dispatcher to a list of bricks. For instance, a nonlinear
%   term $K(U)$ will be replaced by $K((U^{n+1} +  U^{n})/2)$.
% 
%   * gf_model_set(mds,'velocity update for Newmark scheme', int id2dt2_brick,
%   string varnameU,  string datanameV, string dataname_dt, string
%   dataname_twobeta, string dataname_alpha)
%   Function which udpate the velocity $v^{n+1}$ after the computation of the
%   displacement $u^{n+1}$ and before the next iteration. Specific for Newmark
%   scheme and when the velocity is included in the data of the model. This
%   version inverts the mass matrix by a conjugate gradient.
% 
%   * ind = gf_model_set(mds,'first_iter')
%   To be executed before the first iteration of a time integration scheme.
% 
%   * ind = gf_model_set(mds,'next_iter')
%   To be executed at the end of each iteration of a time integration scheme.
% 
function [varargout]=gf_model_set(varargin)
  if (nargout),
    [varargout{1:nargout}]=gf_matlab('model_set',varargin{:});
  else
    gf_matlab('model_set',varargin{:});
    if (exist('ans','var') == 1), varargout{1}=ans; end;
  end;
