Inside GCM Model II

Earlier I did the ‘where to find it how to get it what’s in the box’ posting on NASA GISS GCM Model II in this posting:

https://chiefio.wordpress.com/2016/12/27/a-remarkably-tiny-global-circulation-model-you-can-run/

At the end of the process (down in comments) I’d gotten the thing to compile under Linux. The short form is:

Download.
Unzip.
Edit Makefile and replace the SVNVER variable ‘discovery’ of what svn version you have with
SVNVER=0.0
Edit RANDVAX.f and setpath.f to remove the “_” character from names of functions
Copy Makefile.gfortran to Makefile.pi and comment out the LIBS= line:
#LIBS = -L/Developer/SDKs/MacOSX10.5.sdk/usr/lib

At that point “make” and then “make -f makefile.pi” ought to build it.

At that point you discovery it wants a bunch of fairly complicated input configuration files that are not in the software download. I’m working on getting or creating those… While that happens, I’m doing a bit of code review on the package.

In the earlier posting I noted those small FORTRAN and other source files that were not the core of the program. Things like the GUI added bits and some Macintosh glueware to make it go on a Mac. In this posting, I’ll be looking at the larger bits that were not examined then. (Likely this one and some more as there are 5 large code blocks and I think one per posting is likely the limit. We’ll see as I write them…)

Here’s a listing fo the files you get in the downloaded source tarball:

sh-4.3$ ls -l
-rw-r--r-- 1 chiefio chiefio   3926 Aug  2  2005 B83XXDBL.COM
-rw-r--r-- 1 chiefio chiefio   3164 Aug  2  2005 BA94jalC9.COM
-rw-r--r-- 1 chiefio chiefio 240095 Apr 17  2008 DB11pdC9.f
-rw-r--r-- 1 chiefio chiefio  13208 Aug  2  2005 FFT36macDBL.f
-rw-r--r-- 1 chiefio chiefio   5362 Aug  2  2005 FORCINGSjalC9.f
-rw-r--r-- 1 chiefio chiefio   1333 Aug  2  2005 FORCINGSmac.COM
-rw-r--r-- 1 chiefio chiefio    876 Mar 23  2006 Info.plist
-rw-r--r-- 1 chiefio chiefio    906 Dec 27 23:00 Makefile
-rw-r--r-- 1 chiefio chiefio    612 May 12  2008 Makefile.Mac.PPC
-rw-r--r-- 1 chiefio chiefio   3145 Apr 18  2008 Makefile.README
-rw-r--r-- 1 chiefio chiefio    747 Apr  1  2008 Makefile.gfortran
-rw-r--r-- 1 chiefio chiefio    706 May 12  2008 Makefile.ifort
-rw-r--r-- 1 chiefio chiefio   9238 Apr 17  2008 Makefile.win
-rw-r--r-- 1 chiefio chiefio   2252 Apr 17  2008 Makefile.win.gui
-rw-r--r-- 1 chiefio chiefio 204365 Mar 23  2006 Mjal2cpdC9.f
-rw-r--r-- 1 chiefio chiefio 331692 Jan 17  2006 Pjal0C9.f
-rw-r--r-- 1 chiefio chiefio     59 Aug  2  2005 PostBuild.sh
-rw-r--r-- 1 chiefio chiefio 555793 Aug  2  2005 R83ZAmacDBL.f
-rw-r--r-- 1 chiefio chiefio   1248 Dec 27 22:58 RANVAX.f
-rw-r--r-- 1 chiefio chiefio   1427 Aug  2  2005 RANVAXxlf.f
-rw-r--r-- 1 chiefio chiefio   3339 Mar 13  2007 README.f.in
-rw-r--r-- 1 chiefio chiefio 128314 Aug  2  2005 RFRCmacDBL.f
-rw-r--r-- 1 chiefio chiefio   4203 Jan 18  2006 UTILmacDBL.f
-rw-r--r-- 1 chiefio chiefio   4202 Dec 14  2006 UTILwinDBL.f
-rw-r--r-- 1 chiefio chiefio   5548 Jan 17  2006 commandlinetest.gui
-rw-r--r-- 1 chiefio chiefio  11887 Aug  2  2005 modelF.r
-rw-r--r-- 1 chiefio chiefio   1475 Aug  2  2005 mrweprefs.r
-rw-r--r-- 1 chiefio chiefio    132 Aug  2  2005 pd_COMMON
-rw-r--r-- 1 chiefio chiefio   1321 Dec 27 22:58 setpath.f

Of those, I’ve already mentioned that the COMMON and .COM files are FORTRAN common blocks (definitions of what variables and arrays will be shared by several programs for data passing), the .r files are for Macintosh compatibility use, and the Makefile.x set are custom build scripts for different environments (with Makefile doing a set-up step then telling you to run one of the others). README.f.in is processed by Makefile to produce README.f which looks like it just sticks a ‘edGCM branding’ comment on the tops of programs. Also, I’d looked at setpath.f (that does a workaround for execution path setting in some environments) and RANDVAX files that basically is a “call random” function for making pseudo-random numbers. The “commanlinetest.gui” didn’t interest me as I’m not using the edGCM GUI code (that is proprietary and licensed for a fee…) also the PostBuild.sh shell script that is a one line “copy the executable to your bin directory” trivial “scrip”. That leaves info.plilst and a very few FORTRAN programs to look at next.

-rw-r--r-- 1 chiefio chiefio 240095 Apr 17  2008 DB11pdC9.f
-rw-r--r-- 1 chiefio chiefio  13208 Aug  2  2005 FFT36macDBL.f
-rw-r--r-- 1 chiefio chiefio   5362 Aug  2  2005 FORCINGSjalC9.f
-rw-r--r-- 1 chiefio chiefio    876 Mar 23  2006 Info.plist
-rw-r--r-- 1 chiefio chiefio 204365 Mar 23  2006 Mjal2cpdC9.f
-rw-r--r-- 1 chiefio chiefio 331692 Jan 17  2006 Pjal0C9.f
-rw-r--r-- 1 chiefio chiefio 555793 Aug  2  2005 R83ZAmacDBL.f
-rw-r--r-- 1 chiefio chiefio 128314 Aug  2  2005 RFRCmacDBL.f
-rw-r--r-- 1 chiefio chiefio   4203 Jan 18  2006 UTILmacDBL.f
-rw-r--r-- 1 chiefio chiefio   4202 Dec 14  2006 UTILwinDBL.f

A MUCH smaller set of things to look at, no? I’m going to take them more or less in order of increasing size. Why? To clear out the small and simple stuff quickly, leaving on the larger core to chew on at length. Often this is the best way to discover out a new package works. Nibble off the edges until you are left with a few things to figure out…

So first up, “Info.plist”:

This is just FILLED with angle brackets. Since WordPress strips out all things angle bracket, and I’m not interested in typing a few hundred obscure escape codes to show them, I’m just going to replace them with square brackets for display purposes.

