Modify optimization interface to be more general
Add initial implementation for `ipopt` solver