void apply_sponge(double h[NZ][NXMEM][NYMEM], double dt, double ea[NZ][NXMEM][NYMEM], double eb[NZ][NXMEM][NYMEM]) { /* Arguments: h - Layer thickness, in m. */ /* dt - The amount of time covered by this call, in s. */ /* ea - an array to which the amount of fluid entrained */ /* from the layer above during this call will be */ /* added, in m. */ /* eb - an array to which the amount of fluid entrained */ /* from the layer below during this call will be */ /* added, in m. */ /* This subroutine applies damping to the layers thicknesses, mixed */ /* layer buoyancy, and a variety of tracers for every column where */ /* there is damping. */ double damp; /* The timestep times the local damping */ /* coefficient. Nondimensional. */ double e[NZ+1]; /* The interface heights, in m, usually negative. */ double w; /* The thickess of water moving upwards through an */ /* interface within 1 timestep, in m. */ double wm; /* wm is w if w is negative and 0 otherwise, in m. */ double wb; /* w at the interface below a layer, in m. */ double wpb; /* wpb is wb if wb is positive and 0 otherwise, m. */ int c, i, j, k, m; for (c=0;c<num_col;c++) { i = col_addr[c]/NYMEM; j = col_addr[c]-NYMEM*i; damp = dt*Iresttime_col[c]; e[NZ] = -D[i][j]; for (k=NZ-1;k>=0;k--) e[k] = e[k+1] + h[k][i][j]; wpb = 0.0; wb = 0.0; for (k=NZ-1;k>=0;k--) { w = D_MIN(((e[k] - Ref_val[c*nfNZ+k*nf+0]) * damp), (wb+h[k][i][j] - EPSILON)); wm = 0.5*(w-fabs(w)); for (m=1;m<fldno;m++) { (*var[m])[k][i][j] = (h[k][i][j]*(*var[m])[k][i][j] + Ref_val[c*nfNZ+k*nf+m] * (damp*h[k][i][j] + wpb - wm))/ (h[k][i][j]*(1.0 + damp) + wpb - wm); tr[m-1][k][i][j] = (*var[m])[k][i][j]; } wb = w; wpb = w - wm; } } }
/**************************************************************************** NAME handleAppRefreshEncryptionReq DESCRIPTION Handles the application refresh encryption key message. */ static void handleAppRefreshEncryptionReq(devInstanceTaskData *inst) { switch (the_app->app_state) { case AppStateIdle: { /* If we have a device active but not in call / streaming */ ConnectionSmEncryptionKeyRefresh(&inst->bd_addr); break; } default: { break; } } MessageSendLater(&inst->task, APP_REFRESH_ENCRYPTION_REQ, 0, D_MIN(EPR_TIMEOUT)); }
/**************************************************************************** NAME handleUsbMessage DESCRIPTION Handle firmware USB messages RETURNS void */ void handleUsbMessage(Task task, MessageId id, Message message) { USB_DEBUG(("USB: ")); switch (id) { case MESSAGE_USB_ATTACHED: { USB_DEBUG(("MESSAGE_USB_ATTACHED\n")); usbUpdateChargeCurrent(); audioHandleRouting(audio_source_none); usbSetLowPowerMode(theSink.usb.config.attach_timeout); if(theSink.usb.dead_battery) MessageSendLater(&theSink.task, EventUsbDeadBatteryTimeout, 0, D_MIN(45)); break; } case MESSAGE_USB_DETACHED: { USB_DEBUG(("MESSAGE_USB_DETACHED\n")); theSink.usb.enumerated = FALSE; theSink.usb.suspended = FALSE; theSink.usb.deconfigured = FALSE; usbUpdateChargeCurrent(); audioHandleRouting(audio_source_none); MessageCancelAll(&theSink.task, EventUsbLowPowerMode); MessageCancelAll(&theSink.task, EventUsbDeadBatteryTimeout); break; } case MESSAGE_USB_ENUMERATED: { USB_DEBUG(("MESSAGE_USB_ENUMERATED\n")); if(!theSink.usb.enumerated) { theSink.usb.enumerated = TRUE; usbUpdateChargeCurrent(); MessageCancelAll(&theSink.task, EventUsbLowPowerMode); MessageCancelAll(&theSink.task, EventUsbDeadBatteryTimeout); } break; } case MESSAGE_USB_SUSPENDED: { MessageUsbSuspended* ind = (MessageUsbSuspended*)message; USB_DEBUG(("MESSAGE_USB_SUSPENDED - %s\n", (ind->has_suspended ? "Suspend" : "Resume"))); if(ind->has_suspended != theSink.usb.suspended) { theSink.usb.suspended = ind->has_suspended; usbUpdateChargeCurrent(); } break; } case MESSAGE_USB_DECONFIGURED: { USB_DEBUG(("MESSAGE_USB_DECONFIGURED\n")); if(theSink.usb.enumerated) { theSink.usb.enumerated = FALSE; theSink.usb.deconfigured = TRUE; usbUpdateChargeCurrent(); usbSetLowPowerMode(theSink.usb.config.deconfigured_timeout); } break; } case MESSAGE_USB_ALT_INTERFACE: { uint16 interface_id; MessageUsbAltInterface* ind = (MessageUsbAltInterface*)message; USB_DEBUG(("MESSAGE_USB_ALT_INTERFACE %d %d\n", ind->interface, ind->altsetting)); UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_MIC_INTERFACE_ID, &interface_id); if(interface_id == ind->interface) { theSink.usb.mic_active = (ind->altsetting ? TRUE : FALSE); USB_DEBUG(("USB: Mic ID %d active %d\n", interface_id, theSink.usb.mic_active)); } UsbDeviceClassGetValue(USB_DEVICE_CLASS_GET_SPEAKER_INTERFACE_ID, &interface_id); if(interface_id == ind->interface) { theSink.usb.spkr_active = (ind->altsetting ? TRUE : FALSE); USB_DEBUG(("USB: Speaker ID %d active %d\n", interface_id, theSink.usb.spkr_active)); } #ifdef ENABLE_USB_AUDIO /* check for changes in required audio routing */ USB_DEBUG(("USB: MESSAGE_USB_ALT_INTERFACE checkAudioRouting\n")); MessageCancelFirst(&theSink.task, EventCheckAudioRouting); MessageSendLater(&theSink.task, EventCheckAudioRouting, 0, USB_AUDIO_DISCONNECT_DELAY); #endif break; } case USB_DEVICE_CLASS_MSG_AUDIO_LEVELS_IND: { USB_DEBUG(("USB_DEVICE_CLASS_MSG_AUDIO_LEVELS_IND\n")); usbAudioSetVolume(); break; } default: { USB_DEBUG(("Unhandled USB message 0x%x\n", id)); break; } } }
/**************************************************************************** NAME profileSlcConnectComplete DESCRIPTION A connect attempt to a certain device has completed. */ void profileSlcConnectComplete (devInstanceTaskData *inst, bool status) { DEBUG_CONN(("profileSlcConnectComplete status=%u\n", !status)); if (profileSlcCheckPoweredOff(inst)) return; if (!status) { /* Failed to connect to any profiles */ the_app->disconnect_requested = FALSE; inst->responding_profiles = ProfileNone; switch ( the_app->app_state ) { case AppStateInquiring: case AppStateSearching: { /* if already inquiring or searching then take no action */ break; } default: { if (the_app->inquiring) { if (profileSlcAreAllDevicesDisconnected()) scanMakeDiscoverable(); setAppState(AppStateIdle); kickCommAction(CommActionInquire); } else { setAppState(AppStateIdle); scanMakeConnectable(); if ( the_app->auto_connect_in_progress ) { { /* Failed to automatically connect to devices */ the_app->auto_connect_in_progress = FALSE; eventHandleCancelCommAction(); a2dpStreamRestartAudioStream(); } } else { eventHandleCancelCommAction(); a2dpStreamRestartAudioStream(); } } } } } else { /* Successfully connected to one or more available profiles */ inst->available_profiles_connected = TRUE; if (getNumberDevicesConnected() >= MAX_NUM_DEV_CONNECTIONS) scanMakeUnconnectable(); MessageSendLater(&inst->task, APP_REFRESH_ENCRYPTION_REQ, 0, D_MIN(EPR_TIMEOUT)); switch ( the_app->app_state ) { case AppStateStreaming: case AppStateInCall: { eventHandleCancelCommAction(); /* fall through */ } case AppStateIdle: case AppStateConnecting: { setAppState(AppStateIdle); scanStopAppInquiryTimer(); if ( the_app->auto_connect_in_progress ) { the_app->auto_connect_in_progress = FALSE; } if (a2dpSlcIsMediaOpen() && (the_app->audio_streaming_state != StreamingActive)) { /* Ensure an A2dp media channel is opened on connection */ a2dpStreamSetAudioStreamingState(StreamingPending); } if (the_app->voip_call_active) { /* Voip call detected during connection, open a call */ kickCommAction(CommActionCall); } else if (the_app->audio_streaming_state != StreamingInactive) { /* Audio streaming detected during connection, open an audio connection */ kickCommAction(CommActionStream); } break; } default: { DEBUG_CONN((" - IGNORED\n")); break; } } } }
void handleUEMessage( Task task, MessageId id, Message message ) { headsetHfpState lState = stateManagerGetHfpState() ; /* If we do not want the event received to be indicated then set this to FALSE. */ bool lIndicateEvent = TRUE ; if (theHeadset.ProfileLibrariesInitialising) { if (!eventAllowedWhileProfilesInitialising(id)) { EVENTS_DEBUG(("Event 0x%x while profiles initialising - queue\n",id)); MessageSendConditionally(&theHeadset.task, id, 0, &theHeadset.ProfileLibrariesInitialising); return; } } /* Deal with user generated Event specific actions*/ switch ( id ) { /*these are the events that are not user generated and can occur at any time*/ case EventOkBattery: case EventChargerDisconnected: case EventLEDEventComplete: case EventTrickleCharge: case EventFastCharge: case EventLowBattery: case EventPowerOff: case EventLinkLoss: case EventSLCConnected: case EventA2dpConnected: case EventError: case EventChargeError: case EventCancelLedIndication: case EventAutoSwitchOff: case EventHfpReconnectFailed: case EventA2dpReconnectFailed: /*do nothing for these events*/ break ; default: break; } switch (id) { case EventPowerOn: EVENTS_DEBUG(("EventPowerOn\n")); if (!theHeadset.headsetPoweredOn) { theHeadset.headsetPoweredOn = TRUE; theHeadset.a2dp_list_index = 0xf; theHeadset.hfp_list_index = 0xf; theHeadset.switch_a2dp_source = FALSE; stateManagerPowerOn(); if(theHeadset.Timeouts.EncryptionRefreshTimeout_m != 0) MessageSendLater(&theHeadset.task, APP_EVENT_REFRESH_ENCRYPTION, 0, D_MIN(theHeadset.Timeouts.EncryptionRefreshTimeout_m)); theHeadset.PowerOffIsEnabled = TRUE ; } else { lIndicateEvent = FALSE ; } break; case EventPowerOff: EVENTS_DEBUG(("EventPowerOff\n")); if (!theHeadset.PowerOffIsEnabled) { EVENTS_DEBUG(("Power off disabled - ignore event\n")); lIndicateEvent = FALSE ; break; } theHeadset.headsetPoweredOn = FALSE; theHeadset.a2dp_list_index = 0xf; theHeadset.hfp_list_index = 0xf; theHeadset.switch_a2dp_source = FALSE; stateManagerEnterPoweringOffState(); AuthResetConfirmationFlags(); if (theHeadset.gMuted) VolumeMuteOff() ; hfpCallClearQueuedEvent() ; if(theHeadset.Timeouts.EncryptionRefreshTimeout_m != 0) MessageCancelAll ( &theHeadset.task, APP_EVENT_REFRESH_ENCRYPTION) ; MessageCancelAll ( &theHeadset.task , EventPairingFail) ; break; case EventEnterPairing: EVENTS_DEBUG(("EventEnterPairing\n")); stateManagerEnterConnDiscoverableState( ) ; break ; case EventPairingFail: EVENTS_DEBUG(("EventPairingFail\n")); if (lState != headsetTestMode) { stateManagerEnterHfpConnectableState( TRUE) ; } break ; case EventPairingSuccessful: EVENTS_DEBUG(("EventPairingSuccessful\n")); if (lState == headsetConnDiscoverable) { stateManagerEnterHfpConnectableState( FALSE) ; } break ; case EventConfirmationAccept: EVENTS_DEBUG(("EventConfirmationAccept\n")); headsetPairingAcceptRes(); break; case EventConfirmationReject: EVENTS_DEBUG(("EventConfirmationReject\n")); headsetPairingRejectRes(); break; case EventToggleDebugKeys: EVENTS_DEBUG(("EventToggleDebugKeys\n")); /* if debug keys functionality enabled toggle current state */ if (theHeadset.features.debugKeysEnabled) { ConnectionSmSecModeConfig(&theHeadset.task, cl_sm_wae_acl_owner_none, !theHeadset.debugKeysInUse, TRUE); } break; case EventSLCConnected: EVENTS_DEBUG(("EventSLCConnected\n")); hfpCallRecallQueuedEvent() ; break; case EventLinkLoss: EVENTS_DEBUG(("EventLinkLoss\n")); break; case EventSLCDisconnected: EVENTS_DEBUG(("EventSLCDisconnected\n")); if (lState == headsetPoweringOn ) lIndicateEvent = FALSE ; theHeadset.voice_recognition_enabled = FALSE; break; case EventEstablishSLC: EVENTS_DEBUG(("EventEstablishSLC\n")); /* Cancel inquiry and throw away results if one is in progress */ inquiryStop(); if (theHeadset.slcConnectFromPowerOn) { /* This is from power on so carry out the power on connect sequence */ lIndicateEvent = FALSE ; } else { bdaddr bd_addr; /* Try a connection attempt to Last AG. */ if (!hfpSlcConnectBdaddrRequest( hfp_handsfree_profile, &bd_addr ) ) lIndicateEvent = FALSE ; } break; case EventHfpReconnectFailed: EVENTS_DEBUG(("EventHfpReconnectFailed\n")); break; case EventA2dpReconnectFailed: EVENTS_DEBUG(("EventA2dpReconnectFailed\n")); break; case EventInitateVoiceDial: EVENTS_DEBUG(("EventInitateVoiceDial [%d]\n", theHeadset.voice_recognition_enabled )) ; /* Toggle the voice dial behaviour depending on whether we are currently active */ if (theHeadset.voice_recognition_enabled) { hfpCallCancelVoiceDial() ; lIndicateEvent = FALSE ; } else { if (!hfpCallInitiateVoiceDial()) lIndicateEvent = FALSE ; } break ; case EventLastNumberRedial: if (theHeadset.features.LNRCancelsVoiceDialIfActive) { if (theHeadset.voice_recognition_enabled) { MessageSend(&theHeadset.task, EventInitateVoiceDial, 0); lIndicateEvent = FALSE ; break; } } EVENTS_DEBUG(("EventLastNumberRedial\n" )) ; if (!hfpCallInitiateLNR()) lIndicateEvent = FALSE ; break ; case EventAnswer: EVENTS_DEBUG(("EventAnswer\n" )) ; /* Call the HFP lib function, this will determine the AT cmd to send depending on whether the profile instance is HSP or HFP compliant. */ hfpCallAnswer(); break ; case EventReject: EVENTS_DEBUG(("EventReject\n" )) ; /* Reject incoming call - only valid for instances of HFP. */ hfpCallReject(); break ; case EventCancelEnd: if (theHeadset.features.EndCallWithNoSCOtransfersAudio && !HfpGetAudioSink(theHeadset.hfp_hsp)) { lIndicateEvent = FALSE; MessageSend(&theHeadset.task, EventTransferToggle, 0); } else { EVENTS_DEBUG(("EventCancelEnd\n" )) ; /* Terminate the current ongoing call process */ hfpCallHangUp(); } break ; case EventTransferToggle : EVENTS_DEBUG(("EventTransferToggle\n")) ; hfpCallTransferToggle() ; break ; case EventSCOLinkOpen : EVENTS_DEBUG(("EventScoLinkOpen\n")) ; break ; case EventSCOLinkClose: EVENTS_DEBUG(("EventScoLinkClose\n")) ; break ; case EventResetPairedDeviceList: EVENTS_DEBUG(("EventResetPairedDeviceList\n")) ; if ( stateManagerIsHfpConnected () ) { /* Then we have an SLC active */ hfpSlcDisconnect(); } if ( stateManagerIsA2dpConnected() ) { a2dpDisconnectRequest(); } configManagerReset() ; break ; case EventToggleMute: EVENTS_DEBUG(("EventToggleMute\n")) ; VolumeToggleMute() ; break ; case EventMuteOn : EVENTS_DEBUG(("EventMuteOn\n")) ; VolumeMuteOn() ; break ; case EventMuteOff: EVENTS_DEBUG(("EventMuteOff\n")) ; VolumeMuteOff() ; break ; case EventMuteReminder : EVENTS_DEBUG(("EventMuteReminder\n")) ; MessageSendLater( &theHeadset.task , EventMuteReminder , 0 ,D_SEC(theHeadset.Timeouts.MuteRemindTime_s ) ) ; break; case EventEnterDutState : EVENTS_DEBUG(("EventEnterDutState\n")) ; stateManagerEnterTestModeState() ; break; case EventEnterDutMode : EVENTS_DEBUG(("EventEnterDutMode\n")) ; if (lState != headsetTestMode) { MessageSend( task , EventEnterDutState, 0 ) ; } ConnectionEnterDutMode(); break; case EventEnterTXContTestMode: EVENTS_DEBUG(("EventEnterTXContTestMode\n")); if (lState != headsetTestMode) { MessageSend( task , EventEnterDutState, 0 ) ; } MessageSendLater( task , APP_TX_TEST_MODE, 0, 1000 ) ; break; case EventResetComplete: EVENTS_DEBUG(("EventResetComplete\n")); break; case EventError: EVENTS_DEBUG(("EventError\n")) ; break; case EventEndOfCall : EVENTS_DEBUG(("EventEndOfCall\n")) ; break; case EventA2dpConnected: EVENTS_DEBUG(("EventA2dpConnected\n")) ; break; case EventA2dpDisconnected: EVENTS_DEBUG(("EventA2dpDisconnected\n")) ; if (lState == headsetPoweringOn ) lIndicateEvent = FALSE ; break; case EventVolumeMax: EVENTS_DEBUG(("EventVolumeMax\n")); break; case EventVolumeMin: EVENTS_DEBUG(("EventVolumeMin\n")); break; case EventPlay: EVENTS_DEBUG(("EventPlay\n")); /* Always indicate play event as will try to connect A2DP if not already connected */ avrcpEventPlay(); break; case EventPause: EVENTS_DEBUG(("EventPause\n")); avrcpEventPause(); break; case EventStop: EVENTS_DEBUG(("EventStop\n")); avrcpEventStop(); break; case EventSkipForward: /* Only indicate event if AVRCP connected */ if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventSkipForward\n")); avrcpEventSkipForward(); } else { lIndicateEvent = FALSE ; } break; case EventSkipBackward: /* Only indicate event if AVRCP connected */ if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventSkipBackward\n")); avrcpEventSkipBackward(); } else { lIndicateEvent = FALSE ; } break; case EventFFWDPress: if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventFFWDPress\n")); avrcpEventFastForwardPress(); } else { lIndicateEvent = FALSE ; } break; case EventFFWDRelease: if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventFFWDRelease\n")); avrcpEventFastForwardRelease(); } else { lIndicateEvent = FALSE ; } break; case EventRWDPress: if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventRWDPress\n")); avrcpEventFastRewindPress(); } else { lIndicateEvent = FALSE ; } break; case EventRWDRelease: if ( stateManagerIsAvrcpConnected() ) { EVENTS_DEBUG(("EventRWDRelease\n")); avrcpEventFastRewindRelease(); } else { lIndicateEvent = FALSE ; } break; case EventEnterDFUMode: EVENTS_DEBUG(("EventEnterDFUMode\n")); BootSetMode(0); break; case EventSwitchA2dpSource: EVENTS_DEBUG(("EventSwitchA2dpSource\n")); a2dpSwitchSource(); break; case EventSwitchAudioMode: EVENTS_DEBUG(("EventSwitchAudioMode\n")); if (theHeadset.eqMode >= eq_mode_passthrough) { theHeadset.eqMode = eq_mode_level1; } else { theHeadset.eqMode++; } if ((theHeadset.dsp_process == dsp_process_a2dp)) { /* Set audio mode for A2DP only (not used for Faststream) */ AudioSetMode(theHeadset.eqMode, 0); } break; case EventToggleLEDS: EVENTS_DEBUG(("EventToggleLEDS\n")); #ifdef ROM_LEDS LedManagerToggleLEDS(); #endif break; /* threeway calling events */ case EventThreeWayReleaseAllHeld: EVENTS_DEBUG(("EventThreeWayReleaseAllHeld\n")); HfpMultipleCallsReleaseHeldOrRejectWaiting(theHeadset.hfp); break; case EventThreeWayAcceptWaitingReleaseActive: EVENTS_DEBUG(("EventThreeWayAcceptWaitingReleaseActive\n")); HfpMultipleCallsReleaseActiveAcceptOther(theHeadset.hfp); break; case EventThreeWayAcceptWaitingHoldActive: EVENTS_DEBUG(("EventThreeWayAcceptWaitingHoldActive\n")); HfpMultipleCallsHoldActiveAcceptOther(theHeadset.hfp); break; case EventThreeWayAddHeldTo3Way: EVENTS_DEBUG(("EventThreeWayAddHeldTo3Way\n")); HfpMultipleCallsAddHeldCall(theHeadset.hfp); break; case EventThreeWayConnect2Disconnect: EVENTS_DEBUG(("EventThreeWayConnect2Disconnect\n")); HfpMultipleCallsExplicitCallTransfer(theHeadset.hfp); break; /* end threeway calling events */ case EventRssiPair: EVENTS_DEBUG(("EventRssiPair\n")); /* start inquiry on this event */ inquiryStart(); break; case EventRssiPairReminder: EVENTS_DEBUG(("EventRssiPairReminder\n")); inquiryReminder(); break; case EventRssiPairTimeout: EVENTS_DEBUG(("EventRssiPairTimeout\n")); /* Stop any pending inquiry now as this pairing mode has timed out */ inquiryStop(); break; default: EVENTS_DEBUG(("UNHANDLED EVENT: 0x%x\n",id)); lIndicateEvent = FALSE ; break; } if ( lIndicateEvent ) { LEDManagerIndicateEvent ( id ) ; } }
void tracer(int itts) { /* This subroutine time steps the tracer concentration. */ /* A positive definite scheme is used. */ double minslope; /* The maximum concentration slope per */ /* grid point consistent with mono- */ /* tonicity, in conc. (nondim.). */ double ***hvol; /* The cell volume of an h-element */ double slope[NXMEM+NYMEM][NTR]; /* The concentration slope per grid */ /* point in units of concentration (nondim.). */ double fluxtr[NXMEM+NYMEM][NTR];/* The flux of tracer across a */ /* boundary, in m3 * conc. (nondim.). */ double ***uhr; /* The remaining zonal and meridional */ double ***vhr; /* thickness fluxes, in m3.*/ double uhh[NXMEM]; /* uhh and vhh are the reduced fluxes */ double vhh[NYMEM]; /* during the current iteration, in m3.d */ double hup, hlos; /* hup is the upwind volume, hlos is the */ /* part of that volume that might be lost */ /* due to advection out the other side of */ /* the grid box, both in m3. */ double ts2; double landvolfill; /* An arbitrary? nonzero cell volume, m3. */ double ***ear; double ***ebr; double ***wdh; double bet[NXMEM]; /* bet and gam are variables used by the */ double gam[NZ][NXMEM]; /* tridiagonal solver. */ double hnew0[NXMEM]; /* The original topmost layer thickness, */ #if defined AGE2 || defined AGE3 // extern double hnew[NZ][NXMEM][NYMEM]; extern double ***hnew; #else double ***hnew; #endif double hlst1, Ihnew; double hlst[NYMEM]; // double MLMIN = EPSILON; /* min depth for ML */ double MLMIN = 4.25; double BLMIN = 0.20; #ifdef ENTRAIN double nts = dt/DT; /* number of timesteps (#day*86400/3600seconds) */ #endif int i, j, k, m, ii, pstage; int itt; double fract1; double fract2; # ifdef WRTTS double wrts; # endif hvol = alloc3d(NZ,NXMEM,NYMEM); if(hvol == NULL) { fprintf(stderr,"not enough memory for hvol!\n"); } uhr = alloc3d(NZ,NXMEM,NYMEM); if(uhr == NULL) { fprintf(stderr,"not enough memory for uhr!\n"); } vhr = alloc3d(NZ,NXMEM,NYMEM); if(vhr == NULL) { fprintf(stderr,"not enough memory for vhr!\n"); } ear = alloc3d(NZ,NXMEM,NYMEM); if(ear == NULL) { fprintf(stderr,"not enough memory for ear!\n"); } ebr = alloc3d(NZ,NXMEM,NYMEM); if(ebr == NULL) { fprintf(stderr,"not enough memory for ebr!\n"); } wdh = alloc3d(NZ,NXMEM,NYMEM); if(wdh == NULL) { fprintf(stderr,"not enough memory for wdh!\n"); } #if !defined AGE2 && !defined AGE3 hnew = alloc3d(NZ,NXMEM,NYMEM); if(hnew == NULL) { fprintf(stderr,"not enough memory for hnew!\n"); } #endif landvolfill = EPSILON*1000000.0; /* This is arbitrary. */ /* zonal re-entrance */ #pragma omp parallel { #pragma omp for private(j,k) for (j=0;j<=NYMEM-1;j++) { for (k=0;k<NZ;k++) { uhtm[k][nx+1][j] = uhtm[k][2][j]; uhtm[k][nx+2][j] = uhtm[k][3][j]; uhtm[k][0][j] = uhtm[k][nx-1][j]; uhtm[k][1][j] = uhtm[k][nx][j]; vhtm[k][nx+1][j] = vhtm[k][2][j]; vhtm[k][nx+2][j] = vhtm[k][3][j]; vhtm[k][0][j] = vhtm[k][nx-1][j]; vhtm[k][1][j] = vhtm[k][nx][j]; } for (k=0;k<NZ+1;k++) { wd[k][nx+1][j] = wd[k][2][j]; wd[k][nx+2][j] = wd[k][3][j]; wd[k][0][j] = wd[k][nx-1][j]; wd[k][1][j] = wd[k][nx][j]; } } /* meridional re-entrance */ #pragma omp for private(i,k,ii) for (i=2;i<=nx;i++) { ii = 363 - i; for (k=0;k<NZ;k++) { uhtm[k][ii][ny+1] = (-1)*uhtm[k][i][ny]; uhtm[k][ii][ny+2] = (-1)*uhtm[k][i][ny-1]; vhtm[k][ii][ny+1] = (-1)*vhtm[k][i][ny]; vhtm[k][ii][ny+2] = (-1)*vhtm[k][i][ny-1]; } for (k=0;k<NZ+1;k++) { wd[k][ii][ny+1] = wd[k][i][ny]; wd[k][ii][ny+2] = wd[k][i][ny-1]; } } #pragma omp for private(i,j,k) for (k=0;k<NZ;k++) { /* Put the thickness fluxes into uhr and vhr. */ for (j=0;j<=ny+2;j++) { for (i=0;i<=nx+2;i++) { uhr[k][i][j] = uhtm[k][i][j]*dt; vhr[k][i][j] = vhtm[k][i][j]*dt; if (h[k][i][j] < EPSILON) { h[k][i][j] = 1.0*EPSILON; } /* This line calculates the cell volume */ hvol[k][i][j] = DXDYh(i,j)*h[k][i][j]; hnew[k][i][j] = h[k][i][j]; } } } /* calculate the diapycnal velocities at the interfaces */ /* if we read in the ea, eb and eaml variables */ /* Otherwise we read in wd directly */ #ifdef ENTRAIN #pragma omp for private(i,j) for (i=X0;i<=nx+1;i++) for (j=Y0;j<=ny;j++) wd[0][i][j] = nts*eaml[i][j]; #pragma omp for private(i,j,k) for (k=1;k<NZ;k++) { for (i=X0;i<=nx+1;i++) for (j=Y0;j<=ny;j++) wd[k][i][j] = nts*(ea[k][i][j] - eb[k-1][i][j]); } #endif } // omp #define STANDARD_ADVECTION //#undef STANDARD_ADVECTION #ifdef STANDARD_ADVECTION /* pstage=1; print_tr(pstage); */ /* beginning of itt loop */ for (itt = 0; itt < NUM_ADV_ITER; itt++) { /* big loop over k */ //ompfail #pragma omp parallel { #pragma omp for private(i,j,k,m,minslope,slope,uhh,vhh,fluxtr,hup,hlos,ts2,hlst,hlst1,Ihnew) for (k=0;k<NZ;k++) { /* To insure positive definiteness of the thickness at each */ /* iteration, the mass fluxes out of each layer are checked each */ /* time. This may not be very efficient, but it should be reliable. */ /* ============================================================ */ /* first advect zonally */ /* ============================================================ */ #ifndef ADV1D for (j=Y1;j<=ny;j++) { /* Calculate the i-direction profiles (slopes) of each tracer that */ /* is being advected. */ //#pragma omp for private(i,m,minslope) for (i=X0;i<=nx+1;i++) { for (m=0;m<NTR;m++) { minslope = 4.0*((fabs(tr[m][k][i+1][j]-tr[m][k][i][j]) < fabs(tr[m][k][i][j]-tr[m][k][i-1][j])) ? (tr[m][k][i+1][j]-tr[m][k][i][j]) : (tr[m][k][i][j]-tr[m][k][i-1][j])); slope[i][m] = umask[i][j]*umask[i-1][j] * (((tr[m][k][i+1][j]-tr[m][k][i][j]) * (tr[m][k][i][j]-tr[m][k][i-1][j]) < 0.0) ? 0.0 : ((fabs(tr[m][k][i+1][j]-tr[m][k][i-1][j])<fabs(minslope)) ? 0.5*(tr[m][k][i+1][j]-tr[m][k][i-1][j]) : 0.5*minslope)); } } //#pragma omp barrier /* Calculate the i-direction fluxes of each tracer, using as much */ /* the minimum of the remaining mass flux (uhr) and the half the mass */ /* in the cell plus whatever part of its half of the mass flux that */ /* the flux through the other side does not require. */ //#pragma omp for private(i,m,hup,hlos,ts2) for (i=X0;i<=nx;i++) { if (uhr[k][i][j] == 0.0) { uhh[i] = 0.0; for (m=0;m<NTR;m++) fluxtr[i][m] = 0.0; } else if (uhr[k][i][j] < 0.0) { if (k==0 || k==1 ) { hup = (hvol[k][i+1][j]-DXDYh(i+1,j)*MLMIN); } else { hup = (hvol[k][i+1][j]-DXDYh(i+1,j)*EPSILON); } hlos = D_MAX(0.0,uhr[k][i+1][j]); if (((hup + uhr[k][i][j] - hlos) < 0.0) && ((0.5*hup + uhr[k][i][j]) < 0.0)) { uhh[i] = D_MIN(-0.5*hup,-hup+hlos); } else uhh[i] = uhr[k][i][j]; ts2 = 0.5*(1.0 + uhh[i]/hvol[k][i+1][j]); for (m=0;m<NTR;m++) { fluxtr[i][m] = uhh[i]*(tr[m][k][i+1][j] - slope[i+1][m]*ts2); } } else { if (k==0 || k==1 ) { hup = (hvol[k][i][j]-DXDYh(i,j)*MLMIN); } else { hup = (hvol[k][i][j]-DXDYh(i,j)*EPSILON); } hlos = D_MAX(0.0,-uhr[k][i-1][j]); if (((hup - uhr[k][i][j] - hlos) < 0.0) && ((0.5*hup - uhr[k][i][j]) < 0.0)) { uhh[i] = D_MAX(0.5*hup,hup-hlos); } else uhh[i] = uhr[k][i][j]; ts2 = 0.5*(1.0 - uhh[i]/hvol[k][i][j]); for (m=0;m<NTR;m++) { fluxtr[i][m] = uhh[i]*(tr[m][k][i][j] + slope[i][m]*ts2); } } } //#pragma omp barrier /* Calculate new tracer concentration in each cell after accounting */ /* for the i-direction fluxes. */ uhr[k][X0][j] -= uhh[X0]; // #pragma omp barrier //#pragma omp for private(i,m,hlst1,Ihnew) for (i=X1;i<=nx;i++) { if ((uhh[i] != 0.0) || (uhh[i-1] != 0.0)) { uhr[k][i][j] -= uhh[i]; hlst1 = hvol[k][i][j]; hvol[k][i][j] -= (uhh[i] - uhh[i-1]); Ihnew = 1.0 / hvol[k][i][j]; for (m=0;m<NTR;m++) { tr[m][k][i][j] *= hlst1; tr[m][k][i][j] = (tr[m][k][i][j] - (fluxtr[i][m]-fluxtr[i-1][m])) * Ihnew; } } } // #pragma omp barrier } /* j loop */ #endif /* ============================================================ */ /* now advect meridionally */ /* ============================================================ */ #ifndef ADV1D for (i=X1;i<=nx;i++) { /* Calculate the j-direction profiles (slopes) of each tracer that */ /* is being advected. */ //#pragma omp for private(j,m,minslope) for (j=Y0;j<=ny+1;j++) { for (m=0;m<NTR;m++) { minslope = 4.0*((fabs(tr[m][k][i][j+1]-tr[m][k][i][j]) < fabs(tr[m][k][i][j]-tr[m][k][i][j-1])) ? (tr[m][k][i][j+1]-tr[m][k][i][j]) : (tr[m][k][i][j]-tr[m][k][i][j-1])); slope[j][m] = vmask[i][j] * vmask[i][j-1] * (((tr[m][k][i][j+1]-tr[m][k][i][j]) * (tr[m][k][i][j]-tr[m][k][i][j-1]) < 0.0) ? 0.0 : ((fabs(tr[m][k][i][j+1]-tr[m][k][i][j-1])<fabs(minslope)) ? 0.5*(tr[m][k][i][j+1]-tr[m][k][i][j-1]) : 0.5*minslope)); } } // #pragma omp barrier /* Calculate the j-direction fluxes of each tracer, using as much */ /* the minimum of the remaining mass flux (vhr) and the half the mass */ /* in the cell plus whatever part of its half of the mass flux that */ /* the flux through the other side does not require. */ //#pragma omp for private(j,m,hup,hlos,ts2) for (j=Y0;j<=ny;j++) { if (vhr[k][i][j] == 0.0) { vhh[j] = 0.0; for (m=0;m<NTR;m++) fluxtr[j][m] = 0.0; } else if (vhr[k][i][j] < 0.0) { if (k==0 || k==1 ) { hup = (hvol[k][i][j+1]-DXDYh(i,j+1)*MLMIN); } else { hup = (hvol[k][i][j+1]-DXDYh(i,j+1)*EPSILON); } hlos = D_MAX(0.0,vhr[k][i][j+1]); if (((hup + vhr[k][i][j] - hlos) < 0.0) && ((0.5*hup + vhr[k][i][j]) < 0.0)) { vhh[j] = D_MIN(-0.5*hup,-hup+hlos); } else vhh[j] = vhr[k][i][j]; ts2 = 0.5*(1.0 + vhh[j]/(hvol[k][i][j+1])); for (m=0;m<NTR;m++) { fluxtr[j][m] = vhh[j]*(tr[m][k][i][j+1] - slope[j+1][m]*ts2); } } else { if (k==0 || k==1 ) { hup = (hvol[k][i][j]-DXDYh(i,j)*MLMIN); } else { hup = (hvol[k][i][j]-DXDYh(i,j)*EPSILON); } hlos = D_MAX(0.0,-vhr[k][i][j-1]); if (((hup - vhr[k][i][j] - hlos) < 0.0) && ((0.5*hup - vhr[k][i][j]) < 0.0)) { vhh[j] = D_MAX(0.5*hup,hup-hlos); } else vhh[j] = vhr[k][i][j]; ts2 = 0.5*(1.0 - vhh[j] / (hvol[k][i][j])); for (m=0;m<NTR;m++) { fluxtr[j][m] = vhh[j]*(tr[m][k][i][j] + slope[j][m]*ts2); } } } // #pragma omp barrier /* Calculate new tracer concentration in each cell after accounting */ /* for the j-direction fluxes. */ vhr[k][i][Y0] -= vhh[Y0]; // #pragma omp barrier //#pragma omp for private(j,m,Ihnew) for (j=Y1;j<=ny;j++) { if ((vhh[j] != 0.0) || (vhh[j-1] != 0.0)) { hlst[j] = hvol[k][i][j]; hvol[k][i][j] -= (vhh[j] - vhh[j-1]); Ihnew = 1.0 / hvol[k][i][j]; vhr[k][i][j] -= vhh[j]; for (m=0;m<NTR;m++) { tr[m][k][i][j] *= hlst[j]; tr[m][k][i][j] = (tr[m][k][i][j] - fluxtr[j][m] + fluxtr[j-1][m]) * Ihnew; } } } // #pragma omp barrier } /* i loop */ #endif } /* end of big loop over k */ /* calculate new thickness field - to be used for vertical */ /* tracer advection from updated volumes (vol + fluxes) */ #pragma omp for private(i,j,k) for (k=0; k<=NZ-1; k++) { for (i=X1; i<=nx; i++) { for (j=Y1; j<=ny; j++) { hnew[k][i][j] = hvol[k][i][j]/DXDYh(i,j); if (hnew[k][i][j] < EPSILON) { hnew[k][i][j] = EPSILON; } } } } /* ============================================================ */ /* now advect vertically */ /* ============================================================ */ #pragma omp for private(i,j,hup,hlos) for (j=Y1; j<=ny; j++) { for (i=X1; i<=nx; i++) { /* work from top to bottom - by interfaces - interface k is the */ /* interface between layer k and layer k-1. net flux at this */ /* interface is wd[[k][i][j]= ea[k][i][j] and eb[k-1][i][j] */ /* k=0 */ if (wd[0][i][j] == 0.0) { wdh[0][i][j] = 0.0; } else if (wd[0][i][j] < 0.0) { hup = hnew[0][i][j] - MLMIN; hlos = D_MAX(0.0, wd[1][i][j]); if (((hup + wd[0][i][j] - hlos) < 0.0) && ((0.5*hup + wd[0][i][j]) < 0.0)) { wdh[0][i][j] = D_MIN(-0.5*hup,-hup+hlos); } else wdh[0][i][j] = wd[0][i][j]; } else { wdh[0][i][j] = wd[0][i][j]; } } } #pragma omp for private(i,j,hup,hlos) for (j=Y1; j<=ny; j++) { for (i=X1; i<=nx; i++) { /* k=1 */ if (wd[1][i][j] == 0.0) { wdh[1][i][j] = 0.0; } else if (wd[1][i][j] > 0.0) { hup = hnew[0][i][j] - MLMIN; hlos = D_MAX(0.0, -wd[0][i][j]); if (((hup - wd[1][i][j] - hlos) < 0.0) && ((0.5*hup - wd[1][i][j]) < 0.0)) { wdh[1][i][j] = D_MAX(0.5*hup,hup-hlos); } else wdh[1][i][j] = wd[1][i][j]; } else { hup = hnew[1][i][j] - MLMIN; hlos = D_MAX(0.0,wd[2][i][j]); if (((hup + wd[1][i][j] - hlos) < 0.0) && ((0.5*hup + wd[1][i][j]) < 0.0)) { wdh[1][i][j] = D_MIN(-0.5*hup,-hup+hlos); } else wdh[1][i][j] = wd[1][i][j]; } } } #pragma omp for private(i,j,hup,hlos) for (j=Y1; j<=ny; j++) { for (i=X1; i<=nx; i++) { /* k=2 */ if (wd[2][i][j] == 0.0) { wdh[2][i][j] = 0.0; } else if (wd[2][i][j] > 0.0) { hup = hnew[1][i][j] - MLMIN; hlos = D_MAX(0.0, -wd[1][i][j]); if (((hup - wd[2][i][j] - hlos) < 0.0) && ((0.5*hup - wd[2][i][j]) < 0.0)) { wdh[2][i][j] = D_MAX(0.5*hup,hup-hlos); } else wdh[2][i][j] = wd[2][i][j]; } else { hup = hnew[2][i][j] - EPSILON; hlos = D_MAX(0.0,wd[3][i][j]); if (((hup + wd[2][i][j] - hlos) < 0.0) && ((0.5*hup + wd[2][i][j]) < 0.0)) { wdh[2][i][j] = D_MIN(-0.5*hup,-hup+hlos); } else wdh[2][i][j] = wd[2][i][j]; } } } /* k=3 --> NZ-1 */ #pragma omp for private(i,j,k,hup,hlos) for (k=3; k<=NZ-1; k++) { for (j=Y1; j<=ny; j++) { for (i=X1; i<=nx; i++) { if (wd[k][i][j] == 0.0) { wdh[k][i][j] = 0.0; } else if (wd[k][i][j] > 0.0) { hup = hnew[k-1][i][j] - EPSILON; hlos = D_MAX(0.0, -wd[k-1][i][j]); if (((hup - wd[k][i][j] - hlos) < 0.0) && ((0.5*hup - wd[k][i][j]) < 0.0)) { wdh[k][i][j] = D_MAX(0.5*hup,hup-hlos); } else wdh[k][i][j] = wd[k][i][j]; } else { hup = hnew[k][i][j] - EPSILON; if (k != NZ-1) { hlos = D_MAX(0.0,wd[k+1][i][j]); } else { hlos = 0.0; } if (((hup + wd[k][i][j] - hlos) < 0.0) && ((0.5*hup + wd[k][i][j]) < 0.0)) { wdh[k][i][j] = D_MIN(-0.5*hup,-hup+hlos); } else wdh[k][i][j] = wd[k][i][j]; } } /* k */ } /* j */ } /* i */ #pragma omp for private(i,j) for (i=X1; i<=nx; i++) for (j=Y1; j<=ny; j++) { ear[0][i][j] = wdh[0][i][j]; /* added by Curtis - bottom ebr wasn't set anywhere else */ ebr[NZ-1][i][j] = 0; } #pragma omp for private(i,j,k) for (k=1;k<=NZ-1;k++) { for (i=X1; i<=nx; i++) { for (j=Y1; j<=ny; j++) { ear[k][i][j] = 0.5 * (fabs(wdh[k][i][j]) + wdh[k][i][j]); ebr[k-1][i][j] = 0.5 * (fabs(wdh[k][i][j]) - wdh[k][i][j]); } } } #pragma omp for private(i,j,k,m,hnew0,bet,gam) for (j=Y1; j<=ny; j++) { for (i=X1; i<=nx; i++) { hnew0[i] = hnew[0][i][j]; bet[i]=1.0/(hnew[0][i][j] + ebr[0][i][j] + wdh[0][i][j]); for (m=0;m<NTR;m++) tr[m][0][i][j] = bet[i]*(hnew0[i]*tr[m][0][i][j]); } for (k=1;k<=NZ-1;k++) { for (i=X1;i<=nx;i++) { gam[k][i] = ebr[k-1][i][j] * bet[i]; bet[i]=1.0/(hnew[k][i][j] + ebr[k][i][j] + (1.0-gam[k][i])*ear[k][i][j]); for (m=0;m<NTR;m++) tr[m][k][i][j] = bet[i] * (hnew[k][i][j]*tr[m][k][i][j] + ear[k][i][j]*(tr[m][k-1][i][j]) ); } } for (m=0;m<NTR;m++) for (k=NZ-2;k>=0;k--) { for (i=X1;i<=nx;i++) { tr[m][k][i][j] += gam[k+1][i]*tr[m][k+1][i][j]; } } } /*j*/ /* update hvol with diapycnal fluxes */ #pragma omp for private(i,j,k) for (k=0;k<NZ-1;k++) { for (i=X1; i<=nx; i++) for (j=Y1; j<=ny; j++) hnew[k][i][j] += (wdh[k][i][j] - wdh[k+1][i][j]); } #pragma omp for private(i,j) for (i=X1; i<=nx; i++) for (j=Y1; j<=ny; j++) hnew[NZ-1][i][j] += wdh[NZ-1][i][j]; #pragma omp for private(i,j,k) for (k=0;k<=NZ-1;k++) for (i=X1; i<=nx; i++) for (j=Y1; j<=ny; j++) { if (hnew[k][i][j] < EPSILON) hnew[k][i][j] = EPSILON; hvol[k][i][j] = DXDYh(i,j)*hnew[k][i][j]; if ( wd[k][i][j] > 0.0 && ( wdh[k][i][j] > wd[k][i][j] )) printf("case 1 wdh[k]\n"); else if ( wd[k][i][j] < 0.0 && ( wdh[k][i][j] < wd[k][i][j] )) printf("case 2 wdh[k]\n"); wd[k][i][j] -= wdh[k][i][j]; } #else /* STANDARD_ADVECTION */ /* big loop over k */ // printf("phos(%d,%d,%d)=%g,uhtm=%g\n",0,190,26,tr[mPHOSPHATE][0][190][26], // uhtm[0][190][26]); // exit(1); //yanxu: note these are null cycles, so I comment them out //yanxu for (k=0;k<NZ;k++) { // first advect zonally //yanxu for (j=Y1;j<=ny;j++) { //yanxu for (i=X0;i<=nx+1;i++) { //yanxu for (m=0;m<NTR;m++) { // fluxtr[i][m] = uhtm[i]*(tr[m][k][i][j]); //yanxu } //yanxu } //yanxu } // now advect meridionally // null cycles again, yanxu //yanxu for (i=X1;i<=nx;i++) { //yanxu } //yanxu } /* end of big loop over k */ /* calculate new thickness field - to be used for vertical */ /* tracer advection from updated volumes (vol + fluxes) */ #pragma omp for private(i,j,k) for (k=0; k<=NZ-1; k++) for (i=X1; i<=nx; i++) for (j=Y1; j<=ny; j++) { hnew[k][i][j] = hvol[k][i][j]/DXDYh(i,j); if (hnew[k][i][j] < EPSILON) hnew[k][i][j] = EPSILON; } // now advect vertically //yanxu: null cycles //yanxu for (j=Y1; j<=ny; j++) { //yanxu for (i=X1; i<=nx; i++) { //yanxu //yanxu } //yanxu } #endif /* STANDARD_ADVECTION */ /* zonal re-entrance */ #pragma omp for private(j,k,m) for (j=0;j<NYMEM;j++) { for (k=0;k<NZ;k++) { uhr[k][nx+1][j] = uhr[k][2][j]; uhr[k][nx+2][j] = uhr[k][3][j]; uhr[k][0][j] = uhr[k][nx-1][j]; uhr[k][1][j] = uhr[k][nx][j]; vhr[k][nx+1][j] = vhr[k][2][j]; vhr[k][nx+2][j] = vhr[k][3][j]; vhr[k][0][j] = vhr[k][nx-1][j]; vhr[k][1][j] = vhr[k][nx][j]; hvol[k][nx+1][j] = hvol[k][2][j]; hvol[k][nx+2][j] = hvol[k][3][j]; hvol[k][0][j] = hvol[k][nx-1][j]; hvol[k][1][j] = hvol[k][nx][j]; for (m=0;m<NTR;m++) { tr[m][k][nx+1][j] = tr[m][k][2][j]; tr[m][k][nx+2][j] = tr[m][k][3][j]; tr[m][k][0][j] = tr[m][k][nx-1][j]; tr[m][k][1][j] = tr[m][k][nx][j]; } } } /* meridional re-entrance */ /* meridional re-entrance */ #pragma omp for private(i,k,ii,m) for (i=2;i<=nx;i++) { ii = 363 - i; for (k=0;k<NZ;k++) { uhr[k][ii][ny+1] = (-1)*uhr[k][i][ny]; uhr[k][ii][ny+2] = (-1)*uhr[k][i][ny-1]; vhr[k][ii][ny+1] = (-1)*vhr[k][i][ny]; vhr[k][ii][ny+2] = (-1)*vhr[k][i][ny-1]; hvol[k][ii][ny+1] = hvol[k][i][ny]; hvol[k][ii][ny+2] = hvol[k][i][ny-1]; for (m=0;m<NTR;m++) { tr[m][k][ii][ny+1] = tr[m][k][i][ny]; tr[m][k][ii][ny+2] = tr[m][k][i][ny-1]; } } } } // omp #ifdef STANDARD_ADVECTION # ifdef WRTTS printf("itt = %i\n",itt); wrts = (double)(itts)+(double)(itt)/11.+0.0001; write_ts(wrts); # endif // WRTTS //**************************************************************************************** } /* end of temp itt iteration loop */ //**************************************************************************************** #endif fract1 = (double)(NTSTEP-itts) / (double)NTSTEP; fract2 = 1.0 - fract1; //#pragma omp parallel for private(i,j,k) schedule(dynamic) for (k=0;k<=NZ-1;k++) { for (i=X1; i<=nx; i++) { for (j=Y1; j<=ny; j++) { # ifdef USE_CALC_H h[k][i][j] = hnew[k][i][j]; if (h[k][i][j] < 0.0) printf("tracadv l 796 - h[%d][%d][%d] = %g\n", k,i,j, h[k][i][j]); # else h[k][i][j] = fract1*hstart[k][i][j] + fract2*hend[k][i][j]; //BX h[k][i][j] = hend[k][i][j]; # endif #ifdef HTEST htest[k][i][j] = hnew[k][i][j]; printf("htest(%d,%d,%d)=%g,hend=%g\n", k,i,j, // htest[k][i][j] = h[k][i][j]; #endif } } } //HF // zonal re-entrance //#pragma omp parallel for private(j,k) schedule(dynamic) for (k=0;k<NZ;k++) { for (j=0;j<=NYMEM-1;j++) { h[k][nx+1][j] = h[k][2][j]; h[k][nx+2][j] = h[k][3][j]; h[k][0][j] = h[k][nx-1][j]; h[k][1][j] = h[k][nx][j]; } } // meridional re-entrance //#pragma omp parallel for private(i,k,ii) schedule(dynamic) for (i=2;i<=nx;i++) { ii = 363 - i; for (k=0;k<NZ;k++) { h[k][ii][ny+1] = h[k][i][ny]; h[k][ii][ny+2] = h[k][i][ny-1]; } } //HF-e # ifdef WRTTS printf("End of tracadv\n"); wrts = (double)(itts)+(double)(itt)/11.+0.0005; write_ts(wrts); # endif // WRTTS #ifdef DIFFUSE_TRACER if ((KD>0.0) || (KDML>0.0)) { diffuse_tracer(); } #endif pstage=4; print_tr(pstage); if ((KHTR>0.0)) { tracer_hordiff(); } pstage=5; print_tr(pstage); free3d(hvol, NZ); free3d(uhr, NZ); free3d(vhr, NZ); free3d(ear, NZ); free3d(ebr, NZ); free3d(wdh, NZ); #if !defined AGE2 && !defined AGE3 free3d(hnew, NZ); #endif }