Add abstract collective operation
This new reduce function takes a std::function as an argument which is used to perform the reduce operation It uses an allGather and local reduce on each process which is not be optimal in terms of performance. So only use if non performance critical