% FUNCTION [x] = gf_mesh_fem_get(meshfem MF, operation [, args])
% 
%   General function for inquiry about mesh_fem objects.
% 
%   * n = gf_mesh_fem_get(MF,'nbdof')
%   Return the number of degrees of freedom (dof) of the MeshFem.
% 
%   * n = gf_mesh_fem_get(MF,'nb_basic_dof')
%   Return the number of basic degrees of freedom (dof) of the MeshFem.
% 
%   * DOF = gf_mesh_fem_get(MF,'basic_dof_from_cv,'mat CVids)
%   Return the dof of the convexes listed in `CVids`.  WARNING: the Degree of
%   Freedom might be returned in ANY order, do not use this function in your
%   assembly routines. Use 'basic dof from cvid' instead, if you want to be able
%   to map a convex number with its associated degrees of freedom.  One can also
%   get the list of basic dof on a set on convex faces, by indicating on the
%   second row of `CVids` the faces numbers (with respect to the convex number on
%   the first row).
% 
%   * {DOFs, IDx} = gf_mesh_fem_get(MF,'basic_dof_from_cvid'[, mat CVids])
%   Return the degrees of freedom attached to each convex of the mesh.  If `CVids`
%   is omitted, all the convexes will be considered (equivalent to `CVids = 1 ...
%   gf_mesh_get(M,'max_cvid')`).  `IDx` is a row vector, `length(IDx) =
%   length(CVids)+1`. `DOFs` is a row vector containing the concatenated list of
%   dof of each convex in `CVids`. Each entry of `IDx` is the position of the
%   corresponding convex point list in `DOFs`. Hence, for example, the list of
%   points of the second convex is DOFs(IDx(2):IDx(3)-1) .  If `CVids` contains
%   convex #id which do not exist in the mesh, their point list will be empty.
% 
%   * gf_mesh_fem_get(MF,'non_conformal_basic_dof'[, mat CVids])
%   Return partially linked degrees of freedom.  Return the basic dof located on
%   the border of a convex and which belong to only one convex, except the ones
%   which are located on the border of the mesh.  For example, if the convex 'a'
%   and 'b' share a common face, 'a' has a P1 FEM, and 'b' has a P2 FEM, then the
%   basic dof on the middle of the face will be returned by this function (this
%   can be useful when searching the interfaces between classical FEM and
%   hierarchical FEM).
% 
%   * gf_mesh_fem_get(MF,'qdim')
%   Return the dimension Q of the field interpolated by the MeshFem.  By default,
%   Q=1 (scalar field). This has an impact on the dof numbering.
% 
%   * {FEMs, CV2F} = gf_mesh_fem_get(MF,'fem'[, mat CVids])
%   Return a list of FEM used by the MeshFem.  `FEMs` is an array of all Fem
%   objects found in the convexes given in `CVids`. If `CV2F` was supplied as an
%   output argument, it contains, for each convex listed in `CVids`, the index of
%   its correspounding FEM in `FEMs`.  Convexes which are not part of the mesh, or
%   convexes which do not have any FEM have their correspounding entry in `CV2F`
%   set to -1.
% 
%   Example:
%      cvid=gf_mesh_get(mf,'cvid');
%      [f,c2f]=gf_mesh_fem_get(mf, 'fem');
%      for i=1:size(f), sf{i}=gf_fem_get('char',f(i)); end;
%      for i=1:size(c2f),
%        disp(sprintf('the fem of convex %d is %s',...
%             cvid(i),sf{i}));
%      end;
%   * bB = gf_mesh_fem_get(MF,'is_lagrangian'[, mat CVids])
%   Test if the MeshFem is Lagrangian.  Lagrangian means that each base function
%   Phi[i] is such that Phi[i](P[j]) = delta(i,j), where P[j] is the dof location
%   of the jth base function, and delta(i,j) = 1 if i==j, else 0.
%   
%     If `CVids` is omitted, it returns 1 if all convexes in the mesh are
%   Lagrangian. If `CVids` is used, it returns the convex indices (with respect to
%   `CVids`) which are Lagrangian.
% 
%   * bB = gf_mesh_fem_get(MF,'is_equivalent'[, mat CVids])
%   Test if the MeshFem is equivalent.  See gf_mesh_fem_get(MF,'is_lagrangian')
% 
%   * bB = gf_mesh_fem_get(MF,'is_polynomial'[, mat CVids])
%   Test if all base functions are polynomials.  See
%   gf_mesh_fem_get(MF,'is_lagrangian')
% 
%   * bB = gf_mesh_fem_get(MF,'is_reduced')
%   Return 1 if the optional reduction matrix is applied to the dofs.
% 
%   * bB = gf_mesh_fem_get(MF,'reduction_matrix')
%   Return the optional reduction matrix.
% 
%   * bB = gf_mesh_fem_get(MF,'extension_matrix')
%   Return the optional extension matrix.
% 
%   * DOFs = gf_mesh_fem_get(MF,'basic_dof_on_region,'mat Rs)
%   Return the list of basic dof (before the optional reduction) lying on one of
%   the mesh regions listed in `Rs`.  More precisely, this function returns the
%   basic dof whose support is non-null on one of regions whose #ids are listed in
%   `Rs` (note that for boundary regions, some dof nodes may not lie exactly on
%   the boundary, for example the dof of Pk(n,0) lies on the center of the convex,
%   but the base function in not null on the convex border).
% 
%   * DOFs = gf_mesh_fem_get(MF,'dof_on_region,'mat Rs)
%   Return the list of dof (after the optional reduction) lying on one of the mesh
%   regions listed in `Rs`.  More precisely, this function returns the basic dof
%   whose support is non-null on one of regions whose #ids are listed in `Rs`
%   (note that for boundary regions, some dof nodes may not lie exactly on the
%   boundary, for example the dof of Pk(n,0) lies on the center of the convex, but
%   the base function in not null on the convex border).   For a reduced mesh_fem
%   a dof is lying on a region if its potential corresponding shape function is
%   nonzero on this region. The extension matrix is used to make the
%   correspondance between basic and reduced dofs.
% 
%   * DOFpts = gf_mesh_fem_get(MF,'basic_dof_nodes'[, mat DOFids])
%   Get location of basic degrees of freedom.  Return the list of interpolation
%   points for the specified dof #IDs in `DOFids` (if `DOFids` is omitted, all
%   basic dof are considered).
% 
function [varargout]=gf_mesh_fem_get(varargin)
  if (nargin>=2 & strcmpi(varargin{2},'eval')),
    [varargout{1:nargout}]=gf_mesh_fem_get_eval(varargin{[1 3:nargin]}); return;
  end;
  if (nargout),
    [varargout{1:nargout}]=gf_matlab('mesh_fem_get',varargin{:});
  else
    gf_matlab('mesh_fem_get',varargin{:});
    if (exist('ans','var') == 1), varargout{1}=ans; end;
  end;
