source: CPL/oasis3-mct_5.0/pyoasis/src/component.py @ 6328

Last change on this file since 6328 was 6328, checked in by aclsce, 17 months ago

First import of oasis3-mct_5.0 (from oasis git server, branch OASIS3-MCT_5.0)

File size: 9.1 KB
Line 
1# pyOASIS - A Python wrapper for OASIS
2# Authors: Philippe Gambron, Rupert Ford
3# Copyright (C) 2019 UKRI - STFC
4
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as
7# published by the Free Software Foundation, either version 3 of the
8# License, or any later version.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Lesser General Public License for more details.
14
15# A copy of the GNU Lesser General Public License, version 3, is supplied
16# with this program, in the file lgpl-3.0.txt. It is also available at
17# <https://www.gnu.org/licenses/lgpl-3.0.html>.
18
19
20import pyoasis.mod_oasis_auxiliary_routines
21import pyoasis.mod_oasis_getput_interface
22import pyoasis.mod_oasis_method
23import pyoasis.mod_oasis_part
24import pyoasis.mod_oasis_sys
25import pyoasis.mod_oasis_var
26from mpi4py import MPI
27
28
29class Component(object):
30    """
31    Component that will be coupled by OASIS3-MCT
32
33    :param str name: name of the component
34    :param bool coupled: whether the component will be coupled (default: True)
35    :param mpi4py.MPI.Intracomm communicator: global MPI communicator (default: MPI.COMM_WORLD)
36    :raises OasisException: if OASIS is unable to initialise the component
37    :raises PyOasisException: if an incorrect parameter is supplied
38    """
39
40    _n_components = 0
41
42    def __init__(self, name, coupled=True, communicator=None):
43        """Constructor"""
44        self._initialised = False
45        pyoasis.checktypes.check_types([str, bool, MPI.Intracomm],
46                                       [name, coupled,
47                                       communicator])
48        if Component._n_components > 0:
49            raise pyoasis.PyOasisException("There should be only one component.")
50
51        Component._n_components += 1
52
53        if len(name) == 0:
54            raise pyoasis.PyOasisException("Component name empty.")
55        self._name = name
56        if communicator:
57            self._communicator = communicator
58            return_value = pyoasis.mod_oasis_method.init_comp_with_comm(self._name,
59                                                                        coupled,
60                                                                        self._communicator)
61        else:
62            return_value = pyoasis.mod_oasis_method.init_comp(self._name,coupled)
63        self._initialised = True
64        error = return_value[1]
65        if error < 0:
66            raise pyoasis.OasisException("Error initialising component " + self._name,
67                                         error)
68        self._id = return_value[0]
69        return_value = pyoasis.mod_oasis_auxiliary_routines.get_localcomm()
70        error = return_value[1]
71        if error < 0:
72            raise pyoasis.OasisException("Error in get_localcomm", error)
73        self._localcomm_hdle = return_value[0]
74        try:
75            self.localcomm = MPI.Comm.f2py(self._localcomm_hdle)
76        except MPI.Exception:
77            self.localcomm = MPI.COMM_NULL
78        self.couplcomm = MPI.Comm.Dup(self.localcomm)
79
80    def __del__(self):
81        """
82        Destructor
83        Ends the coupling.
84        """
85        if self._initialised:
86            try:
87                error = pyoasis.mod_oasis_method.terminate()
88                if error < 0:
89                    pyoasis.oasis_abort(self._id, "Component::__del__",
90                                        "oasis_terminate failed",
91                                        "component.py", 79, error)
92                self._initialised = False
93            except AttributeError:
94                pass
95
96    @property
97    def name(self):
98        """
99        :returns: the name of the component
100        :rtype: string
101        """
102        return self._name
103
104    def create_couplcomm(self, coupled):
105        """
106        Creates a coupling communicator toto
107
108        :param bool coupled: coupling flag
109
110        :returns: error code
111        :rtype: int
112
113        :raises OasisException: if OASIS is unable to create the coupling \
114                                communicator
115        :raises PyOasisException: if an incorrect parameter is supplied
116        """
117        allcomm = self._localcomm_hdle
118        pyoasis.check_types([bool, int], [coupled, allcomm])
119        if coupled:
120            icpl = 1
121        else:
122            icpl = MPI.UNDEFINED
123        return_value = pyoasis.mod_oasis_auxiliary_routines.create_couplcomm(icpl,
124                                                                             allcomm)
125        error = return_value[1]
126        if error < 0:
127            raise pyoasis.OasisException("Error in create_couplcomm", error)
128        self._couplcomm_hdle = return_value[0]
129        try:
130            self.couplcomm = MPI.Comm.f2py(self._couplcomm_hdle)
131        except MPI.Exception:
132            self.couplcomm = MPI.COMM_NULL
133
134        return error
135
136    def set_couplcomm(self, couplcomm):
137        """
138        Sets the coupling communicator
139        :param MPI.communicator couplcomm: coupling communicator
140
141        :returns: error code
142        :rtype: int
143
144        :raises OasisException: if OASIS is unable to set the coupling \
145                                communicator
146        :raises PyOasisException: if an incorrect parameter is supplied
147        """
148        error = pyoasis.mod_oasis_auxiliary_routines.set_couplcomm(couplcomm)
149        if error < 0:
150            raise pyoasis.OasisException("Error in set_couplcomm", error)
151        self._couplcomm_hdle = couplcomm.py2f()
152        self.couplcomm = couplcomm
153
154        return error
155
156    def get_intracomm(self, compname):
157        """
158        :param string compname: name of the other component in the intracommunicator
159        :returns: the intracommunicator
160        :rtype: MPI.communicator
161        :raises OasisException: if OASIS is unable to create the intracommunicator
162        :raises PyOasisException: if an incorrect parameter is supplied
163        """
164        pyoasis.check_types([str],[compname])
165        new_comm, error = pyoasis.mod_oasis_auxiliary_routines.get_intracomm(compname)
166        if error < 0:
167            raise pyoasis.OasisException("Error in get_intracomm", error)
168        try:
169            return MPI.Comm.f2py(new_comm)
170        except MPI.Exception:
171            raise pyoasis.OasisException("Error in get_intracomm conversion",
172                                         -1)
173
174    def get_multi_intracomm(self, complist):
175        """
176        :param string complist: list of names of the other component in the intracommunicator
177        :returns: the intracommunicator and a dictionary of the ranks of the component roots in the intracommunicator
178        :rtype: MPI.communicator, dict
179        :raises OasisException: if OASIS is unable to create the intracommunicator
180        :raises PyOasisException: if an incorrect parameter is supplied
181        """
182        pyoasis.check_types([list],[complist])
183        new_comm, root_ranks, error = pyoasis.mod_oasis_auxiliary_routines.get_multi_intracomm(complist)
184        if error < 0:
185            raise pyoasis.OasisException("Error in get_multi_intracomm", error)
186        try:
187            return MPI.Comm.f2py(new_comm), root_ranks
188        except MPI.Exception:
189            raise pyoasis.OasisException("Error in get_multi_intracomm conversion",
190                                         -1)
191
192    def get_intercomm(self, compname):
193        """
194        :param string compname: name of the other component
195         in the intercommunicator
196        :returns: the intercommunicator
197        :rtype: MPI.communicator
198        :raises OasisException: if OASIS is unable to create
199        the intercommunicator
200        :raises PyOasisException: if an incorrect parameter is supplied
201        """
202        pyoasis.check_types([str], [compname])
203        new_comm, error = pyoasis.mod_oasis_auxiliary_routines.get_intercomm(compname)
204        if error < 0:
205            raise pyoasis.OasisException("Error in get_intercomm", error)
206        try:
207            return MPI.Comm.f2py(new_comm)
208        except MPI.Exception:
209            raise pyoasis.OasisException("Error in get_intercomm conversion",
210                                         -1)
211
212    @staticmethod
213    def enddef():
214        """
215        Ends the initialisation of the component.
216
217        :raises OasisException: if OASIS is unable to end the \
218                                initialisation
219        """
220        error = pyoasis.mod_oasis_method.enddef()
221        if error < 0:
222            raise pyoasis.OasisException("Error in enddef", error)
223
224    def __str__(self):
225        return "Component: name: " + self._name + ", id: " + str(self._id)
226
227    @property
228    def debug_level(self):
229        """
230        Returns the currently set debug level
231
232        :returns: debug level
233        :rtype: int
234
235        :raises OasisException: if OASIS is unable to get the debug level
236        """
237        return pyoasis.get_debug()
238
239    @debug_level.setter
240    def debug_level(self, level):
241        """
242        Set a new debug level
243        :param int level: debug level
244        :raises OasisException: if OASIS is unable to get the debug level
245        """
246        pyoasis.set_debug(level)
Note: See TracBrowser for help on using the repository browser.