123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 |
- #include <iostream>
- #include "config.h"
- #include "shell.h"
- #include "oasis-cpp-interface.h"
- #include "OasisCoupler.h"
- #include <stdio.h>
- #include <stdlib.h>
- using namespace std;
- char OasisCoupler::modelName[] = "lpjg";
- // *** Received FROM IFS ***
- // 1
- char OasisCoupler::fieldTempName[] = "T2M_LPJG";
- int OasisCoupler::fieldTempId = 0;
- // 2
- char OasisCoupler::fieldPrecipName[] = "TPRE_LPJ";
- int OasisCoupler::fieldPrecipId = 0;
- // 3
- char OasisCoupler::fieldSnowCName[] = "SNOC_LPJ";
- int OasisCoupler::fieldSnowCId = 0;
- // 4
- char OasisCoupler::fieldSnowDName[] = "SNOD_LPJ";
- int OasisCoupler::fieldSnowDId = 0;
- // 5
- char OasisCoupler::fieldST1LName[] = "ST1L_LPJ";
- int OasisCoupler::fieldST1LId = 0;
- // 6
- char OasisCoupler::fieldST2LName[] = "ST2L_LPJ";
- int OasisCoupler::fieldST2LId = 0;
- // 7
- char OasisCoupler::fieldST3LName[] = "ST3L_LPJ";
- int OasisCoupler::fieldST3LId = 0;
- // 8
- char OasisCoupler::fieldST4LName[] = "ST4L_LPJ";
- int OasisCoupler::fieldST4LId = 0;
- // 9
- char OasisCoupler::fieldSM1LName[] = "SM1L_LPJ";
- int OasisCoupler::fieldSM1LId = 0;
- // 10
- char OasisCoupler::fieldSM2LName[] = "SM2L_LPJ";
- int OasisCoupler::fieldSM2LId = 0;
- // 11
- char OasisCoupler::fieldSM3LName[] = "SM3L_LPJ";
- int OasisCoupler::fieldSM3LId = 0;
- // 12
- char OasisCoupler::fieldSM4LName[] = "SM4L_LPJ";
- int OasisCoupler::fieldSM4LId = 0;
- // 13
- char OasisCoupler::fieldSWRadName[] = "SWNR_LPJ";
- int OasisCoupler::fieldSWRadId = 0;
- // 14
- char OasisCoupler::fieldLWRadName[] = "LWNR_LPJ";
- int OasisCoupler::fieldLWRadId = 0;
- // *** Send TO IFS ***
- // 16
- char OasisCoupler::fieldLowlaiName[] = "GUE_LLAI";
- int OasisCoupler::fieldLowlaiId = 0;
- // 17
- char OasisCoupler::fieldHighlaiName[] = "GUE_HLAI";
- int OasisCoupler::fieldHighlaiId = 0;
- // 18
- char OasisCoupler::fieldTypeHName[] = "GUE_TYPH";
- int OasisCoupler::fieldTypeHId = 0;
- // 19
- char OasisCoupler::fieldFracHName[] = "GUE_FRAH";
- int OasisCoupler::fieldFracHId = 0;
- // 20
- char OasisCoupler::fieldTypeLName[] = "GUE_TYPL";
- int OasisCoupler::fieldTypeLId = 0;
- // 21
- char OasisCoupler::fieldFracLName[] = "GUE_FRAL";
- int OasisCoupler::fieldFracLId = 0;
- // *** Received FROM TM5 ***
- // 22
- char OasisCoupler::fieldCO2Name[] = "CO2_LPJG";
- int OasisCoupler::fieldCO2Id = 0;
- // *** Sent TO TM5 ***
- // 23
- char OasisCoupler::fieldCfluxNatName[] = "GUE_CNAT";
- int OasisCoupler::fieldCfluxNatId = 0;
- // 24
- char OasisCoupler::fieldCfluxAntName[] = "GUE_CANT";
- int OasisCoupler::fieldCfluxAntId = 0;
- // 25
- char OasisCoupler::fieldNPPName[] = "GUE_CNPP";
- int OasisCoupler::fieldNPPId = 0;
- // ecev3 - returns localcomm
- int OasisCoupler::init(int &localcomm)
- {
- int ierror;
- int componentId = -99;
- dprintf("OasisCoupler::init init_comp \n");
- ierror = OASISMCT::init_comp(&componentId,modelName);
- if (ierror != OASISMCT::OASIS_Ok) {
- dprintf("OasisCoupler::init init_comp ERROR!!\n");
- return ierror;
- }
- // ecev3 - for internal parallelisation
- int localCommId = -99;
- ierror = OASISMCT::get_localcomm(localCommId);
- if (ierror != OASISMCT::OASIS_Ok) {
- dprintf("OasisCoupler::get_localcomm ERROR - %i\n", ierror);
- OASISMCT::terminate();
- return ierror;
- }
- // Save the local comm index
- localcomm = localCommId;
- return OASISMCT::OASIS_Ok;
- };
- // ecev3 - returns couplcomm
- int OasisCoupler::create_couplcomm(int myrank, int lcomm, int& ccomm) {
- int ierror;
- dprintf("OasisCoupler::create_couplcomm \n");
- int cplcomm = -99;
- ierror = OASISMCT::create_couplcomm(myrank, lcomm, &cplcomm);
- if ( ierror != OASISMCT::OASIS_Ok )
- return ierror;
- else
- ccomm = cplcomm;
- return OASISMCT::OASIS_Ok;
- };
- // ecev3
- int OasisCoupler::init_part_defvar(int nx, int ny, bool TM5coupled, int rank) {
- int ierror;
- int partitionId = -99;
- int partitionDescr[] = {0,0,nx*ny};
- // ecev3 - see OASIS-MCT documentation
- if (rank != 0)
- partitionDescr[2] = 0;
- dprintf("OasisCoupler::init_part_defvar def_partition for rank %i\n", rank);
- ierror = OASISMCT::def_partition(&partitionId,partitionDescr,3);
- // Bug in OASISMCT: def_partition doesn't return a valid return value
- if ( ierror != OASISMCT::OASIS_Ok ) {
- dprintf("OasisCoupler::init_part_defvar: def_partition returned %i\n", ierror);
- return ierror;
- }
- dprintf("OasisCoupler::init_part_defvar: rank %i partitionId is %i\n", rank, partitionId);
- int varNumDims[] = {2,1};
- int varShape[] = {1,nx,1,ny};
- dprintf("OasisCoupler::init_part_defvar def_var statements for rank %i \n", rank);
- // *** Received FROM IFS (Currently 14) ***
- ierror = OASISMCT::def_var(&fieldTempId,fieldTempName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldPrecipId,fieldPrecipName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSnowCId,fieldSnowCName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSnowDId,fieldSnowDName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldST1LId,fieldST1LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldST2LId,fieldST2LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldST3LId,fieldST3LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldST4LId,fieldST4LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSM1LId,fieldSM1LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSM2LId,fieldSM2LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSM3LId,fieldSM3LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSM4LId,fieldSM4LName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldSWRadId,fieldSWRadName,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldLWRadId,fieldLWRadName,partitionId,varNumDims,OASISMCT::OASIS_In, varShape, OASISMCT::OASIS_Real);
- if (ierror != OASISMCT::OASIS_Ok) return ierror;
- // *** Sent TO IFS (Currently 6) ***
- ierror = OASISMCT::def_var(&fieldLowlaiId,fieldLowlaiName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldHighlaiId,fieldHighlaiName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldTypeHId,fieldTypeHName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldFracHId,fieldFracHName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldTypeLId,fieldTypeLName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- ierror = OASISMCT::def_var(&fieldFracLId,fieldFracLName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- // *** TM5 Coupling (Currently 4 fields) ***
- if (TM5coupled) {
- dprintf("OasisCoupler::init_part_defvar - initialising TM5 coupling\n");
- // FROM TM5
- ierror = OASISMCT::def_var(&fieldCO2Id,fieldCO2Name,partitionId,varNumDims,OASISMCT::OASIS_In,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- // TO TM5
- ierror = OASISMCT::def_var(&fieldCfluxNatId,fieldCfluxNatName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- // TO TM5
- ierror = OASISMCT::def_var(&fieldCfluxAntId,fieldCfluxAntName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- // TO TM5
- ierror = OASISMCT::def_var(&fieldNPPId,fieldNPPName,partitionId,varNumDims,OASISMCT::OASIS_Out,varShape,OASISMCT::OASIS_Real);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- }
- dprintf("OasisCoupler::init_part_defvar - calling OASISMCT::enddef on rank %i\n",rank);
- ierror = OASISMCT::enddef();
- dprintf("OasisCoupler::init_part_defvar - OASISMCT::enddef returned ierror %i on rank %i\n",ierror, rank);
- if (ierror != OASISMCT::OASIS_Ok) return ierror;
- return OASISMCT::OASIS_Ok;
- };
- int OasisCoupler::abort(int compid, std::string routine_name, std::string abort_message, int return_code)
- {
- //dprintf("OasisCoupler::abort %s\n",(char)abort_message);
- int ierror = OASISMCT::abort(compid, routine_name, abort_message, return_code);
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- return 0;
- };
- int OasisCoupler::finalize(void)
- {
- dprintf("OasisCoupler::finalize\n");
- int ierror = OASISMCT::terminate();
- if ( ierror != OASISMCT::OASIS_Ok ) return ierror;
- return 0;
- };
- // Up to 18 fields (17 from IFS + 1 from TM5 if TM5coupled == true)
- int OasisCoupler::couple_get(int time, int nx, int ny, bool TM5coupled, double * fieldTempData, double * fieldPrecipData,
- double * fieldSnowCData, double * fieldSnowDData,
- double * fieldST1LData, double * fieldST2LData, double * fieldST3LData, double * fieldST4LData,
- double * fieldSM1LData, double * fieldSM2LData, double * fieldSM3LData, double * fieldSM4LData,
- double * fieldSWRadData, double * fieldLWRadData, double * fieldCO2Data) {
- int ierror = 0;
- try {
- // printf(" OasisCoupler::couple_get -- for time %i\n",time);
- ierror = OASISMCT::get_2d(OasisCoupler::fieldTempId,time,fieldTempData,nx,ny);
- // printf(" OasisCoupler::couple_get -- got T2m\n");
- }
- catch(...) {
- switch (ierror)
- {
- case OASISMCT::OASIS_Recvd:
- dprintf(" T2M received from other model: %i \n", ierror);
- break;
- case OASISMCT::OASIS_FromRest:
- dprintf(" Read from restart file only: %i \n", ierror);
- break;
- case OASISMCT::OASIS_Input:
- dprintf(" Read from input file only: %i \n", ierror);
- break;
- case OASISMCT::OASIS_RecvOut:
- dprintf(" Received from other model and written to an output file: %i \n", ierror);
- break;
- case OASISMCT::OASIS_FromRestOut:
- dprintf(" Read from restart file and written to output file: %i \n", ierror);
- break;
- case OASISMCT::OASIS_Ok:
- dprintf(" OASIS_Ok, no error. T2M received OK, continue: %i \n", ierror);
- break;
- default:
- dprintf(" OasisCoupler::couple_get - unknown ierror reported from OASIS_GET: %i \n", ierror);
- break;
- }
-
- }
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSWRadId, time, fieldSWRadData, nx, ny);
- //printf(" OasisCoupler::couple -- got Rad\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldLWRadId, time, fieldLWRadData, nx, ny);
- //printf(" OasisCoupler::couple -- got Rad\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSM1LId,time,fieldSM1LData,nx,ny);
- // printf(" OasisCoupler::couple -- got SM1\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSM2LId,time,fieldSM2LData,nx,ny);
- // printf(" OasisCoupler::couple -- got SM2\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSM3LId,time,fieldSM3LData,nx,ny);
- // printf(" OasisCoupler::couple -- got SM3\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSM4LId,time,fieldSM4LData,nx,ny);
- // printf(" OasisCoupler::couple -- got SM4\n");
-
- ierror = OASISMCT::get_2d(OasisCoupler::fieldST1LId,time,fieldST1LData,nx,ny);
- // printf(" OasisCoupler::couple -- got ST1\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldST2LId,time,fieldST2LData,nx,ny);
- // printf(" OasisCoupler::couple -- got ST2\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldST3LId,time,fieldST3LData,nx,ny);
- // printf(" OasisCoupler::couple -- got ST3\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldST4LId,time,fieldST4LData,nx,ny);
- // printf(" OasisCoupler::couple -- got ST4\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSnowCId,time,fieldSnowCData,nx,ny);
- //printf(" OasisCoupler::couple -- got SnowC\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldSnowDId,time,fieldSnowDData,nx,ny);
- // printf(" OasisCoupler::couple -- got SnowD\n");
- ierror = OASISMCT::get_2d(OasisCoupler::fieldPrecipId,time,fieldPrecipData,nx,ny);
- // printf(" OasisCoupler::couple -- got Prec\n");
- // ecev3 - only receive CO2 fields from TM5 if we're coupled
- if (TM5coupled) {
- ierror = OASISMCT::get_2d(OasisCoupler::fieldCO2Id,time,fieldCO2Data,nx,ny);
- dprintf(" OasisCoupler::couple -- got CO2 -- cell 5000 value is %f\n",fieldCO2Data[5000]);
- }
- return 0;
- };
- // Up to 8 fields (6 to IFS + 2 to TM5 if TM5coupled == true)
- int OasisCoupler::couple_put(int time, int nx, int ny, bool TM5coupled, double * fieldLowlaiData, double * fieldHighlaiData,
- double * fieldLPJGtypeHData, double * fieldLPJGfracHData,
- double * fieldLPJGtypeLData, double * fieldLPJGfracLData,
- double * fieldLPJGCfluxNatData, double * fieldLPJGCfluxAntData,
- double * fieldLPJGNPPData) {
- int ierror = 0;
- try {
- // printf(" OasisCoupler::couple_put -- for time %i\n",time);
- ierror = OASISMCT::put_2d(OasisCoupler::fieldLowlaiId,time,fieldLowlaiData,nx,ny);
- }
- catch (...) {
- switch (ierror)
- {
- case OASISMCT::OASIS_Sent:
- dprintf(" LLAI field sent to the other model: %i \n",ierror);
- break;
- case OASISMCT::OASIS_LocTrans:
- dprintf(" OASIS_LocTrans: %i \n",ierror);
- break;
- case OASISMCT::OASIS_Output:
- dprintf(" Output file only: %i \n",ierror);
- break;
- case OASISMCT::OASIS_ToRest:
- dprintf(" Written to restart file only: %i \n",ierror);
- break;
- case OASISMCT::OASIS_ToRestOut:
- dprintf(" Written to restart file and written to output file: %i \n",ierror);
- break;
- case OASISMCT::OASIS_SentOut:
- dprintf(" OASIS_SentOut: %i \n",ierror);
- break;
- case OASISMCT::OASIS_Ok:
- dprintf(" OASIS_Ok, LLAI sent, no error: %i - continue\n",ierror);
- break;
- default:
- dprintf(" OasisCoupler::couple_put - unknown ierror %i reported from OASIS_PUT for field %i \n",ierror,OasisCoupler::fieldLowlaiId);
- break;
- }
- }
- // ecev3 - always send fields to IFS
- ierror = OASISMCT::put_2d(OasisCoupler::fieldHighlaiId,time,fieldHighlaiData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put HLAI - ierror: %i\n",ierror);
- ierror = OASISMCT::put_2d(OasisCoupler::fieldTypeHId,time,fieldLPJGtypeHData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put TYPH - ierror: %i\n",ierror);
- ierror = OASISMCT::put_2d(OasisCoupler::fieldFracHId,time,fieldLPJGfracHData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put FRACH - ierror: %i\n",ierror);
- ierror = OASISMCT::put_2d(OasisCoupler::fieldTypeLId,time,fieldLPJGtypeLData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put TYPL - ierror: %i\n",ierror);
- ierror = OASISMCT::put_2d(OasisCoupler::fieldFracLId,time,fieldLPJGfracLData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put FRACL - ierror: %i\n",ierror);
- // ecev3 - only send CO2 fluxes to TM5 if we are coupled
- if (TM5coupled) {
- ierror = OASISMCT::put_2d(OasisCoupler::fieldCfluxNatId,time,fieldLPJGCfluxNatData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put CFLUXNAT - ierror: %i\n",ierror);
-
- ierror = OASISMCT::put_2d(OasisCoupler::fieldCfluxAntId,time,fieldLPJGCfluxAntData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put CFLUXANT - ierror: %i\n",ierror);
-
- ierror = OASISMCT::put_2d(OasisCoupler::fieldNPPId,time,fieldLPJGNPPData,nx,ny);
- if (ierror != OASISMCT::OASIS_Ok)
- dprintf(" OasisCoupler::couple_put NPP - ierror: %i\n",ierror);
- }
- return 0;
- };
|