function [out,out1,out2]=m_visc(varargin)

%M_VISC viscoelastic material function
%
%       Syntax : mat= m_elastic('default') 
%                mat= m_elastic('database name') 
%                pl = m_elastic('dbval MatId name');
%                pl = m_elastic('dbval -unit MM MatId name');
%
%       Material subtypes supported by m_visc are
%
%	Subtype 1 : xxx
%	    [MatID type rho eta dt 0 0 0 0]
%         with
%           type  fe_mat('m_hyper','SI',1)
%       eta: viscosity used for viscoelastic energy 
%       dt: time step
%	    rho xxx eta xxx dt xxx 
%
%       See also help fe_mat, p_shell, p_beam
%                doc m_elastic, pl, fem


%	Etienne Balmes, Jean-Michel Leclere, Corine Florens, Mathieu Alba
%       Copyright (c) 2001-2005 by INRIA and SDTools, All Rights Reserved.
%       Use under OpenFEM trademark.html license and LGPL.txt library license

if nargin==1 & comstr(varargin{1},'cvs')
 out='$Revision: 1.3 $  $Date: 2006/05/10 08:33:36 $'; return;
end
if nargin<1 help m_visc;return; end
if ischar(varargin{1}) [CAM,Cam]=comstr(varargin{1},1); pl=[]; carg=2;
else pl=varargin{1};[CAM,Cam]=comstr(varargin{2},1); carg=3;
end

sdtdef('diag',['m_visc(''' Cam ''')'])

% -------------------------------------------------------------------------
if comstr(Cam,'propertyunittype')

 i1=varargin{carg};
 out1={};
 switch i1
 %case 1 % isotropic   [MatID typ E nu rho G eta alpha T0]
 %               ind = [0     0   1 0  3   1 0   8     7]; % xxx 
 case 1
 st=...
 {'MatId'                  0;
  'Type'                   0;
  'C1'     0;
  'C2'       0;
  'K'                0;
 };
 otherwise; st={'MatId' 0; 'Type', 0};
 end
 if ~isempty(strfind(Cam,'cell')); out=st; else; out=[st{:,2}]; end

% -------------------------------------------------------------------------
elseif comstr(Cam,'info')

 r1=m_visc('database');
 disp(char({r1.name}))

% -------------------------------------------------------------------------
elseif comstr(Cam,'default')

  out=m_visc('database'); out=out(1);

% -------------------------------------------------------------------------
elseif comstr(Cam,'dbval') 

 i1=strfind(comstr(Cam,-27),'-unit'); out1={}; % See if unit specified
 if ~isempty(i1)
  [Unit,i2,i3,i4]=sscanf(CAM(i1+5:end),'%s',1);
  i4=i1+[0:4+i4];CAM(i4)=''; [CAM,Cam]=comstr(CAM,1);
 else Unit=''; end

 while 1==1

  if ischar(CAM); [i1,CAM,Cam]=comstr(CAM,'dbval','%i');else; i1=[];end
  if isempty(CAM)&carg<=nargin st=varargin{carg};carg=carg+1; 
  else st=CAM;end
  if isempty(st)
  elseif ischar(st); mat=m_visc('database',st); 
  elseif isnumeric(st)
    [typ,st1,i4]=fe_mat('typem',st(2));
    mat=struct('pl',st,'name',sprintf('%i',st(1)),'type',typ,'unit',st1);
  end
  if ~isempty(Unit)
   mat.pl=fe_mat(sprintf('convert %s %s',mat.unit,Unit),mat.pl);
  end
  if length(i1)==1 mat.pl(1)=i1;end
  r1=mat.pl; 
  if ~isempty(pl) i2=find(pl(:,1)==r1(1)); else i2=[];end
  if isempty(i2) i2=size(pl,1)+1;end
  pl(i2,1:length(r1))=r1; 
  out1(end+1,1:3)={'mat',sprintf('%i_%s',mat.pl(1),mat.name),mat};
  if carg>nargin break;end
  CAM=varargin{carg};carg=carg+1;
 end
 out=pl;

% -------------------------------------------------------------------------
elseif comstr(Cam,'database'); [st,Cam]=comstr(CAM,9);

  if isempty(st)&carg<=nargin st=varargin{carg}; carg=carg+1;end
  [MatId,i2,i3,i4]=sscanf(st,'%i',1); if i2~=1 MatId=1;end
  st=comstr(st,i4);

  out.pl=[MatId fe_mat('type','m_visc','SI',1) .3 1e-3];
  out.name='Ref';
  out.type='m_visc';
  out.unit='SI';

  out(2).pl=[MatId fe_mat('type','m_visc','SI',1) 0.1 1e-2];
  out(2).name='Rivlin';
  out(2).type='m_visc';
  out(2).unit='SI';
  
  out(3).pl=[MatId fe_mat('type','m_visc','SI',1) 6.8e2 1e-3];
  out(3).name='phi';
  out(3).type='m_visc';
  out(3).unit='SI';

  out(4).pl=[MatId fe_mat('type','m_visc','SI',1) 1.2 1e-2];
  out(4).name='coeur';
  out(4).type='m_visc';
  out(4).unit='SI';

  i1=strmatch(comstr(st,-27),comstr({out.name},-27),'exact');
  out1='Visco_Elastic';

  if isempty(i1) & isempty(st); return; end

  % match a name 
  if ~isempty(i1); out=out(i1(1));

  else % assume values given
    error('Not a supported material');
  end


% -------------------------------------------------------------------------
% Implementation of elastic constitutive law building 3D
elseif comstr(Cam,'buildconstit')

  ID=varargin{carg};carg=carg+1;
  pl=varargin{carg};carg=carg+1; mat=pl(find(pl(:,1)==ID(1)),:);
  il=varargin{carg};carg=carg+1; pro=[];try;pro=il(find(il(:,1)==ID(2)),:);end
  if isempty(pl) error('MatId is not matched');end

   [st,unit,typ]=fe_mat('type',mat(2));
   
   if strcmp(st,'m_visc')&typ==1 % Nominal hyperelastic behaviour

    % for now just propagate constants to a column of constit
    out=[mat(3:end)];out=out(:); 
    
   elseif strcmp(st,'m_visc')&typ==2 %not used
       out=[mat(3:end)];out=out(:); 
   else
    error(sprintf('Volume law not implemented for this material %s(%i)',st,typ));
   end 
   % Integration rule saved in integ
   if length(ID)<4; ID(4)=0;end; ID(3)=3*ID(4); % must be number of DOFs 
   if size(pro,1)&size(pro,2)>3;  ID(5)=pro(1,4); end  
   ID(7)=5; % used for later NL constit type selection
   % this should match StrategyType in of_mk.c matrix assembly
   out1=int32(ID(:));

% -------------------------------------------------------------------------
elseif comstr(Cam,'propertyunittype')

 if carg<2 error('bad number of input arguments'); end
 out=PropertyUnitType_hyper(varargin{2});

% -------------------------------------------------------------------------
elseif comstr(Cam,'fielddofs')
 out=[1 2 3];
% -------------------------------------------------------------------------
elseif comstr(Cam,'subtypestring')

 i1=varargin{carg}; carg=carg+1;
 switch i1
 case 1;  out='xxx';
 otherwise out='m_visc';
 end

end
% -------------------------------------------------------------------------

