function [cmp, t, rc] = mfs_transrespx(cmp, tdef, args)

# usage: [cmp, t, rc] = mfs_transrespx(cmp, tdef, args)
#
# Input  cmp       Structure with component data
#        tdef(2)   Array with definition of time:
#                   (1) time step
#                   (2) simulation time
#        args{:}   Parameters
#
# Output cmp       Structure with component data
#                  (transient response added)
#        t(:)      Array with time
#        rc        Return code: 0 = no errors
#                               1 = errors
#
# Parameters
#
#   Name       Values    Default   Meaning
#  -----------------------------------------------------------------------
#   method     enhanced  enhanced  Enhanced modal reduction (default)
#              modal               Modal reduction
#              direct              Direct frequency response
#   load       load(:)   none      Structure array defining loads
#   rcase      integer     1       Result case number
#   statresp     lc      none      Number of static load case defining
#                                  initial conditions
#   transresp  [rc, tp]  none      Number of transient result case and
#                                  time step number defining initial
#                                  conditions 
#   param      [a, b]  [0.25, 0.5] Parameters of Newmark algorithm
#
# Fields of structure load
#
#   lc          Load case defining load pattern
#   func        Function defining time function
#   params(:)   Parameters to be supplied to func
#
# The function computes the transient response of a solid structure.
#
# ------------------------------------------------------------------------

# Copyright (c) 2021 by Johannes Wandinger

# Check arguments

  if (nargin != 3 || nargout != 3)
     print_usage();
  end

# Initialize output

  rc = 0;

# Default values of parameters

  meth = 3; rcase = 1; exci  = 0;
  param = [0.25, 0.5, 0.1];
  load  = []; ic = [];

# Define points in time

  t = 0 : tdef(1) : tdef(2);

# Process parameters

  for k = 1 : 2 : length(args)
      switch args{k}
      case "method"
         switch args{k + 1}
         case "enhanced"
            meth = 3;
         case "modal"
            meth = 2;
         case "direct"
            meth = 1;
         otherwise
            printf("*E* mfs_transresp: unknown method %s\n", args{k + 1});
            rc = 1;
         end
      case "load"
         exci = 1;
         load = args{k + 1};
         if (! isstruct(load))
            printf("*E* mfs_transresp: parameter ""load"" must be a structure\n");
            rc = 1;
         end
         for l = 1 : length(load)
             if (! isfield(load(l), "params"))
                load(l).params = [];
             end
         end
      case "rcase"
         rcase = args{k + 1};
         if (rcase < 1)
            printf("*E* mfs_transresp: result case must be positive\n");
            rc = 1;
         end
      case "statresp"
         exci = 1;
         lc   = args{k + 1};
         if (! isfield(cmp, "statresp"))
            printf("*E* mfs_transresp: component does not contain ");
            printf("static load cases\n");
            rc = 1;
         elseif (lc < 1 || lc > cmp.statresp.nofldc)
            printf("*E* mfs_transresp: static load case %d ", lc);
            printf("does not exist\n");
            rc = 1;
         else
            ic = cmp.statresp.disp(:, lc);
         end
      case "transresp"
         exci = 1;
         rct  = args{k + 1};
         if (length(rct) != 2)
            printf("*E* mfs_transresp: parameter transresp doe not ");
            printf("define result case and time step\n");
            rc = 1;
         else
            rcase = rct(1); tno = rct(2);
            if (! isfield(cmp, "transresp"))
               printf("*E* mfs_transresp: component does not contain ");
               printf("transient response results\n");
               rc = 1;
            elseif (rcase < 1 || rcase > cmp.transresp.nta)
               printf("*E* mfs_transresp: transient result case %d ", rcase);
               printf("does not exist\n");
               rc = 1;
            elseif (tno < 1 || tno > cmp.transresp.resp{rcase}.ntime)
               printf("*E* mfs_transresp: time step %d of result case %d ",
                      tno, rcase);
               printf("does not exist\n");
               rc = 1;
            else
               respi = cmp.transresp.resp{rcase};
               methi = respi.method;
               if (methi == 1)
                  ic(:, 1) = respi.u(:, tno);
                  ic(:, 2) = respi.v(:, tno);
               else
                  X = cmp.modes.disp;
                  if (methi == 3)
                     X = [X, respi.Xs];
                  end
                  ic(:, 1) = X * respi.q(:, tno);
                  ic(:, 2) = X * respi.qd(:, tno);
                  if (isfield(respi, "base"))
                     ic(:, 1) += respi.base * respi.f(tno);
                     ic(:, 2) += respi.base * respi.fd(tno);
                  end
               end
            end
         end
      case "param"
         p = args{k + 1};
         if (p(2) < 0.5 || p(1) < 0.25 * (0.5 + p(2))^2)
            printf("*E* mfs_transresp: bad definition of Newmark parameters\n");
            rc = 1;
         end
         param(1 : length(p)) = p;
      otherwise
         printf("*E* mfs_transresp: unknown parameter %s\n", args{k});
         rc = 1;
      end
  end

  if (! exci)
     printf("*E* mfs_transresp: no excitation definied\n");
     rc = 1;
  end

  if (rc) return; end

# Compute response

  if (meth > 1)
     [resp, rc] = mfs_mtrans(cmp, tdef(1), t, load, meth, ic, param);
  else
     [resp, rc] = mfs_dtrans(cmp, tdef(1), t, load, ic, param);
  end

  if (rc) return; end

# Store results

  if(! isfield(cmp, "transresp"))
     cmp.transresp.nta = rcase;
  else
     cmp.transresp.nta = max(rcase, cmp.transresp.nta);
  end
  cmp.transresp.resp{rcase} = resp;

end
