!/===========================================================================/ ! Copyright (c) 2007, The University of Massachusetts Dartmouth ! Produced at the School of Marine Science & Technology ! Marine Ecosystem Dynamics Modeling group ! All rights reserved. ! ! FVCOM has been developed by the joint UMASSD-WHOI research team. For ! details of authorship and attribution of credit please see the FVCOM ! technical manual or contact the MEDM group. ! ! ! This file is part of FVCOM. For details, see http://fvcom.smast.umassd.edu ! The full copyright notice is contained in the file COPYRIGHT located in the ! root directory of the FVCOM code. This original header must be maintained ! in all distributed versions. ! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ! THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ! PURPOSE ARE DISCLAIMED. ! !/---------------------------------------------------------------------------/ ! CVS VERSION INFORMATION ! $Id$ ! $Name$ ! $Revision$ !/===========================================================================/ MODULE MOD_MEANFLOW USE ALL_VARS # if defined (MULTIPROCESSOR) USE MOD_PAR # endif USE MOD_PREC USE MOD_TYPES IMPLICIT NONE SAVE INTEGER :: MF_RST_STCNT INTEGER :: INMF,INTCELL,INTNODE,INTELEL,INTUV INTEGER :: nmfcell_GL, nmfcell, nmfcell_i INTEGER, ALLOCATABLE :: MF_GL2LOC(:) INTEGER, ALLOCATABLE :: I_MFCELL_GL(:),I_MFCELL_N(:) REAL(SP),ALLOCATABLE :: DMFQDIS(:,:),MFQDIS(:),MFDIST(:,:) REAL(SP),ALLOCATABLE :: ANGLEMF(:),MFAREA(:),VLCTYMF(:) TYPE(BC) :: MF_TM !!TIME MAP FOR MEAN FLOW DATA REAL(SP),ALLOCATABLE :: RDISMF(:,:) INTEGER ,ALLOCATABLE :: NODE_MFCELL(:,:) CONTAINS ! we still need to consider the case in which MEAN FLOW bring in/take out T & S !==============================================================================| ! READ IN MEAN FLOW OPEN BOUNDARY FLUX (m^3/s^1) TIME SERIES | !==============================================================================| SUBROUTINE READ_MEANFLOW !------------------------------------------------------------------------------! INTEGER :: k,i,j,i1,i2,i3,ii,NCNT,itemp,IERR INTEGER, ALLOCATABLE :: temp1(:),temp2(:) REAL(SP),ALLOCATABLE :: RTEMP1(:,:),RTEMP2(:,:) REAL(SP) :: ttemp REWIND(INMF) READ(INMF,*) nmfcell_GL nmfcell_i = 0 nmfcell = 0 IF (nmfcell_GL > 0) THEN ALLOCATE(I_MFCELL_GL(nmfcell_GL)) DO I=1,nmfcell_GL READ(INMF,*)I_MFCELL_GL(I) ENDDO !----Read in Mean Flow Flux Vertical Distribution--------------------- ALLOCATE(RTEMP1(nmfcell_GL,KBM1)) DO I = 1, nmfcell_GL READ(INMF,*) J,(RTEMP1(I,K),K = 1,KBM1) END DO !----Read in Time Dependent DataSets --------------------------------- READ(INMF,*) itemp MF_TM%NTIMES = itemp MF_TM%LABEL = "open boundary mean flow flux" ALLOCATE(MF_TM%TIMES(itemp)) ALLOCATE(RTEMP2(nmfcell_GL,itemp)) DO I = 1, itemp READ(INMF,*) ttemp MF_TM%TIMES(I) = ttemp READ(INMF,*) (RTEMP2(J,I),J = 1,nmfcell_GL) !--------------------------------Jianzhong---------------------------- IF(MSR)WRITE(IPT,*)MAXVAL(RTEMP2(1:NMFCELL_GL,I))& &,MAXLOC(RTEMP2(1:NMFCELL_GL,I)) ,MINVAL(RTEMP2(1:NMFCELL_GL,I))& &,MINLOC(RTEMP2(1:NMFCELL_GL,I)) !--------------------------------------------------------------------- ! WRITE(IOPRT,*) ttemp ! WRITE(IOPRT,*) (RTEMP2(J,I),J = 1,nmfcell_GL) END DO CLOSE(INMF) ! !---Map to Local Domain---------------------------------------- IF(SERIAL)THEN nmfcell_i = nmfcell_GL nmfcell = nmfcell_GL ALLOCATE(I_MFCELL_N(nmfcell)) I_MFCELL_N = I_MFCELL_GL ALLOCATE(MFDIST(nmfcell,kbm1)) MFDIST = RTEMP1 ALLOCATE(DMFQDIS(nmfcell,MF_TM%NTIMES)) DMFQDIS = RTEMP2 END IF # if defined (MULTIPROCESSOR) IF(PAR)THEN ALLOCATE(TEMP1(nmfcell_GL)) ALLOCATE(TEMP2(nmfcell_GL)) NCNT = 0 DO I=1,nmfcell_GL ! I1=ELID_X(I_MFCELL_GL(I)) I1=ELID(I_MFCELL_GL(I)) IF(I1 /= 0)THEN NCNT = NCNT + 1 TEMP1(NCNT) = I1 TEMP2(NCNT) = I END IF END DO nmfcell_i = NCNT DO I=1,nmfcell_GL I1=ELID_X(I_MFCELL_GL(I)) I2=ELID(I_MFCELL_GL(I)) IF(I1 /= 0 .and. I1 /= I2)THEN NCNT = NCNT + 1 TEMP1(NCNT) = I1 TEMP2(NCNT) = I END IF END DO nmfcell = NCNT IF(nmfcell > 0)THEN ALLOCATE(I_MFCELL_N(nmfcell),MF_GL2LOC(nmfcell)) I_MFCELL_N(1:nmfcell) = TEMP1(1:nmfcell) MF_GL2LOC (1:nmfcell) = TEMP2(1:nmfcell) END IF ! do i = 1,nmfcell ! write(ipt_p,*)I_MFCELL_N(I), MF_GL2LOC(I) ! end do DEALLOCATE(TEMP1,TEMP2) IF(nmfcell > 0)THEN ALLOCATE(MFDIST(nmfcell,kbm1)) DO I=1,nmfcell DO K=1,KBM1 MFDIST(I,K) = RTEMP1(MF_GL2LOC(I),K) END DO END DO ALLOCATE(DMFQDIS(nmfcell,MF_TM%NTIMES)) DO I=1,MF_TM%NTIMES DMFQDIS(1:nmfcell,I)=RTEMP2(MF_GL2LOC(1:nmfcell),I) END DO END IF END IF # endif DEALLOCATE(RTEMP1,RTEMP2) ELSE ! if statement end for nmfcell_GL > 0 close(INMF) END IF # if defined (MULTIPROCESSOR) IF(PAR)CALL MPI_BARRIER(MPI_FVCOM_GROUP,IERR) # endif !--------------------------------------Jianzhong---------------------- WRITE(IPT,*)'NMFCELL_I=',NMFCELL_I,'NMFCELL=',NMFCELL,'IN THREAD:',MYID !--------------------------------------------------------------------- RETURN END SUBROUTINE READ_MEANFLOW !==============================================================================| !==============================================================================| ! SET METRICS FOR MEAN FLOW BOUNDARY CONDITIONS | !==============================================================================| SUBROUTINE SET_BNDRY_MEANFLOW !------------------------------------------------------------------------------! USE BCS # if defined (SPHERICAL) USE MOD_SPHERICAL # endif USE MOD_OBCS IMPLICIT NONE REAL(DP) DX12,DY12,ATMP1,HTMP INTEGER I,J,I1,I2,J1,J2,II,ITMP,JTMP # if defined (SPHERICAL) REAL(DP) X1_DP,Y1_DP,X2_DP,Y2_DP,SIDE # endif !------------------------------------------------------------------------------! IF(nmfcell > 0)THEN ALLOCATE(ANGLEMF(nmfcell),MFAREA(nmfcell),VLCTYMF(nmfcell),MFQDIS(nmfcell)) ALLOCATE(NODE_MFCELL(nmfcell,2),RDISMF(nmfcell,2)) DO I=1,nmfcell II=I_MFCELL_N(I) IF(I <= nmfcell_i .and. ISBCE(II) /= 2) THEN PRINT*, 'NO.',I,'MEAN FLOW CELL' PRINT*, 'IS NOT A OPEN BOUNDARY ONE' CALL PSTOP END IF ITMP=0 DO J=1,3 IF(NBE(II,J) == 0 .and. ISONB(nv(II,J)) /= 2) THEN JTMP=J ITMP=ITMP+1 END IF END DO IF(ITMP /= 1) THEN PRINT*, 'NO OPEN BOUNDARY OR MORE THAN ONE OPEN BOUNDARY' PRINT*, 'IN NO.',I,'MEAN FLOW CELL' CALL PSTOP END IF J1=JTMP+1-INT((JTMP+1)/4)*3 J2=JTMP+2-INT((JTMP+2)/4)*3 I1=NV(II,J1) I2=NV(II,J2) NODE_MFCELL(I,1)=I1 NODE_MFCELL(I,2)=I2 HTMP=0.5_SP*(H(I1)+H(I2)) ! may be a problem here, should be replaced dy D DY12=VY(I1)-VY(I2) # if defined (SPHERICAL) X1_DP = VX(I2) Y1_DP = VY(I2) X2_DP = VX(I1) Y2_DP = VY(I1) CALL ARCX(X1_DP,Y1_DP,X2_DP,Y2_DP,SIDE) DX12 = SIDE DY12 = TPI*DY12 # else DX12=VX(I1)-VX(I2) # endif ATMP1=ATAN2(DY12,DX12) MFAREA(I)=SQRT(DX12**2+DY12**2)*HTMP ! for spherical coordinates is Phthagolean Theorem still valid? ANGLEMF(I)=ATMP1+3.1415927/2.0 RDISMF(I,1)=ART1(I1)/(ART1(I1)+ART1(I2)) RDISMF(I,2)=ART1(I2)/(ART1(I1)+ART1(I2)) END DO END IF RETURN END SUBROUTINE SET_BNDRY_MEANFLOW !==============================================================================| !==============================================================================| ! INTERPOLATION MEAN FLOW OPEN BOUNDARY FLUX (m^3/s^1) TIME SERIES | !==============================================================================| SUBROUTINE BCOND_MEANFLOW ! !------------------------------------------------------------------------------! USE ALL_VARS USE BCS USE MOD_OBCS INTEGER L1,L2,IERR,II REAL(SP) :: FACT,UFACT REAL(SP) :: THOUR THOUR = DTI*FLOAT(IINT)/3600.0 IF(nmfcell > 0)THEN CALL BRACKET(MF_TM,THOUR,L1,L2,FACT,UFACT,IERR) MFQDIS(:) = UFACT*DMFQDIS(:,L1) + FACT*DMFQDIS(:,L2) MFQDIS = MFQDIS*RAMP END IF RETURN END SUBROUTINE BCOND_MEANFLOW SUBROUTINE BRACKET(TMAP,STIME,L1,L2,FACT,BACT,IERR) !==============================================================================| ! DETERMINE DATA INTERVAL IN WHICH CURRENT TIME LIES | ! | ! L1: DATA INTERVAL PROCEEDING TIME | ! L2: DATA INTERVAL AFTER TIME | ! FACT: LINEAR INTERPOLATION COEFFICIENT (0->1) | ! FACT = .5 : STIME LIES EXACTLY BETWEEN TWO DATA TIMES | ! FACT = 1. : STIME OCCURS AT SECOND DATA TIME | ! BACT = 1.-FACT ! IERR: RETURNS INTEGER ERROR | ! IERR = 0 : NO ERROR, TIME IS BRACKETED BY DATA TIMES | ! IERR =-1 : STIME PROCEEDS ALL DATA TIMES | ! IERR = 1 : STIME IS GREATER THAN ALL DATA TIMES | ! | ! IF STIME PROCEEDS DATA, IERR IS SET TO -1, L1 TO 1, AND FACT TO 0. ! ! IF STIME SUPERCEEDS DATA, IERR IS SET TO -1, L2 TO LMAX, AND FACT TO 1. ! !==============================================================================| USE MOD_TYPES IMPLICIT NONE !------------------------------------------------------------------------------! TYPE(BC), INTENT(IN) :: TMAP REAL(SP), INTENT(IN) :: STIME INTEGER, INTENT(OUT) :: L1,L2 REAL(SP), INTENT(OUT) :: FACT,BACT INTEGER, INTENT(OUT) :: IERR !------------------------------------------------------------------------------! REAL(SP) T1,T2 INTEGER I,NTMAX !==============================================================================| NTMAX = TMAP%NTIMES IF(STIME < TMAP%TIMES(1))THEN FACT = 0.0_SP BACT = 1.0_SP L1 = 1 L2 = 1 IERR = -1 RETURN END IF IF(STIME > TMAP%TIMES(NTMAX))THEN FACT = 1.0_SP BACT = 0.0_SP L1 = NTMAX L2 = NTMAX IERR = 1 RETURN END IF IF(NTMAX == 1)THEN FACT = 1.0_SP BACT = 0.0_SP L1 = 1 L2 = 1 IERR = 0 RETURN END IF DO I=2,TMAP%NTIMES T1 = TMAP%TIMES(I-1) T2 = TMAP%TIMES(I) IF(STIME >= T1 .AND. STIME <= T2)THEN L1 = I-1 L2 = I IERR = 0 FACT = (STIME-T1)/(T2-T1) BACT = 1.0_SP-FACT END IF END DO RETURN END SUBROUTINE BRACKET !==============================================================================| END MODULE MOD_MEANFLOW