[?xml version="1.0" encoding="UTF-8"?]
[!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"]
[plist version="0.9"]
[dict]
      	[key]CFBundleExecutable[/key]
	[string]modelII 8x10x9[/string]
	[key]CFBundleIdentifier[/key]
	[string]com.edgcm.modelII[/string]
	[key]CFBundleInfoDictionaryVersion[/key]
	[string]6.0[/string]
	[key]CFBundlePackageType[/key]
	[string]APPL[/string]
	[key]CFBundleSignature[/key]
	[string]eGCM[/string]
	[key]CFBundleVersion[/key]
	[string]1.0.7[/string]
	[key]CSResourcesFileMapped[/key]
	[true/]
	[key]CFBundleIconFile[/key]
	[string]modelII.icns[/string]
	[key]CFBundleShortVersionString[/key]
    [string]1.0.7 Model II[/string]
    [key]CFBundleLongVersionString[/key]
    [string]1.0.7, GISS GCM Model II (8x10 or 7.826x10, 9-layer)[/string]
    [key]NSApplescriptEnabled[/key]
    [string]No[/string]
[/dict]
[/plist]

“Propertylist” and with an xml tag at the tope. Looks to me like a bunch more of the GUI oriented stuff that I’m not bothering with. OK, moving on…

UTILmacDBL.f and UTILwinDBL.f

As you might guess from their name, these are a Mac and Windows version of the same thing. A “diff” on them shows little difference. The Windows version has “clock90” while the Mac version has “secnds(0.0)”. I’ve preplaced the angle brackets in the ‘diff’ output below with [ and }.

sh-4.3$ diff UTILmacDBL.f UTILwinDBL.f 
33c33
{       IHSC = secnds(0.0)
---
} c      IHSC = secnds(0.0)
35c35
{ c      IHSC = clock()
---
}       IHSC = clock()
124c124
{       MNOW  = secnds (0.0)      
---
} c     MNOW  = secnds (0.0)      
126c126
{ c      MNOW = clock()
---
}       MNOW = clock()

So what’s the Mac version look like in total? It is 131 lines.

sh-4.3$ cat UTILmacDBL.f 
c  *********************************************************************
c  *********************************************************************
c  **
c  ** Model IImac
c  ** Based on GCMII code for IBM RS/6000 computers created at GISS
c  ** Modified to compile under Absoft Pro Fortran 6.2 for MacOS.  
c  ** Based on MP008macC9, BA94C9 and MA94DC9
c  **
c  ** CHANGE HISTORY:
c  **
c  ** 7/27/99 First Successful Compile! (DCH)
c  ** 7/27/99 Changed MCLOCK() call to DTIME() unix call (DCH)
c  ** 7/30/99 Patched DTIME to 4 to make it compile
c  ** 11/01/99 Another patch to work as a shared lib (MFS)
c  ** 12/21/00 Try with another version of Model II (MFS)
c  ** 09/28/02 Use clock() to replace MCLOCK() (MFS)
c  ** 01/27/05 working MCLOCK (GLR)
c  ** 01/17/06 reverted to CLOCKS, secnds on Mac, clock on Win (MFS)
c  **
c  ** NOTES:
c  **  Not sure if DTIME does the same thing as MCLOCK, but Reto believe
c  **  all calls to CLOCKS are not important to the running of the model
c  **
c  *********************************************************************
c  *********************************************************************

c  MS SYSTEM ROUTINES EMULATION FOR IBM RS/6000
c

Looks like a collection of a few Utility Functions. We’ll break them out. First, the “clocks” function:

OK, so it gets run times of executions. Might need to fiddle with just what function is called, but the Mac, being Mach based and using gfortran build likely uses a Linux compatible call. And, as the comment notes, not really important to the actual model. Likely used just to display run time info in the presentation phase of the GUI anyway (or annotated into a run log file.).

      SUBROUTINE CLOCKS(IHSC)
c  THIS VERSION OF CLOCKS RETURNS PROCESS TIME OF USER AND
c  SYSTEM TIME OF CHILD PROCESSES
c  NOTE: MCLOCK IS REALLY IN HUNDREDTHS OF A SECOND, NOT SIXTIETHS.
      IHSC = secnds(0.0)
c  ** Windows should use
c      IHSC = clock()
      RETURN
      END

THBAR looks like some thermobaric calculations. The top comment block presents what they think they are doing. I note that they commented out an older FORTRAN style of the DATA statement and replaced it with the newer PARAMETER form. Nothing like gratuitous changes to a language spec over time to keep programmers employed…

      FUNCTION THBAR (X,Y)
c  **
c  ** TH-mean used for vertical differencing (Arakawa)
c  ** THBAR(T1,T2) = (ln(T1) - ln(T2))/(1/T2 - 1/T1)
c  **              = T1*g(x) with x=T1/T2 , g(x)=ln(x)/(x-1)
c  **      g(x) is replaced by a rational function
c  **           (a+bx+cxx+dxxx+cx**4)/(e+fx+gxx)
c  **      approx.error <1.E-6 for x between .9 and 1.7
c  **
c     REAL*8 A,B,C,D,E,F,G,Q,AL
      IMPLICIT REAL*8 (A-H,O-Z)
      PARAMETER (
     *  A=113.4977618974100d0,B=438.5012518098521d0,
     *  C=88.49964112645850d0,D=-11.50111432385882d0,
     *  E=30.00033943846368d0,F=299.9975118132485d0,
     *  G=299.9994728900967d0)
c     DATA A,B,C,D,E,F,G/113.4977618974100,438.5012518098521,
c    *  88.49964112645850,-11.50111432385882,
c    *  30.00033943846368,299.9975118132485,299.9994728900967/
      Q=X/Y
      AL=(A+Q*(B+Q*(C+Q*(D+Q))))/(E+Q*(F+G*Q))
      THBAR=X*AL
      RETURN
      END

No idea at this point what EXPBYK does. Send it X, it raises X to the power 0.286, but why?

(“Why? Don’t ask why. Down that path lies insanity and ruin. -E.M.Smith”… we will be exploring ‘why’ when we get to the code that calls EXPBYK …

      FUNCTION EXPBYK (X)
      IMPLICIT REAL*8 (A-H,O-Z)
      EXPBYK=X**.286
      RETURN
      END

DREAD function looks like it just does a REAL ARRAY of 4 bytes to REAL 8 byte length conversion. Ah, the joys of data type mismatch… With 64 bit machines common now, one could likely get a speed up by eliminating this function and making all such things 8 bytes long in the mainline code. Change “reals” to “doubles”.

      SUBROUTINE DREAD (IUNIT,AIN,LENGTH,AOUT)
c  **
c  ** READ IN REAL*4 ARRAY AND CONVERT TO REAL*8
c  **
      REAL*4 AIN(LENGTH)
      REAL*8 AOUT(LENGTH)
      READ (IUNIT) AIN
      DO 10 N=LENGTH,1,-1
   10 AOUT(N)=AIN(N)
      RETURN
      END

And the same thing for Integers…

      SUBROUTINE MREAD (IUNIT,M,NSKIP,AIN,LENGTH,AOUT)
c  **
c  ** READ IN INTEGER & REAL*4 ARRAY AND CONVERT TO REAL*8
c  **
      REAL*4 AIN(LENGTH),X
      REAL*8 AOUT(LENGTH)
      READ (IUNIT) M,(X,N=1,NSKIP),AIN
      DO 10 N=LENGTH,1,-1
   10 AOUT(N)=AIN(N)
      RETURN
      END

Then again, the same idea for the TITLE… Title of what? Maybe later… ;-)

      SUBROUTINE READT (IUNIT,NSKIP,AIN,LENGTH,AOUT,IPOS)
c  **
c  ** READ IN TITLE & REAL*4 ARRAY AND CONVERT TO REAL*8
c  **
      REAL*4 AIN(LENGTH),X
      REAL*8 AOUT(LENGTH)
      CHARACTER*80 TITLE
      DO 10 N=1,IPOS-1
   10 READ (IUNIT,END=920)
      READ (IUNIT,ERR=910,END=920) TITLE,(X,N=1,NSKIP),AIN
c     IF(LEN.LT.4*(20+NSKIP+LENGTH)) GO TO 930
      DO 100 N=LENGTH,1,-1
  100 AOUT(N)=AIN(N)
      WRITE(6,'('' Read from Unit '',I2,'':'',A80)') IUNIT,TITLE
      RETURN
  910 WRITE(6,*) 'READ ERROR ON UNIT',IUNIT
      STOP 'READ ERROR'
  920 WRITE(6,*) 'END OF FILE ENCOUNTERED ON UNIT',IUNIT
      STOP 'NO DATA TO READ'
c  30 WRITE(6,*) LEN/4,' RATHER THAN',20+NSKIP+LENGTH,' WORDS ON UNIT',
c    *  IUNIT
c     STOP 'NOT ENOUGH DATA FOUND'
      END

Then we have a ‘timer’ routine. So it is keeping track of run times internally. OK, I’d likely put that external, but whatever. Key bit is it isn’t critical to the actual model nor understanding it.

      SUBROUTINE TIMER (MNOW,MINC,MSUM)
c  **
c  ** OUTPUT: MNOW (.01 S) = CURRENT CPU TIME
c  **         MINC (.01 S) = TIME SINCE LAST CALL TO SUBROUTINE TIMER
c  **         MSUM (.01 S) = MSUM + MINC
c  **
      SAVE MLAST
      MNOW  = secnds (0.0)      
c  ** Windows should use
c      MNOW = clock()
      MINC  = MNOW - MLAST
      MSUM  = MSUM + MINC
      MLAST = MNOW
      RETURN
      END

Forcings? There MUST be FORCINGs…

Next up is that FORCINGSjalC9.f file. It is 175 lines long. Hopefully not too much density in them… I suspect, though, that this will tip the hand about what is expected to produce the desired results from the model.

sh-4.3$ cat FORCINGSjalC9.f 
c  *********************************************************************
c  *********************************************************************
c  **
c  ** Model IImac
c  ** Based on GCMII code for IBM RS/6000 computers created at GISS
c  ** Modified to compile under Absoft Pro Fortran 7.0 for MacOS 9/X.  
c  ** Code to do trends
c  ** 
c  ** CHANGE HISTORY:
c  ** 
c  ** 05/27/02 new S0X code (MSC/MFS)
c  ** 06/03/02 new greenhouse gas trend code (MSC/MFS)
c  ** 06/10/02 fixed bug so it reads the first year (MFS)
c  ** 06/17/02 fixed logic error in code (MFS)
c  ** 06/19/02 moved joldyear to the common block (MFS)
c  ** 05/06/04 added fixed var to include END (MAC)
c  ** 05/27/04 changed JOLDYEAR to array with 5 values (=NGAS) (MAC)
c  ** 06/22/04 removed extra defined jyear (MFS)
c  ** 03/16/05 fix format statement (MFS/Patrick Lee/JAL)
c  ** 
c  ** NOTES:
c  ** This code replaces RFRC
c  ** 
c  *********************************************************************
c  *********************************************************************

Hmmm… there is also a RFRCmacDBL.f program, so one presumes RFRC is short for Radiative FoRCing or some such. OK, we’ve got Sulphur Oxides SOX, a Greenhouse Gas Trend setting, and some things about radiative forcing. Wonder if we’ll find anything else…

      SUBROUTINE SOLARFORCING
c  ** reads the solar trend, replaces code in RFRC
c  ** does both trends and fixed
      INCLUDE 'BA94jalC9.COM'
      INCLUDE 'FORCINGSmac.COM'
c  ** var
      INTEGER*4 JDATAYEAR
      REAL*8 DATAVALUE
      REAL*8 XXGAS
      INTEGER*4 OLDYEAR
      DATA OLDYEAR/-999/
      
      IF((IS0XDATA.GT.0).AND.(JYEAR.GE.IS0XDATASTART))THEN
        IF(OLDYEAR.NE.JYEAR)THEN
          XXGAS=GREENHOUSEGASFORCING(IS0XDATA,IS0XDATASTART,
     *      IS0XDATAEND)
          OLDYEAR=JYEAR
         END IF
        S0X=XXGAS
      END IF
      END

So it DOES have a “Solar Forcing” aspect. Here it reads in 2 COMmon blocks for sharing data. We’ll look at those just below this program. It looks like it uses Julian Date (JDATEYEAR) to maybe drive a solar orbital mechanics variation in sunshine? Nice to have that in, now just to get the values right ;-) Or perhaps it is just to puck up gas forcing based on year… We’ll need to read more of the guts of it to see what it really does.

Then it does a VERY direct “make greenhouse gasses force things this much based on year” near as I can tell (at this point and from function names…). Note to self: Find “GREENHOUSEGASFORCING” function and see what it does… (a ‘grep’ of all things .f shows it is only in this program… so down below somewhere).

DATA-REF-Year

