function [cmps, cmpa, rc] = mfs_backc(cmp, class, item, args)

# usage: [cmps, cmpa, rc] = mfs_backc(cmp, class, item, args)
#
# Input  cmp       Structure with aeroelastic component
#        class     Response class
#        item      Response item
#        args{:}   Additional arguments depending on class and item
#
# Output cmps      Solid component
#        cmpa      Aerodynamic component
#        rc        Return code: 0 = no errors
#                               1 = errors 
#
# The functions performs the back transformation from modal to
# physical coordinates for aeroelastic components.
#
# class = flutter
#
#   item   Description      Additional arguments
#   -------------------------------------------------------------------
#   disp   Displacements    args{1}   modpnt(:, 1) Mode number
#                                     modpnt(:, 2) Flutter point ident.
#
# class = freqresp
#
#   item   Description      Additional arguments
#   -------------------------------------------------------------------
#   disp   Displacements    args{1}   List of excitation frequencies
#                                     (default: all)
#                           args{2}   List of load cases
#                                     (default: all)
#
# ------------------------------------------------------------------------

# Copyright (c) 2020 by Johannes Wandinger

# Check arguments

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

# Initialize

  cmps = cmp.solid;
  cmpa = cmp.aero;
  nargs = length(args);
  rc   = 0;

# Branch according to response class

  switch class

# Flutter

  case "flutter"

     if (! isfield(cmp, "flutter"))
        printf("*E* mfs_back: no flutter results found\n");
        rc = 1; return;
     end

#    Process item

     switch item

     case "disp"

        msel = cmp.flutter.msel;

        modpnt = args{1};
        [nshape, nc] = size(modpnt);

        if (nc != 2)
           printf("*E* mfs_back: selector matrix does not have 2 columns\n");
           rc = 1; return;
        end

        modes = lookup(cmp.flutter.modno, modpnt(:, 1), "m");
        ixbad = find(modes == 0);
        if (! isempty(ixbad))
           for n = 1 : length(ixbad) 
               prinf("*E* mfs_back: flutter mode %3.0d does not exist\n",
                     modpnt(ixbad(n), 1));
           end
           rc = 1; return;
        end
        if ((p = min(modpnt(:, 2))) < 1 || ...
            (p = max(modpnt(:, 2))) > cmp.flutter.nofpnt)
           printf("*E* mfs_back: flutter point %d does not exist\n", p);
           rc = 1; return;
        end

        XX = zeros(cmp.flutter.nsel, nshape);
        v  = zeros(1, nshape); kred = zeros(1, nshape);
        f  = zeros(1, nshape);

        for n = 1 : nshape
            m = modes(n); p = modpnt(n, 2);
            XX(:, n) = cmp.flutter.XX(:, m, p);
            switch cmp.flutter.method
            case "k"
               v(n)    = cmp.flutter.v(m, p);
               kred(n) = cmp.flutter.kred(p);
            case "pk"
               v(n)    = cmp.flutter.v(p);
               kred(n) = cmp.flutter.kred(m, p);
            end
            f(n) = cmp.flutter.f(m, p);
        end

        sdisp = cmps.modes.disp(:, msel) * XX;
        h     = cmp.splines.Shg * sdisp;
        adisp = cmp.splines.Snh * h;

        cmps.flutter = struct("nshape", nshape, "mode", modpnt(:, 1), 
                              "point", modpnt(:, 2), "v", v, "f", f, 
                              "kred", kred, "disp", sdisp);
        cmpa.flutter = struct("nshape", nshape, "mode", modpnt(:, 1), 
                              "point", modpnt(:, 2), "v", v, "f", f, 
                              "kred", kred, "disp", adisp);

     otherwise

        printf("*E* mfs_back: unknown response item \"%s\"\n", item);
        rc = 1;

     end    % item

# Frequency response

  case "freqresp"

     if (! isfield(cmp, "fregsresp"))
        printf("*E* mfs_back: no frequency response results found\n");
        rc = 1; return;
     end

#    Get load case

     if (nargs < 2 || isempty(args{2})
        ldc = 1 : cmp.freqresp.nfa;
     else
        ldc = sort(args{2});
        if ((ldb = max(ldc)) > cmp.freqresp.nfa ||
            (ldb = min(ldc)) < 1)
            printf("*E* mfs_back: loadcase %d ", ldb);
            printf("does nost exist\n");
            rc = 1;
            return;
         end
     end

#    Load case loop

     for l = ldc

         resp = cmp.freqresp.resp{l};

         if (resp.method == 1)
            printf("*I* mfs_back: loadcase %d: ", l);
            printf("no backtransformation for direct frequency response\n");
            continue;
         end

#        Get frequencies

         if (nargs == 0 || isempty(args{1})
            ixf = 1 : resp.nfreq;
         else
            f = sort(args{1});
            if ((fb = min(f)) < resp.freq(1) ||
                (fb = max(f)) > resp.freq(end))
                printf("*E* mfs_back: frequency %8.3f ", fb);
                printf("out of range\n");
                rc = 1;
                return;
            else
               ixf = lookup(resp.freq, f);
            end
         end

#        Process item

         switch item

         case "disp"

         otherwise

             printf("*E* mfs_back: unknown response item \"%s\"\n", item);
             rc = 1;

         end  % item

     end  % Load case loop

  otherwise

     printf("mfs_back: unknown response class \"%s\"\n", class);
     rc = 1;

  end      % class

end
