function nodedata = mfs_mat2nodedata(mat, dofrow, mxdofpnt, type)

# usage: nodedata = mfs_mat2nodedata(mat, dofrow, mxdofpnt, type)
#
# Input  mat(nrow, ncol)   Input matrix
#        dofrow(nrow)      Indices of degrees of freedom corresponding
#                          to matrix rows
#        mxdofpnt          Maximum number of degrees of freedom per
#                          nodal point
#        type              Data type (only stored in nodedata)
#
# Output nodedata(ncol)    Structure array with matrix columns stored
#                          as nodal point results
#
# Fields of structure array nodedata:
#   nofnod              Number of nodal points with data
#   id(nofnod)          Internal nodal point identifiers
#   d(nofnod, mxdofpnt) Nodal point data
#   type                Data type
#
# ---------------------------------------------------------------------

# Check arguments

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

# Get nodal point indices and dof identifiers

  node_index = 1 + floor((dofrow - 1) / mxdofpnt);
  dofid      = 1 + mod(dofrow -1, mxdofpnt);

# Process data

  [nrow, ncol] = size(mat);
  current_id   = 0;
  nofnod       = 0;

  for n = 1 : nrow
      if (node_index(n) == current_id)
         d(nofnod, dofid(n), :) = mat(n, :);
      else
         current_id   = node_index(n);
         id(++nofnod) = current_id;
         d(nofnod, :, :) = zeros(mxdofpnt, ncol);
         d(nofnod, dofid(n), :) = mat(n, :);
      end
  end

  for n = 1 : ncol
      nodedata(n) = struct("nofnod", nofnod, "id", id,
                           "d", d(:, :, n), "type", type);
  end

end
