Refactor AMPI virtual topologies
Currently, ampiCommStruct has members for all possible topologies (cart, graph, dist_graph), even though a a communicator can only be one or zero of those topologies.
There is lots of duplicated code for handling different aspects of these topologies.
I propose refactoring this by creating a virtual Topology class which has 3 derived classes: Cart, Graph, and DistGraph. Make an instance of that class a member in ampiCommStruct, and also have an integer identifying the type of that class in ampiCommStruct (with value MPI_UNDEFINED, MPI_CART, MPI_GRAPH, or MPI_DIST_GRAPH). This way ampiCommStruct's pup routine can use that int to correctly pup the Topology instance.