1. C3PO documentation
1.1. Introduction
C3PO (Collaborative Code Coupling PlatfOrm) is a Python library offering generic services for the definition of coupled calculations with codes meeting a certain framework. This framework is defined by:
Use of Python. Codes have to be wrapped into a Python class, which allows to coordinate them in a homogeneous way regardless of their native programming language.
Use of MEDCoupling for data exchanges. MEDCoupling is the common format choosen for the exchanges of space-dependent variables. MEDCoupling is a C++ library, with Python binding, provided by the open-source SALOME platform [1].
If needed, use of MPI as distributed memory parallelization standard. MPI is by far the dominant distributed memory parallelization standard. C3PO is compatible with the use of MPI, but does not support other distributed memory parallelization standards. On the other hand, full flexibility is given for the intra-code shared memory parallelization.
Implementation of an ICoCo API [2]. ICoCo (V2) is the code API used by C3PO. It includes all required capabilities for multiphysics simulations such as initialization, termination, time-step control, solving, exchange of variables etc. It is defined by
c3po.PhysicsDriver.PhysicsDriver.
For more information about code integration, see How to use a code with C3PO.
The main objective of C3PO is to facilitate and standardize the writing of coupling scripts, in particular in HPC (High Performance Computing) environment. It also provides generic (and HPC-compatible) implementations of the main coupling algorithms (Picard iteration, Anderson acceleration, JFNK), and allows pooling of efforts in the development and verification of multi-physics calculation schemes.
C3PO is code- and physics-agnostic, and therefore constitutes a kernel of generic methods that can be shared by different multi-physics applications. For this reason, it has been made open-source under the (highly permissive) 3-Clause BSD License here: https://sourceforge.net/projects/cea-c3po/.
1.2. Source overview
The sources directory contains:
The directory
c3powith all C3PO sources. It can be imported without any MPI dependency.The file setup.py that can be used to install C3PO via pip: “pip install path –user” (with path the path to the setup.py file)
The file .pylintrc that define coding standards to be followed in C3PO. Install pylint (python3 module available with pip) and run “pylint c3po” from the sources directory to check your code. You must get the grade 10/10!
The directory sources/c3po contains the definition of the following classes:
c3po.DataAccessor.DataAccessoris a class interface (to be implemented) which standardizes the accesses to data. It follows the ICOCO standard.c3po.PhysicsDriver.PhysicsDriveris a class interface (to be implemented) which standardizes the functionalities expected by computer codes. It derives fromc3po.DataAccessor.DataAccessorfor the data accesses. It follows the ICoCo standard.c3po.CollaborativeObject.CollaborativeObjectis a base class for classes that allow to handle a set of objects as a single one.c3po.CollaborativePhysicsDriver.CollaborativePhysicsDriverhandles a set ofc3po.PhysicsDriver.PhysicsDriveras a single one. It inherits fromc3po.CollaborativeObject.CollaborativeObject.c3po.TimeAccumulator.TimeAccumulatoris a class that allows to distinguish a notion of macro time steps to be used to drive ac3po.PhysicsDriver.PhysicsDriverin a coupling from the notion of micro time steps actually used by thec3po.PhysicsDriver.PhysicsDriver. It can also be used to wrap a stabilized transient loop into a steady state call.c3po.DataManager.DataManageris a class interface (to be implemented) which standardizes methods to handle data outside of codes. This is necessary for some coupling techniques or time schemes.c3po.LocalDataManager.LocalDataManagerimplements bothc3po.DataManager.DataManagerandc3po.DataAccessor.DataAccessor: it can store and handle local data.c3po.CollaborativeDataManager.CollaborativeDataManagerhandles a set ofc3po.DataManager.DataManageras a single one. It inherits fromc3po.CollaborativeObject.CollaborativeObject.c3po.Exchanger.Exchangeris a class interface (to be implemented) which standardizes data exchanges betweenc3po.DataAccessor.DataAccessorobjects (c3po.PhysicsDriver.PhysicsDriverorc3po.LocalDataManager.LocalDataManager).c3po.LocalExchanger.LocalExchangeris ac3po.Exchanger.Exchangerfor local data exchanges.c3po.CollaborativeExchanger.CollaborativeExchangerallows to handle a set ofc3po.Exchanger.Exchangeras a single one. It inherits fromc3po.CollaborativeObject.CollaborativeObject.c3po.Coupler.Coupleris the base class for the definition of a coupling, based onc3po.PhysicsDriver.PhysicsDriver,c3po.DataManager.DataManagerandc3po.Exchanger.Exchangerconcepts. It inherits fromc3po.PhysicsDriver.PhysicsDriver.
Basic couplings can be made only with these classes.
The directory sources/c3po also contains six directories:
couplers with specific implementations of
c3po.Coupler.Couplerfor the main coupling algorithms. See below.exchangeMethods with specific implementations of exchange methods (to be used with a
c3po.LocalExchanger.LocalExchanger). See below.medcouplingCompat which deals with various versions of MEDCoupling. Import this module to use all versions of MEDCoupling in an identical way (following the last version API).
physicsDrivers with specific implementations of
c3po.PhysicsDriver.PhysicsDriverfor some codes.services with some optionnal services (mainly for monitoring of coupled calculations). See below.
raises for optionnal error handling services. See below.
multi1D with sources related to the use of a set of 1D models in a 3D coupling. See below.
mpi with sources related to MPI. See below.
Note
When “import c3po” is made, the classes and functions defined in c3po/couplers,
c3po/exchangeMethods and c3po/services are imported and made available directly in c3po module.
“import c3po.medcouplingCompat” must be done if one wants to use directly MEDCoupling (using this helper).
“import c3po.raises” must be done to access raises functionalities. icoco package must be available.
“import c3po.multi1D” (and if needed “import c3po.multi1D.mpi”) must be done to access multi1D functionalities.
“import c3po.mpi” must be done to get access to MPI classes of C3PO (the classes and functions
defined in c3po/mpi/mpiExchangeMethods are imported and made available directly in c3po.mpi
module). mpi4py must be available.
Each class of c3po/physicsDrivers must be imported separately.
“import c3po.services.checkScope” must be done, as it uses an additionnal prerequisite “icoco”.
1.2.1. c3po/couplers directory
This directory contains the definition of the following classes (coupling algorithms, they all
inherit from c3po.Coupler.Coupler):
c3po.couplers.FixedPointCoupler.FixedPointCouplerproposes a damped fixed point algorithm.c3po.couplers.AndersonCoupler.AndersonCouplerproposes a fixed point algorithm with Anderson acceleration. A QR decomposition is used for the optimization problem.c3po.couplers.JFNKCoupler.JFNKCouplerproposes a Jacobian-Free Newton Krylov coupling algorithm.c3po.couplers.CrossedSecantCoupler.CrossedSecantCouplerproposes a fixed point algorithm with crossed secant acceleration.c3po.couplers.AdaptiveResidualBalanceCoupler.AdaptiveResidualBalanceCouplerproposes a adaptive residual balance algorithm (version proposed by Senecal).c3po.couplers.DynamicResidualBalanceCoupler.DynamicResidualBalanceCouplerproposes a dynamic residual balance algorithm (variant of the adaptive residual balance proposed by R. Delvaux).
1.2.2. c3po/exchangeMethods directory
This directory contains the definition of the following classes (exchange methods to be used with
a c3po.LocalExchanger.LocalExchanger):
c3po.exchangeMethods.ExchangeMethod.ExchangeMethodis a class interface (to be implemented) which standardizes exchange methods to be used withc3po.LocalExchanger.LocalExchanger(or its daughter classc3po.mpi.MPIExchanger.MPIExchanger).c3po.exchangeMethods.DirectMatching.DirectMatchingis the most simple exchange method: it does nothing else than output = input.c3po.exchangeMethods.SharedRemapping.SharedRemappingprojects the input fields one by one before returning them as outputs, in the same order.
1.2.3. c3po/services directory
This directory contains the definition of the following elements:
c3po.services.tracer.traceris a class wrapper allowing to trace the calls of the methods of the base class. It has different functions:It can write all calls of the methods of the base class in a text file in Python format in order to allow to replay what happened from the code point of view outside of the coupling.
It can save in .med files input or output MEDFields.
It can redirect code standard and error outputs in text files.
It can contribute (with
c3po.services.ListingWriter.ListingWriter) to the writing of a global coupling listing file with calculation time measurement.
c3po.services.ListingWriter.ListingWriterallows, in association withc3po.services.tracer.tracer, to write a global coupling listing file with calculation time measurement. Three funtions work with this class:mergeListing()which allows to merge listing files produced byc3po.services.ListingWriter.ListingWriter(or by previous call tomergeListing()). It is designed to produce a comprehensive view of a MPI calculation.getTotalTimePhysicsDriver()which reads a listing file produced byc3po.services.ListingWriter.ListingWriterormergeListing()and returns the total time spent by onec3po.PhysicsDriver.PhysicsDriverin indicated methods.getTimesExchanger()which reads a listing file produced byc3po.services.ListingWriter.ListingWriterormergeListing()and returns time information about a chosen exchanger.
c3po.services.NameChanger.NameChangerwraps ac3po.PhysicsDriver.PhysicsDriverobject and changes the names of the values and fields quantities that can be get/set through ICoCo methods. The idea is to improve the genericity of coupling scripts by using generic variable names without having to modify the names “by hand”.c3po.services.PhysicsDriverWrapper.PhysicsDriverWrapperis a skeleton, intended to be overloaded, for modifying the behavior of a PhysicsDriver by composition.c3po.services.wrappercontain two experimental functions:c3po.services.wrapper.buildWrappingClasswhich returns a wrapping class for any provided one.c3po.services.wrapper.wrapperwhich returns a wrapping object (built withc3po.services.wrapper.buildWrappingClass) for any provided one.
c3po.services.TransientLogger.TransientLoggeris a class interface (to be implemented) for logging (in standard output) information during a transient (method solveTransient() fromc3po.PhysicsDriver.PhysicsDriver). There are two implementations of this class:c3po.services.TransientLogger.Timekeeperprovides basic information about transient progress. It is the default implementation used byc3po.PhysicsDriver.PhysicsDriver(but logging is by default desactivated).c3po.services.TransientLogger.FortuneTellerderives fromc3po.services.TransientLogger.Timekeeperand adds an evaluation of the remaining computing time to complete the transient.
1.2.4. c3po/raises directory
This directory contains the definition of the following elements:
c3po.raises.checkScope.CheckScopeMetais a metaclass which adds scope checks required by ICoCo standard (and raise appropriate errors).c3po.raises.checkScope.checkScopeis a class wrapper that appliesc3po.raises.checkScope.CheckScopeMetametaclass.
1.2.5. c3po/multi1D directory
This directory contains the definition of the following classes:
c3po.multi1D.Grid.Gridis a class interface that allows to define 2D grids and to assign indices to each grid cell. The following daughter classes are available:c3po.multi1D.Grid.MEDGridto import a grid defined as a 2D MEDCoupling field,c3po.multi1D.Grid.CartesianGridfor cartesian grids,c3po.multi1D.Grid.HexagonalGridfor hexagonal grids,c3po.multi1D.Grid.MultiLevelGridto define nested grids.
c3po.multi1D.Multi1DAPI.Multi1DAPIis a minimalist class interface for handling a set of 1D components.c3po.multi1D.Multi1DAPI.Multi1DWithObjectsAPIis an extension of the previous class where each 1D component can hold a set of objects identified by name.c3po.multi1D.MEDInterface.MEDInterfaceis a class that can read and write 3D fields by associating ac3po.multi1D.Grid.Gridand ac3po.multi1D.Multi1DAPI.Multi1DAPI.c3po.multi1D.Multi1DPhysicsDriver.Multi1DPhysicsDriveris the master class of the multi1D package. It holds a set of 1D PhysicsDriver (through the non-user class c3po.multi1D.Multi1DPhysicsDriver.DriverAPI that implementsc3po.multi1D.Multi1DAPI.Multi1DAPIfor 1D PhysicsDriver), and behaves like a unique 3D PhysicsDriver (using internallyc3po.multi1D.MEDInterface.MEDInterface).
When c3po.multi1D is imported, the above-mentioned classes are imported and made available
in c3po.multi1D.
c3po/multi1D also contains one directory:
mpi with specializations of
c3po.multi1Dfor MPI couplings. See below.
1.2.5.1. c3po/multi1D/mpi directory
c3po.multi1D.mpi.MPIMulti1DPhysicsDriveris the MPI collaborative version ofc3po.multi1D.Multi1DPhysicsDriver.Multi1DPhysicsDriver.
1.2.6. c3po/mpi directory
This directory contains the definition of C3PO sources related to MPI.
Two parallelization modes are available (and can be mixed):
Collaborative: all the processes run the same instructions. Instructions that do not concern a process (because it does not host a code for example) are ignored.
Master-workers: a master process executes the highest-level instructions. It controls the execution of calculation codes and the data exchanges between worker processes.
These two parallelization modes share a common base of concepts.
1.2.6.1. Common base
c3po.mpi.MPIRemote.MPIRemote. It can replaces a remotec3po.PhysicsDriver.PhysicsDriverandc3po.DataManager.DataManager(and inherits from these class) but passes most of the methods: it does nothing.c3po.mpi.MPIRemoteProcess.MPIRemoteProcessidentifies a (single) remote process. It inherits fromc3po.mpi.MPIRemote.MPIRemotebut contains in addition the rank of the process in charge of the real object.c3po.mpi.MPIRemoteProcesses.MPIRemoteProcessesidentifies a set of remote processes. It inherits fromc3po.mpi.MPIRemote.MPIRemotebut contains in addition the list of ranks of the processes in charge of the real object.c3po.mpi.MPICollectiveProcess.MPICollectiveProcessdefines a collective process. In particular, it allows, by inheritance (a new class that inherits fromc3po.mpi.MPICollectiveProcess.MPICollectiveProcessmust be defined), to define a collectivec3po.PhysicsDriver.PhysicsDriver: all processors will locally launch this component.c3po.mpi.MPIExchanger.MPIExchangeris the MPI version ofc3po.LocalExchanger.LocalExchanger. The class either use directly ac3po.mpi.mpiExchangeMethods.MPIExchangeMethod.MPIExchangeMethodor use ac3po.exchangeMethods.ExchangeMethod.ExchangeMethod(in the case where each code exposes its data on a single MPI process). In this last case, it takes in charge data exchanges between MPI processes then uses locallyc3po.LocalExchanger.LocalExchanger.
1.2.6.2. Collaborative mode
c3po.mpi.MPICollaborativeDataManager.MPICollaborativeDataManageris the MPI collaborative version ofc3po.CollaborativeDataManager.CollaborativeDataManager. It allows to handle a set ofc3po.DataManager.DataManager(some of then being remote) as a single one. Thanks to this class, data can be distributed on different MPI processes but still used in the same way.c3po.mpi.MPIDomainDecompositionDataManager.MPIDomainDecompositionDataManageris the version ofc3po.DataManager.DataManagerto be used to handle data comming from codes using domain decomposition methods. As forc3po.mpi.MPICollaborativeDataManager.MPICollaborativeDataManager, the data are distributed on different MPI processes.c3po.mpi.MPICollectiveDataManager.MPICollectiveDataManageris the MPI collaborative version of thec3po.LocalDataManager.LocalDataManagerin which all processes have all data locally.c3po.mpi.MPICoupler.MPICoupleris the MPI collaborative version ofc3po.Coupler.Coupler.c3po.mpi.MPICollaborativePhysicsDriver.MPICollaborativePhysicsDriveris the MPI collaborative version ofc3po.CollaborativePhysicsDriver.CollaborativePhysicsDriver(and is a specific kind ofc3po.mpi.MPICoupler.MPICoupler). It allows to handle a set ofc3po.PhysicsDriver.PhysicsDriveras a single one.
1.2.6.3. Master/workers mode
c3po.mpi.MPIMasterPhysicsDriver.MPIMasterPhysicsDriveris used by the master process to control remotec3po.PhysicsDriver.PhysicsDriveras a local one.c3po.mpi.MPIMasterDataManager.MPIMasterDataManageris used by the master process to control remotec3po.DataManager.DataManageras a local one.c3po.mpi.MPIMasterExchanger.MPIMasterExchangeris used by the master to control remotec3po.Exchanger.Exchanger.c3po.mpi.MPIWorker.MPIWorkerdefines the behavior of workers.
The directory sources/c3po/mpi also contains one directories:
mpiExchangeMethods with specific implementations of MPI exchange methods. See below.
1.2.6.4. c3po/mpi/mpiExchangeMethods directory
c3po.mpi.mpiExchangeMethods.MPIExchangeMethod.MPIExchangeMethodis a class interface (to be implemented) which standardizes MPI exchange methods. Unlike the exchanges methods of c3po/exchangeMethods, MPI exchange methods support MPI exchanges. It has to be used with ac3po.mpi.MPIExchanger.MPIExchanger.c3po.mpi.mpiExchangeMethods.MPISharedRemapping.MPISharedRemappingthis is the MPI version ofc3po.exchangeMethods.SharedRemapping.SharedRemapping. MPI features of MEDCoupling must be available. It allows to use MEDCoupling projections between codes using domain decomposition methods.c3po.mpi.mpiExchangeMethods.MPIValueBcast.MPIValueBcastcan be used to exchange values (not fields) between two sets of processes.
1.3. Contacts
1.4. References
[1] “Salomé: The Open Source Integration Platform for Numerical Simulation”, http://www.salome-platform.org.
[2] E. Deville, F. Perdu, “Documentation of the Interface for Code Coupling : ICoCo”, NURISP technical report D3.3.1.2 (2012).