source: CPL/oasis3-mct_5.0/pyoasis/docs/index.rst @ 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: 32.4 KB
RevLine 
[6328]1pyOASIS Documentation
2=====================
3
4.. toctree::
5   :maxdepth: 2
6   :caption: Contents:
7
8
9Introduction
10------------
11
12pyOASIS is a Python wrapper for OASIS written using ctypes
13and ISO C bindings to Fortran. It provides an object-oriented
14interface to OASIS3-MCT. This allows users to write and couple models
15written in Python
16or to couple models written in Python with models written
17in Fortran.
18
19It is part of the distribution of OASIS3-MCT. See https://portal.enes.org/oasis/download
20for more information about obtaining it.
21
22pyOASIS and OASIS3-MCT are distributed under the GNU Lesser General Public
23License. For more details, see the file lgpl-3.0.txt or
24https://www.gnu.org/licenses/lgpl-3.0.en.html.
25
26
27Using pyOASIS
28-------------
29
30Code structure
31++++++++++++++
32
33The source code of pyOASIS is in the directory ``pyoasis/src``.
34First, the OASIS3-MCT Fortran code is wrapped in Fortran using ISO-C
35bindings. The corresponding source files are in the subdirectory
36``lib/cbindings/fortran_isoc``. The file names are the same as the
37corresponding ones in the original source code but ending in ``_iso.F90``.
38Subsequently, the Fortran with ISO-C bindings is wrapped in C, see
39the source code is in ``lib/cbindings/c_src``. The names of the files are
40the same as the corresponding Fortran ones, but ending in ``_c.c``. Finally,
41the C is wrapped in Python in the directory ``pyoasis/src``. A low-level
42wrapper is made using the same filenames as the Fortran ones but ending in
43``.py``. To access the python interface, one must write a ``import
44pyoasis`` in his/her python code.
45
46Users can find examples on how to use the interface in python, C and Fortran in ``pyoasis/examples``;
47to run all these examples at once, use ``make test`` in ``oasis3-mct/pyoasis``.
48More advanced testing of the python wrapping functions can be done
49with ``make wrappertest``; this will call the script ``tests/run_pytest.sh`` that invokes the standard ``pytest`` testing framework (that has to be installed).
50
51Creating a component using MPI
52++++++++++++++++++++
53
54In pyOASIS, components are instances of the **Component** class. To
55initialise a component, its name has to be supplied ::
56
57    import pyoasis
58    component_name = "component"
59    comp = pyoasis.Component(component_name)
60
61It is also possible to provide an optional ``coupling_flag`` argument which
62defaults to "True”, which means the component is coupled through OASIS3-MCT::
63
64    import pyoasis
65    component_name = "component"
66    coupling_flag = True
67    comp = pyoasis.Component(component_name, coupling_flag)
68
69OASIS3-MCT couples models which communicate using MPI. By default, the
70**Component** class will set up MPI internally and provides methods
71to get access to information such as rank and number of processes in
72the local communicator gathering only the component processes ::
73
74    import pyoasis
75   
76    comp = pyoasis.Component("component")
77   
78    print("Hello world from process " + str(comp.localcomm.rank)
79          + " of " +  str(comp.localcomm.size))
80
81
82If the user needs to specify that the global communicator gathering at start all components of the coupled model is different from the default MPI COMM WORLD, this can be passed to the **Component** class through the communicator
83optional argument. This should be created with ``mpi4py``. ::
84
85    import pyoasis
86    from mpi4py import MPI
87    [...]
88    comm = my_global_comm
89
90    component_name = "component"
91    coupling_flag = True
92    comp = pyoasis.Component(component_name, coupling_flag, comm)
93
94To create a coupling communicator for a subset of processes, one can
95use the method ``create_couplcomm``, with a flag being ``True`` for all these
96processes: ::
97  coupled = True
98  if local_comm_size > 3:
99    if local_comm_rank >= local_comm_size - 2:
100        coupled = False
101  comp.create_couplcomm(coupled)
102
103If such a communicator already exists in the code, it should simply be
104provided to OASIS3-MCT with the method ``set_couplcomm``. Notice that the processes not involved in the coupling should still invoke this method providing the ``MPI.COMM_NULL`` communicator (predefined in ``mpi4py``): ::
105  couplcomm = comp.localcomm.Split(icpl, local_comm_rank)
106  if icpl == 0:
107      couplcomm = MPI.COMM_NULL
108  comp.set_couplcomm(couplcomm)
109
110To set up an MPI intra-communicator or inter-communicator between the local component and
111another component, e.g. the component ``receiver`` in the example
112below, one can use ``get_intracomm`` or ``get_intercomm``: ::
113  intracomm = comp.get_intracomm("receiver")
114  intercomm = comp.get_intercomm("receiver")
115
116To set up an MPI intra-communicator among some of the coupled components, listed in the ``comp_list`` list,
117one can use::
118  intracomm, root_ranks = comp.get_multi_intracomm(comp_list)
119
120where ``root_ranks`` is a dictionary (the keys are the elements of ``comp_list``) providing the ranks of the component roots in the intra-communicator.
121 
122The current OASIS3-MCT internal debug level (``$NLOGPRT``
123value in the ``namcouple``), can be retrieved as a property of a component,
124namely ``comp.debug_level``, as in: ::
125  print("PyOasis debug level set to {}".format(comp.debug_level)
126
127and can be changed by directly modifying, the ``debug_level`` property
128of the component::
129  comp.debug_level = 2
130
131Creating a partition
132++++++++++++++++++++
133
134The data can be partitioned in various ways.
135These correspond to the  **SerialPartition**, **ApplePartition**,
136**BoxPartition**, **OrangePartition** and **PointsPartition**
137classes which are inherited from the **Partition** abstract class.
138For details on the different ways to describe the partitions,
139see OASIS3-MCT User Guide, section 2.2.3 and examples ``1-serial``,
140``2-apple``, ``3-box``, ``4-orange``, ``5-points`` in ``pyoasis/examples``.
141
142The simplest situation is the serial partitioning where all the data is
143held by a single process and only the number of points has to be
144specified (see example ``1-serial``) ::
145
146    n_points = 1600
147    serial_partition = pyoasis.SerialPartition(n_points)
148
149In the case of the apple partitioning, each process contains a segment
150of a linear domain. To initialise such a partitioning, an offset has to
151be supplied for each rank as well as the number of data points that
152will be stored locally. The following example, close to example ``2-apple``,  if run with 4 processes,
153will produce 4 consecutive local segments containing 400 data points ::
154
155    component_name = "component"
156    comp = pyoasis.Component(component_name)
157    rank = comp.localcomm.rank
158    size = comp.localcomm.size
159    n_points = 1600
160    local_size = int(n_points/size)
161    offset = rank * local_size
162    partition = pyoasis.ApplePartition(offset, local_size)
163
164When we use the box partitioning, a 2-dimensional domain is split
165into several rectangles. The global offset, local extents in the x and
166y directions and the global extent in the x direction have to be supplied
167to the constructor. The global offset is the index of the corner of the local
168rectangle. For example, we can split a 4x4 square domain into 4 2x2 parts with
169the following code that will have to be executed using 4 processes. The
170offset is computed from the global and local domain sizes as well as
171the rank. Another example of a box partition is available in example ``3-box`` ::
172
173    rank = comp.localcomm.rank
174    n_global_points_per_side = 4
175    n_partitions_per_side = 2 
176    local_extent = n_global_points_per_side / n_partitions_per_side
177    i_partition_x = rank / n_partitions_per_side
178    i_partition_y = rank % n_partitions_per_side
179    global_offset =   i_partition_x * n_global_points_per_side * local_extent
180                    + i_partition_y * local_extent
181    global_extent_x = n_global_points_per_side
182    partition = pyoasis.BoxPartition(global_offset, local_extent, local_extent,
183                                     global_extent_x)
184
185The orange partitioning consists of several segments of a linear domain.
186As a consequence, a list of offsets and local sizes have to be provided.
187In this example, each process contains 2 consecutive segments of 2
188points. (Another example with only one segment per process is available in example ``4-orange``.) ::
189
190    rank = comp.localcomm.rank
191    n_segments_per_rank = 2
192    n_points_per_segment = 2
193    offset_beginning = rank * n_segments_per_rank * n_points_per_segment
194    offset = [offset_beginning, offset_beginning + n_points_per_segment]
195    extents = [n_points_per_segment, n_points_per_segment]
196    partition = pyoasis.OrangePartition(offsets, extents)
197
198
199The last type of partitioning is points, where we have to
200specify, in a list, the global indices of the points stored by the
201process. (Another example with only one segment per process is
202available in example ``5-points``.) ::
203
204    global_indices=[0, 1, 2, 3]
205    partition = pyoasis.PointsPartition(global_indices)
206
207Defining the coupling grids
208+++++++++++++++++++++++++++
209
210The grid data files, containing the definition of the grids onto which
211the coupling data is defined, can be created by the user before the
212run or can be written directly at run time by the components, either
213by one component process to write the whole grid or by each process
214holding a part of a grid. Details
215about the grid definition can be found in section 2.2.4 of OASIS3-MCT
216User Guide. A full example of writing a grid in sequential and
217parallel models can be found in ``examples/10-grid`` .
218
219To initialise a grid and write the grid longitudes and latitudes, one
220has to create an instance of the **Grid** class: ::
221  [...]
222  lon = np.array([-180. + comm_rank*nx_loc*dx + float(i)*dx +
223               dx/2.0 for i in range(nx_loc)], dtype=np.float64)
224  lon = np.tile(lon, (ny_loc, 1)).T
225
226  lat = np.array([-90.0 + float(j)*dy + dy/2.0 for j in range(ny_loc)],
227               dtype=np.float64)
228  lat = np.tile(lat, (nx_loc, 1))
229  grid = pyoasis.Grid('pyoa', nx_global, ny_global, lon, lat, partition)
230
231To write the grid cell corner longitudes and latitudes, the
232``set_corners`` method can be used ::
233  [...]
234  ncrn = 4
235  clo = pyoasis.asarray(np.zeros((nx_loc, ny_loc, ncrn), dtype=np.float64))
236  clo[:, :, 0] = lon[:, :] - dx/2.0
237  clo[:, :, 1] = lon[:, :] + dx/2.0
238  clo[:, :, 2] = clo[:, :, 1]
239  clo[:, :, 3] = clo[:, :, 0]
240  cla = pyoasis.asarray(np.zeros((nx_loc, ny_loc, ncrn), dtype=np.float64))
241  cla[:, :, 0] = lat[:, :] - dy/2.0
242  cla[:, :, 1] = cla[:, :, 0]
243  cla[:, :, 2] = lat[:, :] + dy/2.0
244  cla[:, :, 3] = cla[:, :, 2]
245
246  grid.set_corners(clo, cla)
247
248To write the grid cell areas, the
249``set_area`` method can be used : ::
250  [...]
251  area = np.zeros((nx_loc, ny_loc), dtype=np.float64)
252  area[:, :] = dp_conv * \
253             np.abs(np.sin(cla[:, :, 2] * dp_conv) -
254                    np.sin(cla[:, :, 0] * dp_conv)) * \
255             np.abs(clo[:, :, 1] - clo[:, :, 0])
256
257  grid.set_area(area)
258
259To define the mask of the grid, the ``set_mask`` method can be used (here
260a mask where all points have zero value i.e. are valid). Notice the optional
261argument ``companion`` providing the name of the corresponding ocean
262grid from which the masks and fractions are obtained: ::
263  msk = np.zeros((nx_loc, ny_loc), dtype=np.int32)
264  grid.set_mask(msk, companion=None)
265
266To define the grid cell water fraction,
267the ``set_frac`` method can be used: ::
268  frc = np.ones((nx_loc, ny_loc), dtype=np.float64)
269  frc = np.where(msk == 1, 0.0, 1.0)
270  grid.set_frac(frc, companion=None)
271
272To define the grid cell angles,
273the ``set_angle`` method can be used: ::
274  angle = np.zeros((nx_loc, ny_loc), dtype=np.float64)
275  grid.set_angle(angle)
276   
277
278Declaring the coupling data
279+++++++++++++++++++++
280
281The coupling data is handled by the class **Var**. Its constructor requires
282its symbolic name, as it appears in the ``namcouple`` file, the partition and a flag indicating whether the
283data is incoming or outgoing. The latter is an enumerated type and can
284have the values ``pyoasis.OasisParameters.OASIS_OUT`` or
285``pyoasis.OasisParameters.OASIS_IN``. In the following example, we wish
286to send data to a process having the rank 1 and we use a partition that was
287previously created.::
288    data_name = "name"
289    variable = pyoasis.Var(data_name, partition,
290                           pyoasis.OasisParameters.OASIS_OUT)
291
292In the case of the receiving model, the code is: ::
293
294    data_name = "name"
295    variable = pyoasis.Var(data_name, partition,           
296                           pyoasis.OasisParameters.OASIS_IN)
297
298The property ``is_active`` can be tested to check if the variable is
299activated in the ``namcouple`` configuring file: ::
300  variable2 = pyoasis.Var("NOTANAME", partition, OASIS.OUT)
301  if variable2.is_active:
302       print("{} is active".format(variable2))
303   else:
304       print("{} is not active".format(variable2))
305
306The coupling period(s) of the data, as defined in the ``namcouple``, can be
307accessed with the property ``cpl_freqs`` and the number of coupling exchanges in
308which the data is involved by ``len(cpl_freqs)``::
309  var_1 = pyoasis.Var("FRECVATM_1", partition, OASIS.IN)
310  print("Recv_one: coupling frequencies for {} = ".format(var_1.name),
311  var_1.cpl_freqs)
312
313The method ``put_inquire`` of the variable tells what would happen
314to the corresponding data at that date
315below the corresponding send action. This maybe useful if, for
316example, the calculation of a coupling field is costly and if one
317wants to compute it only when it is really sent out. The
318different possible return codes are listed in section 2.2.9 of
319OASIS3-MCT User Guide. ::
320
321  for date in range(43200):
322      if var_1.put_inquire(date) == OASIS.SENT:
323          var_1.put(date, pyoasis.asarray([date], dtype=np.float64))
324  [...]
325
326
327Ending the definition phase
328+++++++++++++++++++++
329
330We must end the definition of the component by calling the ``enddef()``
331method. ::
332
333    comp.enddef()
334
335However this must be done only once the partitioning and the variable data have been initalised.
336
337
338Sending and receiving data
339++++++++++++++++++++++++++
340
341pyOASIS expects data to be provided as a **pyoasis.asarray** object:
342::
343     field = pyoasis.asarray(range(n_points))
344     
345This is a Numpy array but ordered in the Fortran way.
346In C, multidimensional arrays store data in row-major order where
347contiguous elements are accessed by incrementing the rightmost index
348while varying the other indices will correspond to increasing strides in
349memory as we use indices further towards the left. By default, Numpy arrays
350use that ordering as well. Fortran, on the other hand, uses column-major
351order. In that case, contiguous elements are accessed by incrementing
352the leftmost index. **pyoasis.asarray** objects use the same ordering as
353Fortran. As a consequence, it is not necessary to transform data in order to
354use it in the OASIS3-MCT Fortran library. ::
355
356The sending and receiving actions may be called by the component at
357each timestep. The date argument is automatically analysed and actions
358are actually performed only if date corresponds to a time for which it
359should be activated, given the period indicated by the user in the
360namcouple. See OASIS3-MCT User Guide section 2.2.7 for details. ::
361
362The data is sent with the following function. ::
363   
364   date = int(0)
365   variable.put(date, field)
366
367Conversely, it is received with the function ::
368
369    variable.get(date, field)
370
371This will fill the
372**pyoasis.asarray** object.
373
374Termination
375++++++++++
376
377Finally, the coupling is terminated in the destructor of
378the component: ::
379  del comp
380
381
382Exceptions and aborting
383++++++++++
384
385When an error occurs in OASIS3-MCT, the code coupler returns an error
386code and an **OasisException** is raised. In practice, OASIS3-MCT will
387internally handle the error, write an error message in its
388debug log files and to the screen, and abort before the exception is raised. It
389may also happen that the code aborts before the error message appears
390on the screen.
391
392When an error is caught by the pyOASIS wrapper, such as an incorrect parameter
393or a wrong argument type, a **PyOasisException** is raised.
394
395In the following example, where we attempt to initialise a component,
396a **PyOasisException** will be raised as the user supplies an empty
397name : ::
398
399    try:
400        comp = pyoasis.Component("")
401    except (pyoasis.PyOasisException) as exception:
402        pyoasis.pyoasis_abort(exception)
403
404The function ``pyoasis.pyoasis_abort`` takes an exception as argument.
405It stops the execution  of all the processes after having displayed an error message and
406written information in the log files about the error and the context in
407which it took place.
408
409Another function is available, ``pyoasis.oasis_abort``,
410for the cases where a voluntary abort is needed in the code where or
411not an exception has been raised. Its interface mimics the
412corresponding OASIS3-MCT functio ``oasis_abort``.
413
414
415Examples
416--------
417
418Serial partitions
419+++++++++++++++++
420
421The example in examples/1-serial/python, containing the full source code as well as the namcouple file and a script
422to run this example, consists in two models, one sending data to
423another.
424The sender and receiver start in the same way.
425
426-Import pyOASIS and initialise the MPI communicator ::
427
428    import pyoasis
429    from mpi4py import MPI
430    comm = MPI.COMM_WORLD
431
432-Initialisation of the component ::
433
434    comp = pyoasis.Component(component_name)
435
436-Initialisation of the serial partition ::
437
438    partition = pyoasis.SerialPartition(n_points)
439
440-From this point, the sender and the receiver start to
441differ. In the sender, the variable data is initialised
442by ::
443
444    variable = pyoasis.Var("FSENDOCN", partition,
445                          pyoasis.OasisParameters.OASIS_OUT)
446
447whereas, in the receiver, we have ::
448
449    variable = pyoasis.Var("FRECVATM", partition,
450                          pyoasis.OasisParameters.OASIS_IN)
451                       
452where the last flag is instead ``pyoasis.OasisParameters.OASIS_IN``
453to indicate that, in this case, the data will be incoming.
454
455In both scripts, the initialisation of the component ends by ::
456
457    comp.enddef()
458
459In the sender, the data is subsequently transmitted by ::
460
461    time_in_the_model = int(0)
462    field = pyoasis.asarray(range(n_points))
463    variable.put(date, field)
464
465while, in the receiver, it is recovered by ::
466
467    time_in_the_model = int(0)
468    field = pyoasis.asarray(numpy.zeros(n_points))
469    variable.get(date, field)
470
471
472Apple and orange partitions
473+++++++++++++++++++++++++++
474
475In the example in ``examples/6-apple_and_orange/python``, both models run as several processes. The beginning
476of the code is identical to the previous example. We will highlight
477only the differences. In the sender, the data is split according to the apple partitioning ::
478
479    partition = pyoasis.ApplePartition(offset, local_size)
480
481whereas the receiver uses the orange partitioning. ::
482
483    partition = pyoasis.OrangePartition(offsets, extents)
484
485In both cases, the offsets and sizes of the local part of the
486data have to be specified. Each process subsequently transmits and
487receives its share of the data as previously. In the sender, we have ::
488
489    date = int(0)
490    field = pyoasis.asarray(numpy.zeros(local_size))
491    for i in range(local_size):
492        field[i] = offset + i
493    variable.put(date, field) 
494
495
496while, in the receiver, ::
497
498    date = int(0)
499    field = pyoasis.asarray(numpy.zeros(extent))
500    variable.get(date, field)
501
502
503Fortran and Python interoperability
504+++++++++++++++++++++++++++++++++++
505
506In order to illustrate the possibility to couple models written in
507Python and in Fortran, the previous example is repeated in pyoasis/examples/8-interoperability/fortran_and_python but this time, the sender
508has been written in Fortran. The receiver is the same as above.
509
510The sender consists in an analogous sequence using the OASIS3-MCT
511Fortran API
512
513-Initialisation of the component ::
514
515    call oasis_init_comp(comp_id, comp_name, kinfo)
516
517-Initialisation of the apple partition with the relevant offset and
518local size ::
519
520    part_params=[1, offset, local_size]
521    call oasis_def_partition(part_id, part_params, kinfo)
522
523-Creation of the variable data, a bundle with two fields ::
524
525    var_nodims=[1, 2]
526    call oasis_def_var(var_id, var_name, part_id, var_nodims, OASIS_OUT,
527                      [1], OASIS_REAL, kinfo)
528
529-End of the definition of the component ::
530
531   call oasis_enddef(kinfo)
532
533-Transmission of the local part of the data to the other component ::
534
535   call oasis_put(var_id, date, bundle, kinfo)
536
537-End of the coupling ::
538
539   call oasis_terminate(kinfo)
540
541
542API reference
543-------------
544
545.. autoclass:: pyoasis.Component
546               :members:
547                             
548.. autoclass:: pyoasis.SerialPartition
549
550.. autoclass:: pyoasis.ApplePartition
551
552.. autoclass:: pyoasis.BoxPartition
553               
554.. autoclass:: pyoasis.OrangePartition
555
556.. autoclass:: pyoasis.PointsPartition
557
558.. autofunction:: pyoasis.OasisParameters()
559
560.. autofunction:: pyoasis.asarray
561
562.. autoclass:: pyoasis.Var
563               :members:
564 
565.. autoclass:: pyoasis.Grid
566               :members:
567                 
568.. autoclass:: pyoasis.OasisException
569
570.. autoclass:: pyoasis.PyOasisException
571               
572.. autofunction:: pyoasis.pyoasis_abort
573
574.. autofunction:: pyoasis.oasis_abort
575
576
577Correspondence with the OASIS3-MCT Fortran API
578---------------------------------------
579
580These tables show the correspondence between the functions
581described in the OASIS3-MCT user guide and their analogue in pyoasis.
582All the functions have been implemented with their full interface
583except ``put`` which, in the case of pyoasis, accepts only
584a single field.
585
586
587Component
588+++++++++
589
590+------------------------------------+-----------------------------------+
591| OASIS3-MCT                         | pyoasis.Component.                |
592+====================================+===================================+
593| oasis_init_comp(comp_id, comp_name,| __init__(name, coupled=True,      |
594| ierror, coupled, comm_world)       |   communicator=None)              |
595+------------------------------------+-----------------------------------+
596| oasis_terminate(ierror)            | __del__()                         |
597+------------------------------------+-----------------------------------+
598| oasis_create_couplcomm(icpl,       | create_couplcomm(coupled)         |
599| localcomm, couplcomm, kinfo)       |                                   |
600+------------------------------------+-----------------------------------+
601| oasis_set_couplcomm(couplcomm,     | set_couplcomm(couplcomm)          |
602| kinfo)                             |                                   |
603+------------------------------------+-----------------------------------+
604| oasis_get_multi_intracomm(newcomm, | get_multi_intracomm(complist)     |
605| cdnam, root_ranks, kinfo)          |                                   |
606+------------------------------------+-----------------------------------+
607| oasis_get_intracomm(newcomm, cdnam,| get_intracomm(compname)           |
608| kinfo)                             |                                   |
609+------------------------------------+-----------------------------------+
610| oasis_get_intercomm(newcomm,       | get_intercomm(compname)           |
611| cdnam, kinfo)                      |                                   |
612+------------------------------------+-----------------------------------+
613| oasis_enddef(ierror)               | enddef()                          |
614+------------------------------------+-----------------------------------+
615| oasis_get_local_comm(local_comm,   | localcomm                         |
616| ierror)                            |                                   |
617+------------------------------------+-----------------------------------+
618| oasis_get_debug(debugvalue)        | debug_level                       |
619+------------------------------------+-----------------------------------+
620| oasis_set_debug(debugvalue)        | debug_level                       |
621+------------------------------------+-----------------------------------+
622
623Partition
624+++++++++
625
626+------------------------------------+-----------------------------------+
627| OASIS3-MCT                         | pyoasis.                          |
628+====================================+===================================+
629| oasis_def_partition(ilpart_id,     | SerialPartition(size,             |
630|   igparal, ierror, isize, name)    |   global_size=-1, name="")        |
631|                                    | ApplePartition(offset, size,      |
632|                                    |   global_size=-1, name="")        |
633|                                    | BoxPartition(global_offset,       |
634|                                    |   local_extent_x, local_extent_y, |
635|                                    |   global_extent_x, global_size=-1,|
636|                                    |   name="")                        |
637|                                    | OrangePartition(offsets, extents, |
638|                                    |   global_size=-1, name="")        |
639|                                    | PointsPartition(global_indices,   |
640|                                    |   global_size=-1, name="")        |
641+------------------------------------+-----------------------------------+
642
643Var
644+++
645
646+------------------------------------+-----------------------------------+
647| OASIS3-MCT                         | pyoasis.var.                      |
648+====================================+===================================+
649| oasis_def_var(var_id, name,        | __init__(name, partition, inout,  |
650|   il_part_id, var_nodims, kinout,  |   bundle_size=1)                  |
651|   var_actual_shape, vartype,       |                                   |
652|   ierror)                          |                                   |
653+------------------------------------+-----------------------------------+
654| oasis_put(varid, date, fld1, info, | put(date, field,                  |
655| fld2, fld3, fld4, fld5,            |   write_restart=False)            |
656| write_restart)                     |                                   |
657+------------------------------------+-----------------------------------+
658| oasis_get(varid, date, fld, info)  | get(date, field)                  |
659+------------------------------------+-----------------------------------+
660| oasis_put_inquire(varid, date,     | put_inquire(date)                 |
661|   kinfo)                           |                                   |
662+------------------------------------+-----------------------------------+
663| oasis_get_ncpl(varid, ncpl, kinfo) | len(cpl_freqs)                    |
664+------------------------------------+-----------------------------------+
665| oasis_get_freqs(varid, mop, ncpl,  | cpl_freqs                         |
666|   cplfreqs, kinfo)                 |                                   |
667+------------------------------------+-----------------------------------+
668
669Grid
670++++
671
672+---------------------------------+------------------------------+
673| OASIS3-MCT                      | pyoasis.grid.                |
674+=================================+==============================+
675| oasis_start_grids_writing(flag) | __init__(cgrid, nx_global,   |
676| oasis_write_grid(cgrid,         |   ny_global, lon, lat,       |
677|   nx_global, ny_global, lon,    |   partition=None)            |
678|   lat, il_partid)               |                              |
679+---------------------------------+------------------------------+
680| oasis_write_corner(cgrid,       | set_corners(clo, cla)        |
681|   nx_global, ny_global, nc,     |                              |
682|   clon, clat, il_partid)        |                              |
683+---------------------------------+------------------------------+
684| oasis_write_area(cgrid,         | set_area(area)               |
685|   nx_global, ny_global,         |                              |
686|   area, il_partid)              |                              |
687+---------------------------------+------------------------------+
688| oasis_write_mask(cgrid,         | set_mask(mask,               |
689|   nx_glo, ny_glo, mask,         |   companion=None)            |
690|   part_id, companion)           |                              |
691+---------------------------------+------------------------------+
692| oasis_write_frac(cgrid,         | set_frac(frac,               |
693|   nx_glo, ny_glo, frac,         |   companion=None)            |
694|   part_id, companion)           |                              |
695+---------------------------------+------------------------------+
696| oasis_write_angle(cgrid,        | set_angle(angle)             |
697|   nx_global, ny_global,         |                              |
698|   angle, il_partid)             |                              |
699+---------------------------------+------------------------------+
700| oasis_terminate_grids_writing() | write()                      |
701+---------------------------------+------------------------------+
702
703Utilities
704+++++++++
705
706+---------------------------------+-------------------------------+
707| OASIS3-MCT                      | pyoasis.                      |
708+=================================+===============================+
709|oasis_abort(compid, routinename, | oasis_abort(component_id,     |
710|  abortmessage, rcode)           |   routine, message, filename, |
711|                                 |   line, error)                |
712|                                 | pyoasis_abort(exception)      |
713+---------------------------------+-------------------------------+
714
715
716Installation
717------------
718
719
720Under GNU/Linux
721+++++++++++++++
722
723Prerequisites
724.............
725
726- A Fortran and C compiler suite
727- An MPI library
728- NetCDF 4
729- Python 3 with mpi4py, numpy and netCDF4
730- Extra optional packages for plotting (as in examples ``11-test-interpolation`` and ``12-grid-functions``)
731   - matplotlib
732   - GEOS (Geometry Engine, Open Source):
733     package libgeos-dev under Debian or Ubuntu, geos-devel under Fedora
734   - proj:
735     package libproj-dev under Debian or Ubuntu, proj-devel under Fedora
736- Optional packages for generating the documentation:
737   - sphinx
738   - Tex Live
739- Optional package for automated testing:
740   - pytest
741
742OASIS3-MCT Installation
743.......................
744
745- Obtain OASIS3-MCT (refer to OASIS3-MCT User Guide for details).
746- Change directory to ${OASIS_ROOT}/util/make_dir.
747- Create your own make.inc file based on make.intel_davinci, make.gfortran_openmpi_linux or make.bindings.
748- Build and install OASIS3-MCT and pyOASIS::
749
750    make -f TopMakefile realclean
751    make -f TopMakefile pyoasis
752
753- Append the lines displayed at the end of the compilation to your .bashrc file or, alternatively, before using pyOASIS, source the script mentioned there.
754
755Virtual Python environment
756................
757
758- Create a virtual environment (set ``VENVDIR`` as a directory of your choice containing the virtual environment): ::
759
760    export VENVDIR=~/INSTALL/PY_ENV/PyO   
761    python3 -m venv ${VENVDIR}
762    source ${VENVDIR}/bin/activate
763   
764- Install packages: ::
765   
766    pip install --upgrade pip
767    pip install mpi4py
768    pip install numpy
769    pip install netcdf4
770
771Extra software
772..............
773
774- For applications using Cartopy plots, as in the examples ``11-test-interpolation`` and ``12-grid-functions`` : ::
775   
776    pip install scipy
777    pip install matplotlib
778    pip uninstall shapely   
779    pip install shapely --no-binary shapely
780    pip install cartopy
781
782- Optional package for performances optimisation: ::
783   
784    pip install pykdtree
785
786
787Under macOS
788+++++++++++
789
790Prerequisites
791.............
792
793Refer to the GNU/Linux section.
794
795If using Brew (tested with gnu up to version 10.2.0): ::
796   
797   brew install gcc   
798   brew install openblas
799   brew install openmpi
800
801For the optional packages: ::
802 
803   brew install geos
804   brew install proj
805
806   
807OASIS3-MCT Installation
808.......................
809
810Same as under GNU/Linux. See previous section.
811
812
813Virtual Python environment
814..........................
815
816- Create a virtual environment:
817
818    Same as under GNU/Linux, see previous section.
819   
820- Install packages: ::
821
822    pip install mpi4py
823    pip uninstall numpy
824    pip cache remove numpy
825    OPENBLAS="$(brew --prefix openblas)" pip install --global-option=build-ext numpy
826    pip install netcdf4
827
828Extra software
829..............
830
831- For applications using Cartopy plots, as in the examples ``11-test-interpolation`` and ``12-grid-functions``: ::
832   
833    pip uninstall scipy
834    pip cache remove scipy
835    pip install --global-option=build-ext scipy
836    pip uninstall shapely
837    pip install shapely --no-binary shapely
838    pip install matplotlib
839    pip install cartopy
840   
841- Optional package for performances optimisation: ::
842   
843    pip install pykdtree
844
845Set up the environment
846......................
847At the end of your .bashrc, ::
848
849    export TMPDIR=/tmp
850    export OMPI_MCA_mca_base_env_list=LD_LIBRARY_PATH=${PYOASIS_ROOT}/lib
851
852
853Documentation
854+++++++++++++
855
856If pyOASIS is modified, this document can be regenerated, using Sphinx,
857by typing the following command in the directory ${OASIS_ROOT}/pyoasis::
858 
859   make doc
860
861
862Acknowledgments
863---------------
864
865This work has been financed by the IS-ENES3 project which has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 824084.
866
867.. image:: euflag.png
868
869 
870Index and search
871----------------
872
873* :ref:`genindex`
874* :ref:`search`
Note: See TracBrowser for help on using the repository browser.