I like the “goes very weird” comment ;-) So water vapor, CO2, Ozone, Oxygen (why oxygen?, NOx, Methane, and some Freons… The 4211, 12, and 13 are line numbers in the original file.

Again, it includes the COMmon block for sharing data.

Overall, looks like it just forces XGAS to 1958 values to “avoid weirdness”… Then packs JOLDYEAR with a bad data value of -999 (common marker in FORTRAN era stuff to show it isn’t zero but empty).

      SUBROUTINE DATAREFYEAR(XGAS,YEAR,NGAS)
c  ** for reference purposes 1958 values always have to be certian
c  ** constants or the scaling goes very weird, Andy warned me
c  **
c  ** Here are the original lines from R83ZAmacC9
C                 H2O   CO2  O3      O2 NO2   N2O   CH4   CCL3F1 CCL2F2 4211.   
C     DATA FULGAS/1.0,  1.0,1.0,    1.0,1.0,  1.0,  1.0,    1.0,    1.0/4212.   
c     DATA PPMV58/0.0,315.0,0.0,210000.,0.0,0.295,1.400,8.00E-6,25.0E-6/4213.   
      INCLUDE 'FORCINGSmac.COM'
c  ** var
      REAL*8 XGAS(5)
      REAL*8 YEAR
      INTEGER*4 NGAS
c  ** set xgas to 1958 values
      XGAS(1) = 315.
      XGAS(2) = 0.295
      XGAS(3) = 1.400
      XGAS(4) = 8.00E-6 * 1000.D0
      XGAS(5) = 25.0E-6 * 1000.D0
c  ** setup joldyear
      DO 100 I=1,NGAS
      JOLDYEAR(I) = -999
  100 CONTINUE
      END

This next bit lets you load in any ‘trend’ you would like in a data stream. It is to avoid hard coding trends. So it will tell us the format of the “trend” files… that look to have a year marker and then what the trend ought to be in that year. Again, the two common COMMON blocks… I note in passing the use of lots of *GAS* variables, solar and tidal and cosmic rays and orbital not so much… Gee, I wonder why it finds GH GAS as an important driver and not solar…

So basically this reads in the trends in GHG that you set, then down below it calculates what temperature “forcing” that would make, then eventually you get the temperature increase at the end…

      SUBROUTINE DATAFILETREND(XGAS,YEAR,NGAS)
c  ** file based trend code to run any trend you want without having to
c  ** recompile the model. updates the trends from the file once a year
c  ** and caches the values inbetween. 
      INCLUDE 'BA94jalC9.COM'
      INCLUDE 'FORCINGSmac.COM'

      REAL*8 XGAS(5)
      REAL*8 XXGAS(5)
      REAL*8 YEAR
      INTEGER*4 NGAS
        
      IF((ICO2DATA.GT.0).AND.(JYEAR.GE.ICO2DATASTART))THEN
        IF(JOLDYEAR(1).NE.JYEAR)THEN
          XXGAS(1)=GREENHOUSEGASFORCING(ICO2DATA,ICO2DATASTART,
     *      ICO2DATAEND)
          JOLDYEAR(1)=JYEAR
         END IF
        XGAS(1)=XXGAS(1)
      ELSE
        XGAS(1)=CO2
      END IF
        
      IF((IN2ODATA.GT.0).AND.(JYEAR.GE.IN2ODATASTART))THEN
        IF(JOLDYEAR(2).NE.JYEAR)THEN
          XXGAS(2)=GREENHOUSEGASFORCING(IN2ODATA,IN2ODATASTART,
     *      IN2ODATAEND)
          JOLDYEAR(2)=JYEAR
        END IF
        XGAS(2)=XXGAS(2)
      ELSE
        XGAS(2)=ZN2O
      END IF
        
      IF((ICH4DATA.GT.0).AND.(JYEAR.GE.ICH4DATASTART))THEN
        IF(JOLDYEAR(3).NE.JYEAR)THEN
          XXGAS(3)=GREENHOUSEGASFORCING(ICH4DATA,ICH4DATASTART,
     *      ICH4DATAEND)
          JOLDYEAR(3)=JYEAR
        END IF
        XGAS(3)=XXGAS(3)
      ELSE
        XGAS(3)=CH4
      END IF
        
      IF((IF11DATA.GT.0).AND.(JYEAR.GE.IF11DATASTART))THEN
        IF(JOLDYEAR(4).NE.JYEAR)THEN
          XXGAS(4)=GREENHOUSEGASFORCING(IF11DATA,IF11DATASTART,
     *      IF11DATAEND)
          JOLDYEAR(4)=JYEAR
        END IF
        XGAS(4)=XXGAS(4)
      ELSE
        XGAS(4)=F11
      END IF
      
      IF((IF12DATA.GT.0).AND.(JYEAR.GE.IF12DATASTART))THEN
        IF(JOLDYEAR(5).NE.JYEAR)THEN
          XXGAS(5)=GREENHOUSEGASFORCING(IF12DATA,IF12DATASTART,
     *      IF12DATAEND)
          JOLDYEAR(5)=JYEAR
        END IF
        XGAS(5)=XXGAS(5)
      ELSE
        XGAS(5)=F12
      END IF
        
      END

Once more, the two common blocks for sharing data. For a given JDATAYEAR (line 10) it reads in a given DATAVALUE, then sets the GREENHOUSEGASFORCING to that value. Nice…

      FUNCTION GREENHOUSEGASFORCING(IDATAUNIT,ISTARTDATA,IENDDATA)
c  ** reads a greenhouse gas trend and gives the result back
c  ** to the rest of the code, replaces code in RFRC
      INCLUDE 'BA94jalC9.COM'
      INCLUDE 'FORCINGSmac.COM'
c  ** var
      INTEGER*4 IDATAUNIT,ISTARTDATA,IENDDATA
      INTEGER*4 JDATAYEAR
      REAL*8 DATAVALUE
      REAL*8 GREENHOUSEGASFORCING
      
      IF(IDATAUNIT.GT.0)THEN
   10   READ(IDATAUNIT,900,ERR=100,END=100) JDATAYEAR,DATAVALUE
        IF(JDATAYEAR.EQ.JYEAR)THEN
          GREENHOUSEGASFORCING=DATAVALUE
        ELSE IF(JDATAYEAR.LT.JYEAR)THEN
          GO TO 10
        ELSE
          GO TO 110
        END IF
      ELSE
c  ** default is to do nothing        
      END IF 
c  ** sucess      
      RETURN
c  ** errors     
  100 STOP 'Error: Data file ends before current year.\n'
  110 STOP 'Error: Data file begins after current year.\n'
c  ** format
  900 FORMAT(I4,T6,F15.8)
      END

The COMMON blocks

OK, just for completeness, here are those COMMON blocks. Note that this just says what variables are global to the whole program. Any code that has an include of these variables can change them and share the results with others. This can cause no end of grief in debugging if you are not careful, but is very useful for sharing data structures.

sh-4.3$ ls -l *COM* 
-rw-r--r-- 1 chiefio chiefio 3926 Aug  2  2005 B83XXDBL.COM
-rw-r--r-- 1 chiefio chiefio 3164 Aug  2  2005 BA94jalC9.COM
-rw-r--r-- 1 chiefio chiefio 1333 Aug  2  2005 FORCINGSmac.COM
-rw-r--r-- 1 chiefio chiefio  132 Aug  2  2005 pd_COMMON

So there are 3 total. Note that “pd_COMMON” is not a FORTRAN common block like the others, involved in the model operation:

sh-4.3$ cat pd_COMMON 
      character*80 clabel
      equivalence (clabel,xlabel)
      common/pd_com/iprint_pd(12),iu_pd(12),iform_pd(12),iNetcdf_pd(12)

It has to do with printing out some things…

The FORCINGSmac.COM file

So what does FORCINGSmac.COM look like? BTW, the comments indicate changes over time. That implies strongly some other code that USED this common block to pass data changed then too.

sh-4.3$ cat FORCINGSmac.COM 
c  *********************************************************************
c  *********************************************************************
c  **
c  ** Model IImac
c  ** Based on GCMII code for IBM RS/6000 computers created at GISS
c  ** Modified to compile under Absoft Pro Fortran 6.2 for MacOS.  
c  ** Based on BRCRFmac.COM
c  **
c  ** CHANGE HISTORY:
c  **
c  ** 05/27/02 new S0X code (MFS)
c  ** 06/07/02 added ktrend (MFS)
c  ** 06/15/02 renamed ktrend to ktrendext(MFS)
c  ** 06/19/02 moved joldyear to here (MFS)
c  ** 05/27/04 changed JOLDYEAR to array with MGAS values (=NGAS) (MAC)
c  **
c  ** NOTES:
c  **
c  *********************************************************************
c  *********************************************************************

c  ** force reals to be real*8
c      IMPLICIT REAL*8 (A-H,O-Z)
c  ** new common for INPUTFORCINGS
      PARAMETER (MGAS=5)
      COMMON/IFORCINGS/
     *  KTRENDEXT, JOLDYEAR(MGAS),
     *  ICO2DATA, ICO2DATASTART, ICO2DATAEND,
     *  IN2ODATA, IN2ODATASTART, IN2ODATAEND,
     *  ICH4DATA, ICH4DATASTART, ICH4DATAEND,
     *  IF11DATA, IF11DATASTART, IF11DATAEND,
     *  IF12DATA, IF12DATASTART, IF12DATAEND,
     *  IS0XDATA, IS0XDATASTART, IS0XDATAEND,
     *  IVOLDATA, IVOLDATASTART, IVOLDATAEND
      COMMON/RFORCINGS/
     *  ZN2O, CH4, F11, F12, VOL

So the block is all REAL*8 or 64 bit values. I wonder if MGAS stands for Magic Gas ;-)

The forcings look like a trend external file, CO2, NOx, Methane, Freons, SOx and “IVOLDATA”… Volume? In any case, it’s pretty clear what is going to drive ANY temperature change in this “model”. It is just looking for Magic Gas effects, nothing else.

The BA94jalC9.COM file

That BA94jalC9.COM file has more meat in it, but we don’t know what it is used for yet. The comment about “to change the grid” in the second comment (after the intro block) implies it is a data structure for the actual grid status. We’ll see if that speculation holds. Remember that in FORTRAN, varables named starting with I through N are INTEGER types, so something like IFROG is being cast as an INT with the leading I and it likely does NOT have meaning beyond that if the rump has meaning alone. You will see a lot of varuables like JM and KTD that are likely things like (integer)M and (integer)TD. But who knows. Folks often play games with it and you can change those defaults with an explicit type assignmnet (though it is considdered a bit rude…)

sh-4.3$ cat BA94jalC9.COM 
c  *********************************************************************
c  *********************************************************************
c  **
c  ** Model IImac
c  ** Based on GCMII code for IBM RS/6000 computers created at GISS
c  ** Modified to compile under Absoft Pro Fortran 6.2 for MacOS.  
c  ** Based on MP008macC9, BA94C9 and MA94DC9
c  **
c  ** CHANGE HISTORY:
c  **
c  ** 07/27/99 First Successful Compile! (DCH)
c  ** 06/14/02 as original (MFS)
c  **
c  ** NOTES: 10/2002 Modernized by J.Lerner
c  **
c  *********************************************************************
c  *********************************************************************

C**** COMMON BLOCK (B35V)  FINE MODEL II DBLE.PREC. RS6000 10/29/91
C**** TO CHANGE THE GRID, MODIFY THE NEXT LINE ONLY
      PARAMETER (IM=36,JM=24,LM=9, KTD=6,KAIJ=80,KAJK=50)
C**** IM,JM,LM LIMITED TO 72,46,36 RESPECTIVELY BY RADCOM & SIGmas
      IMPLICIT REAL*8 (A-H,O-Z)
      REAL*8 LHE,LHM,LHS,KAPA,LAT,lat_dg
C**** THERE ARE 100 INTEGER PARAMETERS IN COMMON (JC-ARRAY)
      COMMON /IPARMB/IM0,JM0,LM0,JMM1,LMM1,   LS1,LTM,LBLM,LMCM,LSSM,
     *  KOCEAN,KDISK,KEYCT,KACC0,KCOPY,  IRAND,IJRA,MFILTR,NDYN,NCNDS,
     *  NRAD,NSURF,NGRND,NFILTR,NDAA,   NDA5D,NDA5K,NDA5S,NDA4,NDASF,
     *  MLAST,MDYN,MCNDS,MRAD,MSURF,    MDIAG,MELSE,MODRD,MODD5K,MODD5S,
     *  IYEAR,IDAY,IDAY0,JYEAR,JYEAR0,  JDAY,JDATE,JDATE0,NSTEP,MRCH,
     *  IDUM(4),NDZERO(13),NDPRNT(13),  IJD6(2,4),IDACC(12)
C**** THERE ARE 161 REAL NUMBERS IN COMMON (RC-ARRAY)
      COMMON /RPARMB/
     *  TAU,TAU0,TOFDAY,TOFDY0,DT,      TAUP,TAUI,TAUE,TAUT,TAUO,
     *  TWOPI,SDAY,LHE,LHM,LHS,         RADIUS,GRAV,RGAS,KAPA,OMEGA,
     *  CCMCX,ETA,S0X,CO2,SRCOR,        PTOP,PSF,PSL,PTRUNC,AREAG,
     *  XCDNST(2),XINT,DLAT,DLON,       SKIPSE,USESLP,USEP,USET,FIM,
     *  RSDIST,SIND,COSD,DOPK,SIG(36),SIGE(37),RDM2(44)
      CHARACTER*4 XLABEL,NAMD6,JMONTH,JMNTH0
      COMMON /TEXT/ XLABEL(33),NAMD6(4),JMONTH,JMNTH0
      COMMON /GEOMCB/ RAPVS(JM),RAPVN(JM),RAVPS(JM),RAVPN(JM),F(JM),
     *  DXYP(JM),DXP(JM),DYP(JM),DXYS(JM),SINP(JM),LAT(JM),
     *  DXYV(JM),DXV(JM),DYV(JM),DXYN(JM),COSP(JM),COSV(JM),lat_dg(jm,2)
      COMMON /BNDYCB/ FDATA(IM,JM,3),ODATA(IM,JM,5),GDATA(IM,JM,14),
     *  BLDATA(IM,JM,8),VDATA(IM,JM,10),
     *  Z1O(IM,JM),Z12O(IM,JM)
      COMMON /RADNCB/ RQT(IM,JM,3),SRHR(IM,JM,LM+1),TRHR(IM,JM,LM+1)
      COMMON /LAYACB/ DSIG(37),DSIGO(36)
      DIMENSION U(IM,JM,LM),V(IM,JM,LM),T(IM,JM,LM),P(IM,JM),Q(IM,JM,LM)
