Abstractions and performance optimisations for finite element methods