This replaces the makePreconditoner() function. The main advantage is that it is extensible, making it easy to for example add new preconditioners to the factory at runtime. It supports both parallel and serial preconditioners.