C**** DIAGNOSTIC ARRAYS
      PARAMETER (IMH=IM/2,     KACC=JM*80*3 + 24*80 +
     *   JM*3 + JM*LM*54 + JM*3*4 + IM*JM*KAIJ +
     *   IM*LM*16                      + 20*100 +
     *   JM*36 + (IMH+1)*20*8 + 8*2 + 24*50*4 +
     *   2*62*10*12 + JM*LM*KAJK + IM*JM*LM*6)
      COMMON/ACCUM/AJ(JM,80),BJ(JM,80),CJ(JM,80),DJ(24,80),
     *  APJ(JM,3),AJL(JM,LM,54),ASJL(JM,3,4),AIJ(IM,JM,KAIJ),
     *  AIL(IM,LM,16),ENERGY(20,100),
     *  CONSRV(JM,36),SPECA((IMH+1),20,8),ATPE(8,2),ADAILY(24,50,4),
     *  WAVE(2,62,10,12),AJK(JM,LM,KAJK),AIJK(IM,JM,LM,6),
     *  TSFREZ(IM,JM,2),TDIURN(IM,JM,KTD)
      COMMON/REGION/JREG(IM,JM)
      COMMON/KEYS/KEYNR(42,50),KDIAG(12)
sh-4.3$

Overall, this looks to me like it is defining the GRID layout, and with JM and IM and LM as the size values for various other arrays. I suspect LM is layers as we know MODEL II has 9 layers in the later version. That would make IM and JM the Lat and Long sizes. (nuber of boxes each way). Don’t know yet what the KTD and KA* set do, but Kxxx is often used for an INTEGER counter (COUNT being a real or float value not being between I and N…)

So mostly this looks like it sets up a bunch of arrays sized to the global grid for tracking input values and results. Any more depth can come from looking at the code that uses the variables.

The B83XXDBL.COM file

The next one looks like it is devoted to input parameters. Likely that stuff like where there is land and ice and water and vegetation and all… So this is the one I need to find a way to fill at start time. All those basic settings that were tuned to make it run “just so”.

sh-4.3$ cat B83XXDBL.COM 
c  *********************************************************************
c  *********************************************************************
c  **
c  ** Model IImac
c  ** Based on GCMII code for IBM RS/6000 computers created at GISS
c  ** Modified to compile under Absoft Pro Fortran 6.2 for MacOS.  
c  ** Based on MP008macC9, BA94C9 and MA94DC9
c  **
c  ** CHANGE HISTORY:
c  **
c  ** 07/27/99 First Successful Compile! (DCH)
c  ** 12/21/00
c  **
c  ** NOTES:
c  **
c  *********************************************************************
c  *********************************************************************


C                                                                       
C                   RADCOM:      CONTROL/INPUT PARAMETERS
C
      IMPLICIT REAL*8 (A-H,O-Z)
      COMMON/RADCOM/VADATA(11, 4, 3),DLAT(46),DLON(72),TAUMIN,FULGAS(18)
     A             ,FRACSL,RATQSL,FOGTSL,PTLISO,TLGRAD,TKCICE,FGOLDH(18)
     B             ,FLONO3,FRAYLE,FCLDTR,FCLDSR,FALGAE,FMARCL,FEMTRA(6)
     C             ,WETTRA,WETSRA,DMOICE,DMLICE,LICETK,NTRACE,FZASRA(6)
     D             ,ID5(5),ITR(4),IMG(2),ILG(2),LAPGAS,KWVCON,NORMS0,NV
     E             ,KEEPRH,KEEPAL,ISOSCT,IHGSCT,KGASSR,KAERSR,KFRACC
     F             ,MARCLD,LAYRAD,NL,NLP,JMLAT ,IMLON ,KFORCE,LASTVC
C
C                                BASIC RADCOM INPUT DATA
C
     G             ,PLB(40),HLB(40),TLB(40),TLT(40),TLM(40),U0GAS(40,9)
     H             ,ULGAS(40,9),TRACER(40,4),CLDTAU(40),SHL(40),RHL(40)
     I             ,POCEAN,PEARTH,POICE,PLICE,AGESN,SNOWE,SNOWOI,SNOWLI
     J             ,TGO,TGE,TGOI,TGLI,TSL,WMAG,WEARTH,ZOICE,FSPARE(200)
     K             ,S0,COSZ,PVT(11),BXA(153),SRBXAL(15,2),FRC(5),LUXGAS
     L             ,JYEAR,JDAY,JLAT,ILON,MEANAL,KALVIS,ISPARE(25),PSIG0
C
C                                BASIC RADCOM OUTPUT DATA
C
     M             ,TRDFLB(40),TRUFLB(40),TRNFLB(40),TRFCRL(40),TRSLCR
     N             ,SRDFLB(40),SRUFLB(40),SRNFLB(40),SRFHRL(40),SRSLHR
     O             ,SRIVIS,SROVIS,PLAVIS,SRINIR,SRONIR,PLANIR,SRXATM(4)
     P             ,SRDVIS,SRUVIS,ALBVIS,SRDNIR,SRUNIR,ALBNIR,FSRNFG(4)
     Q             ,SRTVIS,SRRVIS,SRAVIS,SRTNIR,SRRNIR,SRANIR,FTRUFG(4)
     R             ,TRDFGW,TRUFGW,TRUFTW,BTEMPW,TRDFSL,TRUFSL,DTRUFG(4)
     S             ,TRSLTS,TRSLTG,TRSLWV,TRSLBS,TTRUFG,LBOTCL,LTOPCL
C
C                                BLOCKD INITIALIZED DEFAULT DATA
C
      COMMON/BLOCKD/AGOLDH(11, 5),BGOLDH(11, 5),CGOLDH(11, 5)
     T             ,TRAQEX(25,11),TRAQSC(25,11),TRACOS(25,11)
     T             ,TRCQEX(25, 2),TRCQSC(25, 2),TRCCOS(25, 2)
     S             ,SRAQEX( 6,11),SRAQSC( 6,11),SRACOS( 6,11)
     S             ,SRCQEX( 6, 2),SRCQSC( 6, 2),SRCCOS( 6, 2)
     X             ,AOCEAN(25   ),AGSIDV(25, 4),CLDALB(25, 2)
     Y             ,CMANO2(42   ),TRACEG(25,16),PPMV58(9),Z0(9),ZH(9)
     Z             ,ASNALB(15),AOIALB(15),ALIALB(15),NAERO,NGOLDH,NKSR
C
      COMMON/WORK4/ ITLB(40),ITLT(40),PL(40),DPL(40),UO3L(40),PSIG(40)
     T           ,COSLAT(46),TRCALB(40),TRGALB(40),BGFEMT(40),BGFEMD(40)
     T             ,TRAEXT(40,25),TAUN(1000),TAUSL(25),FTAUSL(25)
     T             ,ENA(40),ENB(40),ENC(40),TRA(40),TRB(40),TRC(40)
     T             ,WTLB(40),WTLT(40)
     T             ,DFLB(40,25),UFLB(40,25),WFLB(40,25)
     T             ,DFSL(25),UFSL(25),WFSL(25)
     S             ,EXTAER(40,6),SCTAER(40,6),COSAER(40,6),PI0AER(40,6)
     S             ,RNB(40),RNX(40),TNB(40),TNX(40),XNB(40),XNX(40)
     S             ,SRB(40),SRX(40),VRU(40),VRD(40),FAC(40),O3A(40)
     S             ,BVSURF,BNSURF,XVSURF,XNSURF
     X             ,UXGAS(40,9),SRTAU(600)
C
C
      COMMON/TRDCOM/TRAX(40,25,5),TRCX(25,2),PLANCK(6250),TAUTBL(80000)
     A             ,TAULAP(1000),TKPFW(630)
     B             ,ITRHDR(100),MLGAS(30),MLLAP(30),NKTR,IT0,ITNEXT
     C             ,JNORTH,ALVISD(22),ALNIRD(22)
C$   D             ,ISRHDR(100),SRTBL(44800)
C

in Conclusion

OK, that’s enough for this one posting. The others will most likely get into the actual formulas and operations applied. There will be some kind of “load the data into the arrays” process, then a “stir the pot” and finally a “dump out the stew”, but at this point it is likely we have some clue about the goals and drivers of the program. It ASSUMES that FORCING will be via “Greenhouse Gasses” and that not much else is a driving parameter. Much of the rest will be ‘tuned’ values to let the GHG fantasy unfold as desired / expected.

Having read the Hansen paper about the model, that is much of what it says, reading between the lines. Things like “vegetation has to be like this or things are not right” and “temperatures were 15 degrees too high in the arctic until we tuned FOO”. More on that paper in a later posting too. (It is a PDF and quoting them can be a pain, so I put it off…)

For now, We’ve got a pretty good handle on the nature of the model.

Left to do?

-rw-r--r-- 1 chiefio chiefio 240095 Apr 17  2008 DB11pdC9.f
-rw-r--r-- 1 chiefio chiefio  13208 Aug  2  2005 FFT36macDBL.f
-rw-r--r-- 1 chiefio chiefio 204365 Mar 23  2006 Mjal2cpdC9.f
-rw-r--r-- 1 chiefio chiefio 331692 Jan 17  2006 Pjal0C9.f
-rw-r--r-- 1 chiefio chiefio 555793 Aug  2  2005 R83ZAmacDBL.f
-rw-r--r-- 1 chiefio chiefio 128314 Aug  2  2005 RFRCmacDBL.f

The FFT* program (that does a Fast Fourier Transform… I peeked ;-) and then 5 other large chunks. Each of them likely to take a whole posting just by themselves. They range from 1600 to just under 7000 lines each, so I’m unlikely to quote them in their entirety…

With that, I’m off for a cupp-a and some sofa time… ;-)

Subscribe to feed

About E.M.Smith

A technical managerial sort interested in things from Stonehenge to computer science. My present "hot buttons' are the mythology of Climate Change and ancient metrology; but things change...
This entry was posted in AGW and GIStemp Issues, GCM, Tech Bits and tagged , , , . Bookmark the permalink.

