#!/usr/bin/env python3 # Copyright 2021 - Barcelona Supercomputing Center # Author: Rodrigo Martín Posada # MIT License import f90nml import pyoasis from pyoasis import OASIS # pylint: disable=no-name-in-module import numpy as np import logging NAMELIST_FILE_NAME = 'namelist.amip' L080_NX = 35718 # number of LAND grid cells at T159 resolution L128_NX = 88838 # number of LAND grid cells at T255 resolution L256_NX = 348528 # number of LAND grid cells at T511 resolution CO2_MODE = False def def_local_partition(nx, npes, mype): il_size = nx // npes il_offset = mype * il_size if (npes-mype) <= nx % npes: il_size += 1 il_offset += (nx % npes) - (npes-mype) return il_size, il_offset if __name__ == '__main__': # Constants from namelist nml = f90nml.read(NAMELIST_FILE_NAME) COUPLING_INTERVAL = nml['NAMAMIP']['TimeStepSec'] RUN_LENGTH_SEC = nml['NAMAMIP']['RunLengthSec'] # Init OASIS comp = pyoasis.Component("IFS_MOCK") local_comm = comp.localcomm # Get rank in local communicator mype = comp.localcomm.rank npes = comp.localcomm.size # Unit for output messages out_ifs = 'IFS_mock.out_'+str(100+mype) logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) logging.debug('-----------------------------------------------------------') logging.debug('I am IFS-mock process with rank : {}'.format(mype)) logging.debug('in my local communicator gathering {} processes'.format(npes)) logging.debug('----------------------------------------------------------') # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ with open('namcouple', 'r') as f: contents = f.read() if 'CO2_conc' in contents: CO2_MODE = True if 'L080' in contents: nx = L080_NX elif 'L128' in contents: nx = L128_NX elif 'L256' in contents: nx = L256_NX else: raise Exception('Invalid IFS grid in namcouple') # Definition of the local partition il_size, il_offset = def_local_partition(nx, npes, mype) logging.debug('Local partition definition') logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) partition = pyoasis.ApplePartition(il_offset, il_size) if CO2_MODE: nx_co2 = 2 if mype == 0: logging.debug('Local serial partition') logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) partition2 = pyoasis.SerialPartition(nx_co2) else: nx_co2 = 0 partition2 = None # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) if CO2_MODE: A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) if mype == 0: A_CO2_conc = pyoasis.Var("A_CO2_conc", partition2, OASIS.IN) logging.debug('var_id A_CO2_conc {}'.format(A_CO2_conc._id)) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION OF DEFINITION PHASE # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('End of initialisation phase') comp.enddef() # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TIME STEP LOOP # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('Timestep, field min, mean and max value') field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) if CO2_MODE and mype == 0: field_recv_A_CO2_conc = pyoasis.asarray(np.full(nx_co2, -1.0)) for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): A_SST.get(itap_sec, field_recv_A_SST) A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) logging.debug('ITAP_SEC: {}'.format(itap_sec)) logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_SST), np.mean(field_recv_A_SST), np.max(field_recv_A_SST))) logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_Ice_frac), np.mean(field_recv_A_Ice_frac), np.max(field_recv_A_Ice_frac))) if CO2_MODE: A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) if mype == 0: A_CO2_conc.get(itap_sec, field_recv_A_CO2_conc) logging.debug('A_CO2_conc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_conc), np.mean(field_recv_A_CO2_conc), np.max(field_recv_A_CO2_conc))) logging.debug('--------------------------------------\n') # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('End of the program') del comp