New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
trcatm_c14.F90 in branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/TOP_SRC/C14 – NEMO

source: branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/TOP_SRC/C14/trcatm_c14.F90 @ 7910

Last change on this file since 7910 was 7910, checked in by timgraham, 7 years ago

All wrk_alloc removed

File size: 13.3 KB
Line 
1MODULE trcatm_c14
2   !!======================================================================
3   !!                     ***  MODULE  trcatm_c14  ***
4   !! TOP :  read and manages atmospheric values for radiocarbon model 
5   !!=====================================================================
6   !! History: Based on trcini_c14b & trcsms_c14b :
7   !!          Anne Mouchet
8   !!----------------------------------------------------------------------
9   !!   trc_atm_c14_ini  : initialize c14atm & pco2atm
10   !!   trc_atm_c14      : read and time interpolate  c14atm & pco2atm
11   !!----------------------------------------------------------------------
12   USE par_trc       !  passive tracers parameters
13   USE oce_trc       !  shared variables between ocean and passive tracers
14   USE trc           !  passive tracers common variables
15   USE sms_c14    ! c14 simulation type, atm default values...
16
17   IMPLICIT NONE
18   PRIVATE
19
20   PUBLIC   trc_atm_c14         ! called in trcsms_c14.F90
21   PUBLIC   trc_atm_c14_ini     ! called in trcini_c14.F90
22   !
23   !!----------------------------------------------------------------------
24   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
25   !! $Id: trcatm_c14.F90 .... $
26   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
27   !!----------------------------------------------------------------------
28CONTAINS
29
30   SUBROUTINE trc_atm_c14_ini
31      !!----------------------------------------------------------------------
32      !!                   ***  ROUTINE trc_c14_ini  ***
33      !!                   
34      !! ** Purpose :   initialisation of sbc for radiocarbon
35      !!
36      !! ** Method  :
37      !!----------------------------------------------------------------------
38      !
39      CHARACTER (len=20)        :: clfile                        ! forcing file name
40      INTEGER                   :: ji,jj,jn                        ! dummy loop indice
41      INTEGER                   :: ierr1,ierr2,ierr3,izco2         ! temporary integers
42      INTEGER                   :: inum1,inum2,incom,iyear         ! temporary integers
43      REAL(wp) ::   ys40 = -40.     ! 40 degrees south
44      REAL(wp) ::   ys20 = -20.     ! 20 degrees south
45      REAL(wp) ::   yn20 =  20.     ! 20 degrees north
46      REAL(wp) ::   yn40 =  40.     ! 40 degrees north
47      REAL(wp), DIMENSION(nrecco2)   :: zco2, zyrco2  ! temporary arrays for swap
48      !
49      !!----------------------------------------------------------------------
50      !
51      IF( nn_timing == 1 )  CALL timing_start('trc_atm_c14_ini')
52      !
53     
54      IF( lwp ) WRITE(numout,*) ' '
55      IF( lwp ) WRITE(numout,*) ' trc_atm_c14_ini : initialize atm CO2 & C14-ratio '
56      IF( lwp ) WRITE(numout,*) ' '
57      !
58      tyrc14_now = 0._wp   ! initialize
59      !
60      IF(kc14typ >= 1) THEN  ! Transient atmospheric forcing: CO2
61      !
62         clfile = TRIM( cfileco2 )
63         IF(lwp) WRITE(numout,*) 'Read CO2 atmospheric concentrations file ',clfile
64         CALL ctl_opn( inum1, clfile, 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, numout, .FALSE. )
65         REWIND(inum1)
66     
67         READ(inum1,*) nrecco2,incom
68         DO jn = 1, incom        ! Skip over descriptor lines
69            READ(inum1,'(1x)')
70         END DO
71         ALLOCATE( spco2(nrecco2), tyrco2(nrecco2)       , STAT=ierr1 )
72         IF( ierr1 /= 0 )   CALL ctl_stop( 'STOP', 'trc_atm_c14_ini: unable to allocate co2 arrays' )
73      ! get  CO2 data
74         DO jn = 1, nrecco2
75            READ(inum1, *)  tyrco2(jn), spco2(jn)
76         END DO
77         CLOSE(inum1)
78      !
79         IF(kc14typ==2) THEN
80            zco2(:)=spco2(:)
81            zyrco2(:)=tyrco2(:)
82      ! Set CO2 times on AD time scale & swap records : In CO2 file : youngest first
83            DO jn = 1, nrecco2
84               izco2=nrecco2-jn+1
85               spco2(izco2)=zco2(jn)
86               tyrco2(izco2)=1950._wp-zyrco2(jn)         ! BP to AD dates
87            END DO
88         ENDIF
89      !
90      !        ! Transient atmospheric forcing: Bomb C14 & Paleo C14 : open file
91      !
92         clfile = TRIM( cfilec14 )
93         IF (lwp) WRITE(numout,*) 'Read C-14 atmospheric concentrations file ',clfile
94         CALL ctl_opn( inum2, clfile, 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, numout, .FALSE. )
95         REWIND(inum2)
96      !
97      ! Bomb C14: 3 zones for atm C14 !
98         IF(kc14typ == 1) THEN  ! Transient atmospheric forcing: Bomb C14
99      !
100            READ(inum2,*) nrecc14,incom
101            DO jn = 1, incom        ! Skip over descriptor lines
102               READ(inum2,'(1x)')
103            END DO
104            ALLOCATE( bomb(nrecc14,nc14zon), tyrc14(nrecc14)       , STAT=ierr2 )
105            IF( ierr2 /= 0 )   CALL ctl_stop( 'STOP', 'trc_atm_c14_ini: unable to allocate c14 arrays' )
106      ! get bomb c14 data
107            DO jn = 1, nrecc14
108               READ(inum2,*) tyrc14(jn), bomb(jn,1), bomb(jn,2), bomb(jn,3)
109            END DO
110            CLOSE(inum2)
111
112       ! Linear  interpolation of the C-14 source fonction
113       ! in linear latitude bands  (20N,40N) and (20S,40S)
114       !------------------------------------------------------
115            ALLOCATE( fareaz  (jpi,jpj ,nc14zon) , STAT=ierr3 )
116            IF( ierr3 /= 0 )   CALL ctl_stop( 'STOP', 'trc_atm_c14_ini: unable to allocate fareaz' )
117      !
118            DO jj = 1 , jpj                       ! from C14b package
119              DO ji = 1 , jpi
120                 IF( gphit(ji,jj) >= yn40 ) THEN
121                    fareaz(ji,jj,1) = 0.
122                    fareaz(ji,jj,2) = 0.
123                    fareaz(ji,jj,3) = 1.
124                 ELSE IF( gphit(ji,jj ) <= ys40) THEN
125                    fareaz(ji,jj,1) = 1.
126                    fareaz(ji,jj,2) = 0.
127                    fareaz(ji,jj,3) = 0.
128                 ELSE IF( gphit(ji,jj) >= yn20 ) THEN
129                    fareaz(ji,jj,1) = 0.
130                    fareaz(ji,jj,2) = 2. * ( 1. - gphit(ji,jj) / yn40 )
131                    fareaz(ji,jj,3) = 2. * gphit(ji,jj) / yn40 - 1.
132                 ELSE IF( gphit(ji,jj) <= ys20 ) THEN
133                    fareaz(ji,jj,1) = 2. * gphit(ji,jj) / ys40 - 1.
134                    fareaz(ji,jj,2) = 2. * ( 1. - gphit(ji,jj) / ys40 )
135                    fareaz(ji,jj,3) = 0.
136                 ELSE
137                    fareaz(ji,jj,1) = 0.
138                    fareaz(ji,jj,2) = 1.
139                    fareaz(ji,jj,3) = 0.
140                 ENDIF
141              END DO
142           END DO
143      !
144         ENDIF
145      !
146      ! Paleo C14: 1 zone for atm C14 !
147         IF(kc14typ == 2) THEN  ! Transient atmospheric forcing: Paleo C14
148      !
149            READ(inum2,*) nrecc14,incom
150            DO jn = 1, incom        ! Skip over descriptor lines
151               READ(inum2,'(1x)')
152            END DO
153            ALLOCATE( atmc14(nrecc14), tyrc14(nrecc14)       , STAT=ierr2 )
154            IF( ierr2 /= 0 )   CALL ctl_stop( 'STOP', 'trc_atm_c14_ini: unable to allocate c14 arrays' )
155      ! get past c14 data
156            DO jn = 1, nrecc14
157               READ(inum2,*) iyear,incom,incom,atmc14(jn)
158               tyrc14(jn)=1950._wp-REAL(iyear,wp)                ! BP to AD dates
159            END DO
160            CLOSE(inum2)
161      !
162         ENDIF
163      !
164      ! Note on dates:
165      !   In files dates have dimension yr; either AD or BP; if BP date is changed into AD here
166      !   When dealing with dates previous to 0. AD one needs to set tyrc14_beg to the actual starting year
167      !   Do not forget to appropriately set nn_date0 and nn_rstctl in namelist
168      !                           AND        nn_rsttr in namelist_top  if offline run
169      !   All details are given in NEMO-C14.pdf report
170     
171         tyrc14_now=nyear                                ! actual initial yr - Bomb
172         if(kc14typ == 2) tyrc14_now=nyear+tyrc14_beg-1  ! actual initial yr - Paleo
173      !                                     ! we suppose we start on tyrc14_now/01/01 @ 0h
174         m1_c14= 1
175         m1_co2= 1
176         DO jn = 1,nrecco2
177            IF ( tyrc14_now >= tyrco2(jn) ) m1_co2 = jn  ! index of first co2 record to consider
178         END DO
179         DO jn = 1,nrecc14
180            IF ( tyrc14_now >= tyrc14(jn) ) m1_c14 = jn  ! index of first c14 record to consider
181         END DO
182         IF (lwp) WRITE(numout,*) 'Initial yr for experiment', tyrc14_now
183         IF (lwp) WRITE(numout,*) '   CO2 & C14 start years:', tyrco2(m1_co2),tyrc14(m1_c14)
184      !
185         m2_c14= m1_c14
186         m2_co2= m1_co2
187      !
188      ENDIF
189      !
190      IF( nn_timing == 1 )  CALL timing_stop('trc_atm_c14_ini')
191      !
192   END SUBROUTINE trc_atm_c14_ini
193
194
195   SUBROUTINE trc_atm_c14( kt, co2sbc, c14sbc )
196      !!----------------------------------------------------------------------
197      !!                   ***  ROUTINE trc_flx  ***
198      !!                   
199      !! ** Purpose :   provides sbc for co2 & c14 at kt
200      !!
201      !! ** Method  :  read files
202      !!
203      !! ** Action  :   atmospheric values interpolated at time-step kt
204      !!----------------------------------------------------------------------
205      INTEGER                 , INTENT(in   )   ::   kt       ! ocean time-step
206      REAL(wp), DIMENSION(:,:), INTENT(  out)   ::   c14sbc   ! atm c14 ratio
207      REAL(wp),                 INTENT(  out)   ::   co2sbc   ! atm co2 p
208      INTEGER                                   ::   jz       ! dummy loop indice
209      REAL(wp)                              ::   zdint,zint   ! work
210      REAL(wp), DIMENSION(nc14zon)              ::   zonbc14  ! work
211      !
212      !!----------------------------------------------------------------------
213      !
214      IF( nn_timing == 1 )  CALL timing_start('trc_atm_c14')
215      !
216      IF( kc14typ == 0) THEN
217         co2sbc=pco2at
218         c14sbc(:,:)=rc14at
219      ENDIF
220      !
221      IF(kc14typ >= 1) THEN  ! Transient C14 & CO2
222      !
223         tyrc14_now = tyrc14_now + ( rdt / ( rday * nyear_len(1)) )    !  current time step in yr relative to tyrc14_beg
224      !
225      ! CO2 --------------------------------------------------------
226      !
227      ! time interpolation of CO2 concentrations     ! if out of record keeps first/last value
228         IF( tyrc14_now > tyrco2(m2_co2) ) THEN     ! next interval
229           m1_co2 = m2_co2
230           m2_co2 = MIN ( m2_co2 + 1 , nrecco2 )
231         ENDIF
232      !
233         zdint  = tyrco2(m2_co2) - tyrco2(m1_co2)
234         co2sbc = spco2(m2_co2)                        ! if out of record keeps first/last value
235         zint = 0._wp
236         IF ( zdint > 0._wp ) THEN                     ! if within record interpolate:
237            zint = ( tyrco2(m2_co2) - tyrc14_now ) / zdint
238            co2sbc = spco2(m2_co2) + zint * ( spco2(m1_co2) - spco2(m2_co2) )
239         ENDIF
240      !
241         IF( lwp .AND.  kt == nitend )  THEN
242            WRITE(numout, '(3(A,F12.4))') 't1/tn/t2:',tyrco2(m1_co2),'/', tyrc14_now,'/',tyrco2(m2_co2)
243            WRITE(numout, *) 'CO2:',spco2(m1_co2),co2sbc ,spco2(m2_co2)
244         ENDIF
245      !
246      ! C14 --------------------------------------------------------
247      !
248      ! time interpolation of C14 concentrations
249         IF ( tyrc14_now > tyrc14(m2_c14) ) THEN     ! next interval
250           m1_c14 = m2_c14
251           m2_c14 = MIN ( m2_c14 + 1 , nrecc14 )
252         ENDIF
253         zdint = tyrc14(m2_c14) - tyrc14(m1_c14)
254         zint=0._wp
255         IF ( zdint > 0._wp ) zint = ( tyrc14(m2_c14) - tyrc14_now ) / zdint ! if  within record
256         IF( lwp .AND.  kt == nitend )  &
257            &     WRITE(numout,'(3(A,F12.4))') 't1/tn/t2:',tyrc14(m1_c14),'/', tyrc14_now,'/',tyrc14(m2_c14)
258      !
259      ! ------- Bomb C14  ------------------------------------------
260      !
261         IF( kc14typ == 1) THEN
262      !                                          ! time interpolation
263          zonbc14(:) = bomb(m2_c14,:)                ! if out of record keeps first/last value
264      !                                          !    if within record interpolate:
265          IF ( zdint > 0._wp ) zonbc14(:) = bomb(m2_c14,:) + zint * ( bomb(m1_c14,:)  - bomb(m2_c14,:)  )
266      !
267            IF(lwp .AND.  kt == nitend )  &
268                 &      WRITE(numout, *)  'C14:',bomb(m1_c14,1),zonbc14(1),bomb(m2_c14,1)
269      !   Transform DeltaC14 --> C14 ratio
270            zonbc14(:) = 1._wp + zonbc14(:)/1.d03
271      !
272      !  For each (i,j)-box, with information from the fractional area
273      !  (zonmean), computes area-weighted mean to give the atmospheric C-14
274      !  ----------------------------------------------------------------
275            c14sbc(:,:) = zonbc14(1) * fareaz(:,:,1)   &
276               &          + zonbc14(2) * fareaz(:,:,2)   &
277               &          + zonbc14(3) * fareaz(:,:,3)
278         ENDIF
279      !
280      ! ------- Paleo C14  -----------------------------------------
281      !
282         IF( kc14typ == 2 ) THEN
283      !                                          ! time interpolation
284            zonbc14(1) = atmc14(m2_c14)          ! if out of record keeps first/last value
285         !                                       !    if within record interpolate:
286            IF ( zdint > 0._wp ) zonbc14(1) = atmc14(m2_c14) + zint * ( atmc14(m1_c14) - atmc14(m2_c14) )
287            IF(lwp .AND.  kt == nitend )  &
288                 &      WRITE(numout, *)  'C14: ',atmc14(m1_c14),zonbc14(1),atmc14(m2_c14)
289      !   Transform DeltaC14 --> C14 ratio
290            c14sbc(:,:) = 1._wp + zonbc14(1)/1.d03
291         ENDIF
292      !
293      ENDIF
294      !
295      IF( nn_timing == 1 )  CALL timing_stop('trc_atm_c14')
296      !
297   END SUBROUTINE trc_atm_c14
298
299   !!======================================================================
300END MODULE trcatm_c14
Note: See TracBrowser for help on using the repository browser.