25 Responses to Inside GCM Model II

  1. E.M.Smith says:

    I did a quick “look ahead” at the remaining bits with:

    sh-4.3$ for i in FFT36macDBL.f DB11pdC9.f Mjal2cpdC9.f Pjal0C9.f RFRCmacDBL.f 
    > do
    > echo 
    > head -50 $i
    > read ANS 
    > echo
    > done
    

    To just look at what was in the headings. The FFT has already been discussed a bit:

    From a bit further down than the header…

          SUBROUTINE FRTR (F)
    c  ** THIS SUBROUTINE PERFORMS A FOURIER ANALYSIS ON THE ONE DIMENSIONAL
    c  ** ARRAY F WHICH MUST BE DIMENSIONED 36.  IT RETURNS IN F THE ENERGY
    c  ** ASSOCIATED WITH EACH WAVE NUMBER.  UPON ENTERING THIS ROUTINE,
    c  ** THE TOTAL ENERGY IS
    c  **   .5*SUM(F(K)*F(K))
    c  ** WITH THE SUM BEING TAKEN OVER ALL K FROM 1 TO 36.  UPON LEAVING
    c  ** THIS ROUTINE, THE TOTAL ENERGY IS
    c  **   SUM(F(N+1))
    c  ** WITH THE SUM BEING TAKEN OVER ALL WAVE NUMBERS FROM 0 TO 18.
    

    It is essentially just a math library…

    For DB11pdC9.f we get:

    c  ** MODEL II FINE GRID DIAGNOSTICS WITH HALF-BOX SHIFT IN LONGITUDE
    c  ** subroutines in DB11F9: IJMAP
    c  ** DA94C9  BA94C9 DA94M9                  12/20/89
    c  ** OPT(3)
    c  **
    c  ** MODEL II FINE GRID DIAGNOSTICS
    c  ** subroutines in DA94F9: all diagnostics routines
    c  ** Model II diagnostics in double precision for work station  7/19/91
          SUBROUTINE DIAGA (U,V,T,P,Q)
    c  **                                                             IDACC
    

    Seems to be some kind of diagnostic thing for post mortems? Or perhaps analysis inside the body of stuff somewhere…

    Then Mjal2cpdC9.f

    C DYNAM broken into subroutines
    [...]
    c  ** 11/27/01 deep ocean, kocean=2 (MFS/GLR)
    c  ** 01/11/02 failed attempt to fix things (reverted) (MFS)
    c  ** 01/14/02 fixed error message (MFS)
    c  ** 01/15/02 fixed restart (MFS/RAR)
    c  ** 02/05/02 restart bug fixed (RAR)
    c  ** 02/07/02 :oda: -> :ocean: (MFS)
    c  ** 02/13/02 OHT multiplier (deleted) (MFS/GLR)
    c  ** 02/14/02 trend code, deep ocean fixes (MFS)
    c  ** 02/19/02 trend code with debug, fixes (MFS)
    c  ** 02/27/02 new trend code, data file trends only (MFS)
    c  ** 05/27/02 try old S0X & old trends (MSC)
    c  ** 06/03/02 put back mostly old trend code (MSC/MFS)
    c  ** 06/07/02 add ktrend to the namelist (MSC/MFS)
    c  ** 06/12/02 more trend fixes, path fixes (MFS)
    c  ** 06/14/02 found year bug that killed trends (MFS)
    c  ** 06/17/02 Andy says keep 1958 as the default for trends (MFS/AAL)
    c  ** 06/27/02 trend still don't work, remove (MFS)
    c  ** 06/28/02 older radiation, 20 char run numbers (MFS)
    c  ** 07/01/02 pass ktrend again to keep it in scope (MFS)
    c  ** 07/03/02 allow you to bypass trend code (MFS)
    c  ** 07/23/02 Xserve test version (MFS)
    c  ** 07/24/02 call to writer when trends change (MFS/RAR)
    c  ** 09/18/02 disable calls to writer (MFS)
    c  ** 09/26/02 command line version for MacOS X/IRIX (MFS)
    c  ** 09/28/02 put in Jeff's RANVAX to replace Power series RANDU (MFS)
    c  ** 04/08/04 2nd order version, modular dynamics, diag fixes,
    c  **          observed ocean mode, drag preserves wind direction (JAL)
    c  ** 04/09/04 merged in changes from MP030b (MFS/JAL)
    c  ** 05/06/04 setpath for PC support (MFS)
    c  ** 05/07/04 options experiment, works (MFS)
    c  ** 05/19/04 climatological change (JAL)
    c  ** 05/20/04 eccentricity, axial tilt, and omegat (JAL)
    

    Has had a LOT of modifications of the years, so a big one to look at. Looks like it is related to oceans, radiation, earth orbital position, etc. etc. I’d rank this one as “most interesting”…

    Then there is Pjal0C9.f :

          SUBROUTINE CONDSE                                                 2001.   
    C****                                                                   2002.   
    C**** THIS SUBROUTINE MIXES AIR CAUSED BY MOIST CONVECTION, AND         2003.   
    C**** CALCULATES PRECIPITATION AND CLOUD COVER DUE TO CONVECTIVE        2004.   
    C**** AND SUPER SATURATION CLOUDS.                                      2005.   
    C****                                                                   2005.5  
          INCLUDE 'BA94jalC9.COM'                                           2006.   
          REAL*8 LHX,LHXUP,MPLUME,MCLOUD                                    2008.   
          COMMON U,V,T,P,Q                                                  2009.   
          COMMON/WORK1/CONV(IM,JM,LM),PK(IM,JM,LM),PREC(IM,JM),             2010.   
         *  TPREC(IM,JM),UC(IM,JM,LM),VC(IM,JM,LM)                          2011.   
    

    I’d call that one the condensation / precipitation block. Likely also of interest, especially given that moisture at altitude after condensation is one of the mistakes they (GISS) make. The upper air gets dryer, not wetter. So likely the ‘issue’ with that topic is in this module… somewhere…

    Finally RFRCmacDBL.f :

    C**** RFRCDBL B83XXDBL RFRCDBL                      2/24/92                0.1  
    C**** OPT(3)                                                               0.2  
    C****                                                                      0.3  
    C**** Atmospheric forcing by trace gases and volcanoes 1850-2000           0.4  
    ***** RFRCDBL B83XXDBL RFRCDBL                      2/24/92                0.1  
    ***** OPT(3)                                                               0.2  
    *****                                                                      0.3  
    ***** Atmospheric forcing by trace gases and volcanoes 1850-2000           0.4  
          SUBROUTINE FORSET(TREF,KTREND,KWRITE)                                1.   
          INCLUDE 'B83XXDBL.COM'                                               2.   
    C                                                                          3.   
          DIMENSION XNOW(5),XREF(5),XDT0(5),XDAT(5),XRAT(5),KFOR(5)            4.   
          DIMENSION YNOW(5),YREF(5),ZNOW(5),ZREF(5),YDT0(5),ZDT0(5)            5.   
          DIMENSION QREF(5),QNOW(5)                                            6.   
    C                                                                          7.   
          LAPGAS=2                                                             8.   
          NGAS=5                                                               9.   
          DO 110 I=1,NGAS                                                     10.   
          YREF(I)=1.D-10                                                      11.   
          YNOW(I)=1.D-10                                                      12.   
          ZREF(I)=1.D-10                                                      13.   
      110 ZNOW(I)=1.D-10                                                      14.   
    

    Looks like this one is where all the GHG Forcing is added in. So it’s of interest too.

    OK, so that’s the big bits in “scratch and sniff” form… Looks like other than a cursory look at the FFT code and the Diagnostics (mostly to make sure there isn’t something unexpected hiding down in it somewhere…) the guts of it are the other three. One that does {something} with trend stuff and needs to be looked at just to see what it really does, one Precipitation model block, and one GHG Driver as the core goal maker.

    I’ll likely do the first three as a quick look and comment, then the other two in some depth. Unless, of course, one of the first three has a big point to make ;-)

    With that, I’m again taking a break for the early afternoon.

    I think I’ve got a pretty good handle on the general layout and function of this model maker. Next comes some deeper dives into the guts portions… but only after some recreation / offsite / SUN! it’s only out for a couple of hours, go get in it!!! time…

  2. Larry Ledwick says:

    On the exponent to .286 item I think you will find it has to do with :

    Potential temperature (aka Poisson's Equation)
    
    PT = T(1000/P)^Rd/cp = T(1000/P)^0.286
    T = temperature in Kelvins
    P = pressure in millibars
    Rd = gas constant for dry air
    Cp = constant pressure process
    
    Interpretation: Potential temperature is the temperature a parcel of air will have if raised or lowered to the 1000-millibar level. Potential temperature is the same for a parcel of air, as it rises or sinks, assuming adiabatic conditions.
    *Potential temperature decreasing with height is an indication of atmospheric instability
    
    Example Problem: What is the potential temperature of an air parcel at 500 mb that has a temperature of 0° C.
    
    Answer: PT = (273° K)(2)^0.286 = 333° K 
  3. Larry Ledwick says:

    That exponent is used in calculations related to adiabatic compression:

    Click to access Ch03-Slides-4.pdf

  4. E.M.Smith says:

    @Larry:

    Thanks for that… One Less Mystery to explore and research…

    Questions expand exponentially… capacity only linear, if at all…

  5. Glenn999 says:

    sorry off topic
    Brendan Eich who was fired from Mozilla for donating to a DOMA group, has launched a new browser called Brave.
    https://brave.com/

  6. E.M.Smith says:

    @Glenn999:

    Um, there’s a place for Off Topic Tips, it’s called “tips”… Latest is at the top of the list under the Category Tips (see the side bar for a list of categories) or click on T at the top of all the postings…
    https://chiefio.wordpress.com/category/tips/

    T

    While the Defense Of Marriage Act is important to a lot of folks, from both sides, it isn’t even tangentially connected to the guts of the GCM Model II… Though I suppose you could say it is a computer code so both involve computers…

    BTW, there’s dozens of “alternative” browsers, so he’ll need to have a “something special” to make it above the noise…

  7. Pingback: Brave Browser has Promise | Musings from the Chiefio

  8. E.M.Smith says:

    Oh, this is cute…

    I’m reading those large blocks of code that I referenced a comment or three above. Most of it is just fine. Dense and cryptic at times (with lots of variables that have one to 3 character names devoid of meaning…) but generally well commented and an orderly design. Then you run into bits of comment by the typical “maintenance programmer” who had to fix something or add something and found a bit of a mystery. But copes as best one can and “carries on”… but leaves a “here there be Dragons” marker for the NEXT maintenance programmer who might come by and wonder why that last guy did what was done…

    In Mjal2cpdC9.f

    c  ** MFS (CHANGED)
    c  ** For some reason the qflux/sst code used IF(KSS6.EQ.1) GO TO 800.
    c  ** I don't know why the MODRD.EQ.NRAD-NDYN was added.
    c  ** the old code in this model was
    c      IF(KSS6.EQ.1) GO TO 800                                             62.   
    c  ** but the old code in the deep ocean model was
    c      IF(KSS6.EQ.1.AND.MODRD.EQ.NRAD-NDYN) GO TO 800                      62.   
          IF(KOCEAN.EQ.2) THEN
            IF(KSS6.EQ.1.AND.MODRD.EQ.NRAD-NDYN) GO TO 800            
          ELSE
          IF(KSS6.EQ.1) GO TO 800                                             62.   
          END IF   
    c  ** END (CHANGED)
    

    Gee, one hopes someone knows why the line of code was changed… and what effect it had…

    Ah well, as code ages and gets molested by many hands, more such things accumulate. It is absolutely ordinary and doesn’t have any nefarious overtones. Just “someone” spent hours (or sometimes days) figuring out that a change was needed, but didn’t leave a comment about it; then someone else comes along and decides not to spend hours (or days…) figuring out what the first person figured out… but drops a note in passing that there’s a bit of undocumented dragon sleeping here…

    Ah, the life of the programmer… So “sometime” I’ll need to figure out what KSS6 is, and what KOCEAN does ( I think it is an integer flag for deep vs shallow ocean – how many layers of ocean to model – but I’m not sure…) and then the mysteries of NRAD-NDYN and MODR can be sorted… All integer values (first letter between I and N) so maybe RADiative (soimething) and DYNamic (something) and what would ODRxxxx be? Maybe tomorrow ;-)

    BTW, this program looks to do the bulk of the ‘setting up’ and various steps like resetting arrays to empty at time boundaries. It’s a candidate for the top level control program. ( I have 2 more to look at to confirm that…)

  9. E.M.Smith says:

    It looks like Pjal0C9.f is a collection of subroutines to do various of the physics bits. Plumes of water vapor laden air into clouds, freezing ground, precipitation, etc. etc. It’s the place where one would look to find the “errors of physics” IMHO. (The outer wrapper calling those routines mostly just doing a coordinative / iterative management role).

    After this cursory scan, I’m going back to that one to look for how high altitude moisture increases in the model, when it decreases in the real world.

    OK, only one more to go…

    Maybe after a fresh cup of coffee… my brain wants a rest ;-)

  10. E.M.Smith says:

    Hmmm…. R83ZAmacDBL.f looks like the ‘guts’ of many of the higher order functions. It has a load of subroutines in it that call functions (other subroutines) specified in some of the other programs. Sort of like they are the physics library and this one stitches them together into processes that are run by the outer timing loop…

    It looks like this bit sets the level of water in the air, globally:

    C---------------------------------------------------------------------   713.   
    C     DEFINE GLOBAL MEAN GAS AMOUNTS FOR TRACEGAS & OVERLAP ABSORPTION   714.   
    C---------------------------------------------------------------------   715.   
    C                                                                        716.   
    C                                         ----------------------------   717.   
    C                                         GLOBAL MEAN H2O DISTRIBUTION   718.   
    C                                         ----------------------------   719.   
          RHP=0.77                                                           720.   
          EST=10.0**(9.4051-2353.0/TLB(1))                                   721.   
          FWB=0.662*RHP*EST/(PLB(1)-RHP*EST)                                 722.   
          DO 111 L=1,NL                                                      723.   
          PLT=PLB(L+1)                                                       724.   
          DP=PLB(L)-PLT                                                      725.   
          RHP=0.77*(PLT/P0-0.02)/.98                                         726.   
          EST=10.0**(9.4051-2353.0/TLT(L))                                   727.   
          FWT=0.662*RHP*EST/(PLT-RHP*EST)                                    728.   
          IF(FWT.GT.3.D-06) GO TO 110                                        729.   
          FWT=3.D-06                                                         730.   
          RHP=FWT*PLT/(EST*(FWT+0.662))                                      731.   
      110 ULGASL=0.5*(FWB+FWT)*DP*1270.                                      732.   
    C$110 ULGASL=0.5*(FWB+FWT)*DP*1268.75                                    733.   
          U0GAS(L,1)=ULGASL                                                  734.   
          SHL(L)=ULGASL/(ULGASL+1268.75*DP)                                  735.   
          EQ=0.5*(PLB(L)+PLT)*SHL(L)/(0.662+0.378*SHL(L))                    736.   
          ES=10.**(9.4051-2353./TLM(L))                                      737.   
          RHL(L)=EQ/ES                                                       738.   
      111 FWB=FWT                                                            739.   
      112 CONTINUE                                                           740.   
    

    Though I’m not yet loaded up with the Data Dictionary (i.e. I need to memorize all those variables and figure out what they do…) so can’t say just which of these lines does what… yet.

    But, I’d guess that one of those lines with a ‘magic number’ in it sets the high altitude water vapor too high. for example, I’m wondering where the numbers in these lines come from:

          EQ=0.5*(PLB(L)+PLT)*SHL(L)/(0.662+0.378*SHL(L))                    736.   
          ES=10.**(9.4051-2353./TLM(L))                                      737.   
          RHL(L)=EQ/ES                                                       738.   
    

    I’d guess that RHL has something to do with Relative Humidity? and then you have these two equations… so where do those numerical factors come from? Physics, or plug numbers? Or a bit of both. In any case, I think that bit of code is a nice place to start a “Dig Here!” on why it gets atmospheric humidity to rise with rising CO2 when in fact it falls…

    This program goes on to have routines that set aerosol levels and gas distributions and such. It even looks like it does the clouds:

    C-----------------------------------------------------------------------1143.   
    C                            GET CLOUD & AEROSOL AMOUNTS & DISTRIBUTIONS1144.   
    C-----------------------------------------------------------------------1145.   
          LBOTCL=0                                                          1146.   
          LTOPCL=0                                                          1147.   
          DO 203 L=1,NL                                                     1148.   
          KCLD=1                                                            1149.   
          IF(TLM(L).LT.TKCICE) KCLD=2                                       1150.   
          IF(CLDTAU(NLP-L).GT.0.1) LTOPCL=NLP-L                             1151.   
    C$    IF(CLDTAU(NLP-L).GT.0.1) LBOTCL=NLP-L   *******************CORRECT1152.   
          IF(CLDTAU(    L).GT.0.1) LBOTCL=L                                 1153.   
    C$    IF(CLDTAU(    L).GT.0.1) LTOPCL=L   ***********************CORRECT1154.   
    C                                                (THERMAL)              1155.   
    C                                                ---------              1156.   
          DO 202 K=1,NKTR                                                   1157.   
          SUMEXT=1.D-30                                                     1158.   
          DO 201 J=1,NGOLDH                                                 1159.   
      201 SUMEXT=SUMEXT+FGOLDH(J)*TRAX(L,K,J)                               1160.   
          TRAEXT(L,K)=SUMEXT+CLDTAU(L)*TRCX(K,KCLD)*FCLDTR                  1161.   
      202 TAUN(L+(K-1)*NL)=TAUN(L+(K-1)*NL)+TRAEXT(L,K)                     1162.   
      203 CONTINUE                                                          1163.        
    

    Though it looks like at some time there was an argument over lines 1151 and 1153 since there are comments stuck in to remind folks what the “CORRECT” version are…

    It goes on to set ALBEDO for various places and has a SOLAR part that looks like it is just figuring out the angle and strength of the sun at a give cell.

    C                                                (SOLAR)                1181.   
    C                                                -------                1182.   
          KSR=9*KAERSR                                                      1183.   
          DO 212 K=1,NKSR                                                   1184.   
          DO 212 L=1,NL                                                     1185.   
          EXTSUM=1.D-30                                                     1186.   
          SCTSUM=1.D-40                                                     1187.   
          COSSUM=0.                                                         1188.   
          DO 211 J=1,NGOLDH                                                 1189.   
          EXTSUM=EXTSUM+FGOLDH(J+KSR)*SRAX(L,K,J)                           1190.   
          SCTSUM=SCTSUM+FGOLDH(J+KSR)*SRAS(L,K,J)                           1191.   
      211 COSSUM=COSSUM+FGOLDH(J+KSR)*SRAS(L,K,J)*SRAC(L,K,J)               1192.   
          EXTAER(L,K)=EXTSUM                                                1193.   
          SCTAER(L,K)=SCTSUM                                                1194.   
      212 COSAER(L,K)=COSSUM/SCTSUM                                         1195.   
          IF(NTRACE.GT.0) GO TO 300                                         1196.   
    C                                                                       1197.   
    C-----------                                                            1198.   
          RETURN   
    

    then it gets into trace items and computing fluxes and all. So the “meat” of it in terms of gas driven heating functions.

    C     ------------------------------------------------------------------1629.   
    C                                         WINDOW REGION FLUX COMPUTATION1630.   
    C     ------------------------------------------------------------------1631.   
    C                                                          DOWNWARD FLUX1632.   
    C     ------------------------------------------------------------------1633.   
          K=1                                                               1634.   
          BG=BGFEMT(K)                                                      1635.   
          WTS1=1.-WTS                                                       1636.   
    [... zeroing variables]  
          NLK=NL                                                            1645.   
          TRDFLB(NLP)=0.                                                    1646.   
      100 TAUA=TAUN(NLK)                                                    1647.   
          IF(TAUA.GT.1.D-05) GO TO 120                                      1648.   
          TRDFLB(NLK)=0.                                                    1649.   
          NLK=NLK-1                                                         1650.   
          IF(NLK.GT.NLK0) GO TO 100                                         1651.   
      110 NLK=NLK+1                                                         1652.   
    and a whole lot more...
    

    There’s a whole solar subroutine:

          SUBROUTINE SOLAR                                                  1958.   
    C-----------------------------------------------------------------------1959.   
    C          SOLAR RETURNS                                                1960.   
    C-----------------------------------------------------------------------1961.   
    C                       SRDFLB   SOLAR DOWNWARD FLUX AT LAYER BOTTOM    1962.   
    C                       SRUFLB   SOLAR UPWARD FLUX AT LAYER BOTTOM EDGE 1963.   
    C                       SRNFLB   SOLAR NET (DOWNWARD) FLUX (WATTS/M**2) 1964.   
    C                       SRFHRL   SOLAR HEATING RATE : FLUX (WATTS/M**2) 1965.   
    C                       SRRVIS   VISALB OF ATMOSPHERE (AS IF RSURFX=0.) 1966.   
    C                       SRTATM   ATMOS. TRANSMISSIVITY (TOTAL SPECTRUM) 1967.   
    C                       PLAVIS   PLANETARY ALBEDO 0.2-0.7 MICRON REGION 1968.   
    C                       ALBVIS   ALBEDO AT GROUND 0.2-0.7 MICRON REGION 1969.   
    C                       PLANIR   PLANETARY ALBEDO WAV>0.7 MICRON REGION 1970.   
    C                       ALBNIR   ALBEDO AT GROUND WAV>0.7 MICRON REGION 1971.   
    C-----------------------------------------------------------------------1972.   
    C                COMMENT                                                1973.   
    C-----------------------------------------------------------------------1974.   
    C                       SOLAR DATA IS RETURNED IN RADCOM LINES:  N,O,P,Q1975.   
    

    So lots of places to look for “plug number” adjustements…

    Places like here, that seems to have lots of “plug numbers” based on the values of water and whatever DSO is (double precision Sulfer Oxides? this thing could REALLY use a decent data dictionary)

    101  CONTINUE                                                          2162.   
    C--------K=6-------H2O       DS0=.01                                    2163.   
          TERMA=(35.66+TLN*(.0416-.0004622*TLN+.001057*PLN))*(1.+.04286*PLN)2164.   
          TERMB=(1.+.00171*ULN)*(1.+PLN*(189.088+.1316*PLN))                2165.   
          TAU1  =TERMA/TERMB                                                2166.   
          IF(TAU1.GT.0.02343) TAU1=0.02343                                  2167.   
          TAU=TAU1*ULN                                                      2168.   
          GO TO 120                                                         2169.   
     102  CONTINUE                                                          2170.   
    C--------K=5-------H2O       DS0=.03                                    2171.   
          TERMA=(2.792+TLN*(.0914-.0002848*TLN+.0003395*PLN))               2172.   
         +     *(1.+.02964*PLN)                                             2173.   
          TERMB=(1.0+.000657*ULN)*(1.+PLN*(240.70+.13847*PLN))              2174.   
          TAU1  =TERMA/TERMB                                                2175.   
          IF(TAU1.GT.0.00520) TAU1=0.00520                                  2176.   
          TAU=TAU1*ULN                                                      2177.   
          GO TO 120                                                         2178.   
     103  CONTINUE                                                          2179.   
    C--------K=4-------H2O       DS0=.04                                    2180.   
          TERMA=(.4768+.467D-04*PLN*TLN)*(1.+TLN*(.00191-.719D-05*TLN))     2181.   
          TERMB=(1.+.717D-04*ULN)*(1.+PLN*(130.56+.0876*PLN))/(1.+.0266*PLN)2182.   
          TAU1  =TERMA/TERMB                                                2183.   
          IF(TAU1.GT.0.00150) TAU1=0.0015                                   2184.   
          TAU=TAU1*ULN                                                      2185.   
          GO TO 120                                                         2186.   
     104  CONTINUE                                                          2187.   
    

    Oh, and then there is this interesting bit:

    C                                                                       2554.   
    C-----------------------------------------------------------------------2555.   
    C     SOLAR NET FLUX (SRNFLB(1)) DISTRIBUTION ACCORDING TO SURFACE TYPE 2556.   
    CR    NOT USED AND NOT SAFE (CAUSES DIVIDE CHECKS)                      2556.1  
    C-----------------------------------------------------------------------2557.   
    

    So they had “issues” with division when trying to set solar flux based on surface type, and just commented it out…

    In the Ozone section it has some big data blocks included, and even is nice enough to point to the reference for them. Then gets into seasonal albedos for various vegetation types. One wonders if they have seasonal transpiration of water vapor and seasonal thunderstorm formation and all the other seasonal changes in the hydrology of the planet, or are just fixated on things radiative… /snarc;

    After a few thousand lines of such data, you get to the Planck Flux calcs

          FUNCTION PFOFTK(WAVNA,WAVNB,TK)                                   4626.   
    C     ------------------------------------------------------------------4627.   
    C                                                                       4628.   
    C        INPUT DATA                                                     4629.   
    C                  WAVNA,WAVNB  SPECLTRAL INTERVAL IN WAVENUMBERS       4630.   
    C                               (ORDER OF WAVNA,WAVNB NOT IMPORTANT)    4631.   
    C                                                                       4632.   
    C                  TK           ABSOLUTE TEMPERATURE IN DEGREES KELVIN  4633.   
    C                                                                       4634.   
    C       OUTPUT DATA                                                     4635.   
    C                  PFOFTK       PLANCK FLUX (W/M**2)                    4636.   
    C                                                                       4637.   
    C                                                                       4638.   
    C           REMARKS                                                     4639.   
    C                   PLANCK INTENSITY (W/M**2/STER) IS GIVEN BY PFOFTK/PI4640.   
    C                                                                       4641.   
    C     ------------------------------------------------------------------4642.   
    

    After that is a long section called “Writer” that writes things out…

    There’s also a bunch of atmosphere stuff where it sets a bunch of atmosphere state and layers.

    Oh, this is an interesting bit. It sets the clouds and volcanoes… I’ve bolded an interesting point…

    C                               -------------------------------------   6099.   
    C                               NCLD:   CLOUD LAYER,TAU SPECIFICATION   6100.   
    C                               -------------------------------------   6101.   
       60 NCLD=LAST                                                         6102.   
          DO 61 L=1,NL                                                      6103.   
       61 CLDTAU(L)=0.                                                      6104.   
          IF(NCLD.GT.0) CLDTAU(NCLD)=64./2**NCLD                            6105.   
          RETURN                                                            6106.   
          END                                                               6107.   
          SUBROUTINE SETFOR(NFTFOR)                                         6108.   
          INCLUDE 'B83XXDBL.COM'                                            6109.   
    C     COMMON/TMINOR/FCO2,FN2O,FCH4,FF11,FF12,FVOL,FSUN                  6150.   
    C                                                                       6151.   
    C-----------------------------------------------------------------------6152.   
    C     EXTERNAL FORCING FOR  CO2,N2O,CH4,F11,F12,VOLCANIC AER,SOLAR CONST6153.   
    C     STARTING FROM  JAN 1,1880  PROJECTED THROUGH  DEC 31,2100         6154.   
    C     INPUT FORCING DATA READ IN FROM DISK DATA  DSN=CLIM.RUN.FORCING   6155.   
    C                                                                       6156.   
    C     CALL SETFOR  TO READ IN AND/OR INITIALIZE DATA AND/OR RESET PARAMS6157.   
    C                                                                       6158.   
    C     IF(NFTFOR.GT.0)  FORCING DATA WILL BE READ IN FROM DISKUNIT=NFTFOR6159.   
    C     IF(NFTFOR.EQ.0)  NO DATA READ, SELECT CONSTITUENTS FOR EXT FORCING6160.   
    C     IF(NFTFOR.LT.0)  NO DATA READ, RESET ONLY SOL CONST REFERENCE VALU6161.   
    C-----------------------------------------------------------------------6162.   
    

    So essentially you set the clouds, aerosols, etc., compute the solar angle, and then run the radiative processes based on your read in “forcing” plug numbers. Golly, wonder why it only finds gas forcing causing things… /sarc;

    C-----------------------------------------------------------------------6247.   
    C     EXTERNAL FORCING RETURNED FOR CONSTITUENTS PRESELECTED IN   SETFOR6248.   
    C                                                                       6249.   
    C            RADCOM  INPUT DATA:   JYEAR, JDAY                          6250.   
    C                                                                       6251.   
    C            RADCOM OUTPUT DATA:   FULGAS(K),K=2,6,7,8,9;  FGOLDH(1), S06252.   
    C                                                                       6253.   
    C-----------------------------------------------------------------------6254.   
    C                                                                       6255.   
          JDM=JDAY                                                          6256.   
          DO 210 JMONTH=1,12                                                6257.   
          IF(JDAY.GT.JDY(JMONTH)) GO TO 210                                 6258.   
          GO TO 220                                                         6259.   
      210 JDM=JDAY-JDY(JMONTH)                                              6260.   
          JMONTH=12                                                         6261.   
      220 MO=JMONTH+(JYEAR-1880)*12                                         6262.   
          IF(MO.LT.   1) MO=1                                               6263.   
          IF(MO.GT.2651) MO=2651                                            6264.   
    C                                                                       6265.   
          FRACYR=(JDAY-183)/365.                                            6266.   
          FRACMO=JDM/DMO(JMONTH)                                            6267.   
    C                                                                       6268.   
          NY=JYEAR-1880+1                                                   6269.   
          IF(JDAY.LT.183) NY=NY-1                                           6270.   
          IF(JDAY.LT.183) FRACYR=FRACYR+0.5                                 6271.   
          IF(NY.LT.  1) NY=1                                                6272.   
          IF(NY.GT.220) NY=220                                              6273.   
          FCO2=SCO2(NY)+(SCO2(NY+1)-SCO2(NY))*FRACYR                        6274.   
          FCH4=SCH4(NY)+(SCH4(NY+1)-SCH4(NY))*FRACYR                        6275.   
          FN2O=SN2O(NY)+(SN2O(NY+1)-SN2O(NY))*FRACYR                        6276.   
          FF11=SF11(NY)+(SF11(NY+1)-SF11(NY))*FRACYR                        6277.   
          FF12=SF12(NY)+(SF12(NY+1)-SF12(NY))*FRACYR                        6278.   
          FSUN=UPPM(NY)+(UPPM(NY+1)-UPPM(NY))*FRACYR                        6279.   
          FVOL=TAUM(MO)+(TAUM(MO+1)-TAUM(MO))*FRACMO                        6280.   
    C                                                                       6281.   
    C-----------------------------------------------------------------------6282.   
    

    So it is computing a “forcing” for each Magic Gas (FCO2, FCH4, etc.) based on the forcing values read in and then adjusted by the particular solar / radiative formulas. OK…

    There are then a bunch of blocks doing “cloud stuff” that at first glance look like large blocks of plug number data and then some fudge to smear it around / interact it with other drivers… maybe.

    C     ----------------------------------------------------------------  7265.   
    C     COSBAR ADJUSTMENT TO REPRODUCE THE SOLAR ZENITH ANGLE DEPENDENCE  7266.   
    C     FOR CLOUD ALBEDOS FOR OPTICAL THICKNESS FROM (1.0 < TAU < 99.0)   7267.   
    C     ----------------------------------------------------------------  7268.   
    C                                                                       7269.   
    C                                                                       7270.   
    C                          -------------------------------------------  7271.   
    C                          XMU (COSZ) SOLAR ZENITH ANGLE INTERPOLATION  7272.   
    C                          DATA INTERVAL:  0.02  ON  (0.0 < XMU < 1.0)  7273.   
    C                          -------------------------------------------  7274.   
    C                                                                       7275.   
          XI=XMU*50.0+0.9999                                                7276.   
          IX=XI                                                             7277.   
          IF(IX.LT.1) IX=1                                                  7278.   
          JX=IX+1                                                           7279.   
          WXJ=XI-IX                                                         7280.   
          WXI=1.0-WXJ                                                       7281.   
    C                                                                       7282.   
    C                                              -----------------------  7283.   
    C                                              CLOUD TAU INTERPOLATION  7284.   
    C                                              1.0 OVER (1 < TAU < 10)  7285.   
    C                                              LINEAR (10 < TAU < 100)  7286.   
    C                                              -----------------------  7287. 
    

    Then, at the bottom, is this interesting subroutine:

         SUBROUTINE ADDVOL                                                 7472.   
          DATA IFIRST/1/                                                    7473.   
          IF(IFIRST.EQ.1)                                                   7474.   
         *   WRITE(6,'(''0'',A28//)') '!!!! ADDVOL is NOT used !!!!'        7475.   
          IFIRST=0                                                          7476.   
          RETURN                                                            7477.   
          END                                                               7478.   
    

    One hopes that IFIRST is in a COMMON block somewhere or similarly has life beyond this subroutine, otherwise this routine would just print out that it isn’t used… I’m not sure what happens on subsequent calls, if the DATA continues to set the value or if the IFIRST=0 persists. It’s an odd little bugger in any case. I think I need to brush up on how FORTRAN handles data on nested / repeated subroutine calls.

    OK, with this, I’m done with the cursory digging. Now to contemplate for a day or two while the brain sorts it all and I think about other things… Hey, that’s how programming works. You load a bunch of this stuff rapidly and with mediocre understanding (mostly building the start of a Data Dictionary and Block Diagram in your brain) then let the subconscious stew on it a while. After that, filling in the details is much easier…

    So time for me to come up from the “coding frenzy” and rejoin the real world for a day or three..
    Just in time for the New Years! ;-)

  11. p.g.sharrow says:

    EMSmith;”Just in time for the New Years! ;-)”
    Lol for sure! A New Year with many new beginnings.
    There will be many upheavals for those that have had a cozy existance. Opertunity in the resulting chaos for those that can adapt to or guide the formation of the dawning new age. Have fun, And a prosperous New Year.
    We live in interesting times…pg

  12. Will Janoschka says:

    EMSmith,
    Thank you so much for such an effort! Just what was needed for a new year and a new president.

  13. Larry Ledwick says:

    Just out of curiosity, E.M. it looks like you are moving toward a “new” open source model over time as you dissect things and make sense out of the code, are you going to add your own comment blocks or a readme file that explains what you find as you go?.

    I have the sense that over time this is destined to morph into the “Chiefio base open source model”

    Then we can have a “battle of the bands” competition between the skeptics and the believers and see which of them comes up with the best model which more closely predicts real climate trends.

  14. cdquarles says:

    Okay, what do we know. We know that moist air has a lower lapse rate than dry air. We know moist air is more opaque, well, maybe not opaque over a large bandwidth, but definitely more absorbing. Absorbing in both directions. That, conditionally, locally heats the fictional parcel of air. Actually, the gas constituents (mostly molecular) that get additional kinetic energy simply move faster (higher kinetic energy being the definition of thermodynamic temperature and keep *that* separate from color/brightness temperature). That is why the lapse rate decreases (lapse rate being the change in local temperature above the ground as one goes upward as an adiabatic process). That’s why the theory projected a hot spot at altitude. Absorption of down-welling radiation with re-emission downward effectively is the same as no absorption energetically with a time delay. Absorption of down-welling radiation with re-emission upward effectively is the same, energetically as reflection, with a time delay. For the bulk, the effect is to clip the extremes, conditionally.

  15. E.M.Smith says:

    @Larry:

    You got it in one!

    Don’t know how far I’ll get. There’s only so much one old FORTRAN programmer can do… but I’m headed that way.

    FWIW, at this point I’m seeing MODEL II as mostly a ‘learning experience’ on the basics of the models. It is not at all set up for multiple cores / machines (so only the compiler will make things run on multiple cores as threads).

    Model E is already multiple machine ready and in a way that ought to work cross architectures. That means that a stack of Pi boards can all work together AND any old Intel boxes laying around can join in (as long as you put *NIX and MPI on them)

    Add that to the low core count needed if you just shut off the parts that Model II doesn’t do, and you can get a Model E that is runnable on a modest cluster.

    So while I’m going to continue doing a ‘dig here’ on Model II for a bit, I’ll likely try firing up Model E (reduced feature set as described in the NASA page) and see if I need to cut back the grid size, or if 12 to 16 Pi Cores is enough to get a modest run to run…

    As Model E comes with all the ‘fixings’, there’s no need to snarf up input / config files from somewhere else, and that’s one less thing to have rocks tossed about.

    Yes, the Model E source code is larger, but I’ve worked on bigger systems. It ought to be tractable. As usual “We’ll see”…

    So the general idea is:

    A) Get the generic Model to run.
    B) Adjust to dry upper troposphere / stratosphere to match reality.
    C) Add in Solar Flux Variation (likely as a UV vs IR spectral distribution of heating) with the driving cycle being from planetary alignment cycles.
    D) Tune to match history (i.e. make hindcasts right).
    E) Run and predict (or, pardon, “project”…) the future.

    Oh, and I’d add an F) of my usual tendency to add copious comments, written descriptions, and better structure as I find the need… but that’s distributed through the whole process. Then at some point I’ll make a ‘human narrative’ of what I think the code is doing. A posting for folks who never want to read a line of FORTRAN ;-)

    That’s the idea, anyway.

    As all things are subject to “Aw Shit!”s, any schedule is speculative…

    I’ve now got Devuan running where I want it, all on armhf code, so I can easily set up a ‘distcc’ between the 12 cores (need to add one $10 powersupply for 4 of them…) and then build ModelE to run across all twelve and see if it is enough for minimal runs, or not. (Size and performance profile on these cards). At that point I can “do the math” to figure what scale is needed for actual use. (All this in step A…)

    Then the rest begins…

    For now, though, it’s just poking around to see what they do in Model II and get their mode of thinking in mind. Likely I’ll make a modest written Data Dictionary and Block Diagram. That’s the basic structure for understanding what it’s up to.

    For anyone not familiar with it, Data Dictionary has a long history:
    https://en.wikipedia.org/wiki/Data_dictionary

    A data dictionary, or metadata repository, as defined in the IBM Dictionary of Computing, is a “centralized repository of information about data such as meaning, relationships to other data, origin, usage, and format.”[1] The term can have one of several closely related meanings pertaining to databases and database management systems (DBMS):

    A document describing a database or collection of databases
    An integral component of a DBMS that is required to determine its structure
    A piece of middleware that extends or supplants the native data dictionary of a DBMS

    It comes out of the IBM mainframe database world (no surprise I use the term, as in 1980s I was working on databases on IBM mainframes…). My extension of the use to a non-database product is a little unusual, but not much. Essentially any program is a collection of a data structure and an algorithm so that data structure can have a Data Dictionary made about it. For these programs, it’s the input data files and the variables that carry them.

    Block Diagram is self explanatory. Mostly it will just be listing the various subroutines, and what calls them when / where. Plus a bit about what each one does.

    I suspect that Model E will have very similar structure (same physics…) and mostly added modules to map (plus, likely, different variable names…)

    So no idea if this will end up chasing wild waterfowl, or will be something great… only time and effort will tell…

    @P.G.:

    Yup, I’m about 3 hours away from “Testing Whisky Stones” and some R&R ;-)

    @Will:

    Well, I hope this high level swoop past the code is helpful in some way to someone. It’s mostly going to be useful to me as a reference. Say, on January 2rd when I’m trying to remember what I’d done before January 1st came ;-)

    It does give a nice pointer to where someone might want to look into the code about any given process. Saves others that “swoop” time ;-)

    @CDQuarles:

    One thing I’ve not dug into enough yet, is the handling of mass flow of air up and down. IMHO that’s likely where there’s an issue. The reality is that convection is largely driven by humidity ( H2O is mass 18 while N2 is mass 28 ) not temperature. I need to check that they have that right. Then, as air rises, it gets colder and the water condenses out and falls as precipitation. Once dry enough that air then sinks. This, IMHO, is the key bit about dry air and not having water driven runaway thermal feedback. As long as the air is moist, it rises and rains out, until it isn’t. This assures dry air at altitude, not wet. IMHO the “problem” will be that they limit cloud rise and water loss, when in reality the top will just rise to where it dries… But that’s speculation on my part…

    I’ve got a nice page by a Met type that covers all the dry vs wet lapse rates and all and describes the process nicely. I need to compare that with what the code does… Maybe I’ll find that link and post a pointer article to it just so I don’t lose track of it ;-0

    Essentially, the model looks to be largely radiation focused (and driven) while IMHO reality is more mass flow and water driven. Outgoing radiation only being effective at the Top Of Troposphere / Stratosphere (by definition… that’s why we have a tropopause…)

    But that’s all several more steps down the road… I only got my Devuan base chips built today… next I customize it and add my tools, then add GIStemp (as a test case of build and Big-Endian compiler flags) and then add Model E and THEN get to try some things.

    Golly, for a guy with no job I sure have a lot of work to do!

    (Maybe I’ll test the Whisky Stones in one hour instead of 3… ;-)

  16. cdquarles says:

    Yep. It is radiation and radiation only as far as I can tell, relegating anything else as a factor to the circular file (and I suspect treating the radiative transfer inappropriately, too). I have not only an archive of EdGCM, I have one of ModelE as well, both obtained in 2008. I wonder what they’ve changed since then. Not only is there convection (vertical motion, better known as thermal up and down drafts), there’s advection (horizontal motion, better known as wind), too; and these are affected by relative composition and differential (local) heating.

    If they want to convince me from physics, they’d better be sure that the chemistry doesn’t get ignored where chemistry matters. It should follow from chemistry’s kinetic theory of gases. Hot air/gas rising (relatively) follows directly from it. Hot gas moves faster than cold gas.

    Thermodynamic temperature is the geometric mean of the constituent’s kinetic energy. KE = 1/2mv^2 as a first approximation and a boundary given from an ideal set of conditions far away from ‘relativistic’ speeds.

    I’m conflicted in trying to wrap my head around it now. I’m a decade older and a lot sicker than I was back then. About their handling of bulk flows via Navier-Stokes, see Dr. Gerald Browning’s work.

  17. Pingback: GCM Model II – DYNAM and the Dynamic Subroutines | Musings from the Chiefio

  18. E.M.Smith says:

    @CDQuarles:

    Would you have an example Model II “rundeck”?

    @All:

    Just an update: I’ve to the Model II to compile, and I’ve got what looks like most of the raw datasets for input. I’ve built a little script to do the set-up and execute, and run that script; at which time I got the first data sets needed identified and pin place.

    However…

    It demanded a “rundeck” and found I none… So I have to make one.

    It is a very long list of ‘settings’ to the model to make it do what you want. I’ve found a couple of example descriptions, though they come from a couple of different eras so don’t look at first blush like they agree in layout.

    That means I need to go into the code and decipher what this particular code demands, then give it that. Probably take me a few days to get around to it what with Valentines day and fence mending to do.

    Now you might think an example rundeck would be one of the “must include” bits of code and documentation… well, those who think would think so…

    It looks to me like the Model is a kit of tools to make a world as you like it, and they left out the rundeck since of course everyone will want to make their fantasy world different… Sigh.

    Well, at least it compiles without error and has not so far given any errors in execution other than “missing dataset” on input files…

  19. Larry Ledwick says:

    Which as you have mentioned countless times, sets up a situation where no two runs of the model would be the same (or could be recreated) unless you had a diagnostic output printout with each run that tells you what all the input parameters were.

    That shows why they depend on multiple runs and then presume that the average of all those runs means something. Without documentation of the run parameters of each model they are just useless numbers that look like data.

    Have you found if there is there any switch in the code you can flag to get it to dump the input values with each run? I don’t recall you ever mentioning any self documenting feature as the code runs.

    Ideally you would want something like this ballistics calculator does where it not only generates a table of all the calculated values but also what all the input values were to generate the table.

    http://www.jbmballistics.com/cgi-bin/jbmtraj-5.1.cgi

  20. E.M.Smith says:

    There is a large “Diagnostics” block of code that looks to save state information. It looks like the intent is to figure out why crazy runs went crazy so you can corral it back to the desired state.

    Near as I can tell, each researcher is expected to preserve their own “rundecks” and output…

    But the Diagnostics are the place to look.

    Once I have it doing something I’ll be paying more attention to the diagnostics part…

  21. E.M.Smith says:

    FWIW, here’s the place where I’ve gotten stuck in Mjal2cpdC9.f:

    C**** Read in Label and Namelist parameters from rundeck                 595.
    c  ** MAC (CHANGED)
    c  ** Open the namelist file this is file 110
    c      READ(5,'(A80)') NLREC(1),NLREC(2)                                  595.1
          OPEN(110,status='old',iostat=iosq)
          IF(IOSQ.NE.0) WRITE(6,*) 'Error opening unit 110 (Rundeck)'
          READ(110,'(A80)') NLREC(1),NLREC(2)
    c  ** END (CHANGED)
          NOFF=0                                                             595.2
          IF(NLREC(1)(73:80).EQ.'        ') NOFF=2                           595.3
          DO 55 I=1,20-NOFF                                                  595.4
       55 XLABEL(I)=NLREC(1)((4*I-3):(4*I))                                  595.5
          DO 56 I=1,12+NOFF                                                  595.6
       56 XLABEL(20-NOFF+I)=NLREC(2)((4*I-3):(4*I))                          595.7
          RUNID=XLABEL(1)                                                    595.9
          XLABEL(33) = ' '                                                   596.
          WRITE (6,'(A,33A4/)') '0',XLABEL                                   597.
    C**** COPY INPUTZ NAMELIST ONTO CORE TAPE AND TITLE PAGE                 598.
          IREC=0                                                             598.5
       60 IREC=IREC+1                                                        599.
    c  ** MAC (CHANGED)
    c      READ  (5,904) NLREC(IREC)                                          600.
          READ  (110,'(A80)') NLREC(IREC)
    c  ** END (CHANGED)
          WRITE (6,'(35X,A80)') NLREC(IREC)                                  601.
          IF (NLREC(IREC)(1:5).NE.' &END')  GO TO 60                         602.
    c     READ (NLREC,INPUTZ)                                                604.
          REWIND 8                                                           604.1
          WRITE(8,'(A)') (NLREC(IR),IR=1,IREC)                               604.2
          REWIND 8                                                           604.3
          READ (8,NML=INPUTZ)                                                604.4
          REWIND 8                                                           604.5
    c  ** MAC (ADDED)
          READ (110,NML=FORCINGS)
    c  ** END (ADDED)
    

    So you can see that the 110 input unit (which will be a file named ‘fort.110’ in normal use) is read for several iines of stuff to be decoded and some placed in the output as identifying information.

    At a first casual look it seems to include things from the name of the run, to forcings, to how many dimensions to use for things like grid cells (even though the model itself seems to be fixed in that regard… so some of these ‘parameters’ may be proforma…)

    So that’s the ravel I’m unraveling at the moment….

  22. cdquarles says:

    EM, I’ll check.

  23. cdquarles says:

    Hmm, I didn’t see anything that made “rundeck” obvious to me. From the EdGCM parts, itself, I suspect that fiddling with stuff in creating a ‘scenario’ is where one would get a sample “rundeck”. Given that I’ve never run this thing … well, that would explain why I don’t see something obvious.

  24. E.M.Smith says:

    Yeah, the EdGCM stuff looks to me like a wrapper to do the setup (i.e. order the data files and create a rundeck).

  25. cdquarles says:

    Okay, I bit the bullet and downloaded the EdGCM package again. I ran it this time. A ‘reference’ run took seconds. I zipped up the output. I’ll send that.

Comments are closed.