function [set2phys, eset] = mfs_exp_phys(fid, cmp, typ2dim)

# usage: [set2phys, eset] = mfs_exp_phys(fid, cmp, typ2dim)
#
# Input  fid              File handle of output file
#        cmp              Structure with component
#        typ2dim(noftyp)  Array with element dimensions
#
# Output set2phys  Structure relating sets to physical names
#        eset      Structure with element sets
#
# This function builds the physical names and writes them to the
# output file.
#
# Fields of structure set2phys:
#    set2phys.(name)(:).dim       Dimension
#                      .physTag   Physical tag
#
#    (name) = "nset" or "eset"
#
#    The index of a set in (name) agrees with the index of the set
#    in cmp.nset or cmp.eset.
#
# ------------------------------------------------------------------------

# Check arguments

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

# Initialize

  eset     = struct();
  set2phys = struct();

  nnset = numfields(cmp.nset);
  neset = numfields(cmp.eset);

  if (! (neset || nnset))
     return;
  end

  incTag = 0;
  numPhys = nnset + neset;

  fprintf(fid, "$PhysicalNames\n");
  fprintf(fid, "%d\n", numPhys);

# Process the node sets 
# ---------------------

  if (nnset)
     set2phys.nset = struct("dim", 0, 
                            "physTag", num2cell(1 : nnset));
     nsets = fieldnames(cmp.nset);
     for n = 1 : nnset
         fprintf(fid, "0 %d \"%s\"\n", n, nsets{n})
     end
     incTag = nnset;
  end

# Process the element sets
# ------------------------

  if (neset)

     eset = cmp.eset;

# Determine the dimensions of the elements in the sets. If not all
# elements within a set have the same dimension, keep only those with
# the highest dimension.

     dim = zeros(1, neset); n = 1;

     for [eindx, name] = cmp.eset

         etype = cmp.elements.index(eindx, 3);
         dims  = typ2dim(etype);
         mxdim = max(dims);

         dim(n++)    = mxdim;
         ixe         = find(dims == mxdim);
         eset.(name) = eindx(ixe);

     end

# Create structure

     physTag = (1 : neset) + incTag;
     set2phys.eset = struct("dim",     num2cell(dim),
                            "physTag", num2cell(physTag));

# Output physical names

      esets = fieldnames(eset);
      [~, ixset] = sort(dim);

      for n = 1 : neset
          ix = ixset(n);
          fprintf(fid, "%d %d \"%s\"\n", dim(ix), physTag(ix),
                  esets{ix});
      end

  end

# End

  fprintf(fid, "$EndPhysicalNames\n");

end
