Hi,
the behavior is correct. If you plot fes.FreeDofs() you observe that the last dof is “not-free”, it depends on the first one due to periodicity. If you draw the function you get a periodic function
from ngsolve.internal import visoptions
from ngsolve.internal import viewoptions
visoptions.showsurfacesolution=True
viewoptions.drawedges=1
visoptions.deformation=1
Draw(gfu, mymesh, "gfu")
With fes = Compress(Periodic(H1(mymesh,order=1))) the last dof is compressed out and you have only 3 dofs left.
Best,
Michael