* XVARIABLES.CMN - COMMON/ XVARIABLES /
* array declarations and information for variables stored in memory and
* information on variables that can be computed
* variable-naming:
* 2/88 - removed "num_file_vars"
* 3/88 - modulo_var_pri 2000 --> 100000
* 7/88 - added mv_flink/blink and mblk_flink/size for
*	 efficient memory management  -  eliminated blk_in_use
*      - split into 3 distinct COMMON areas:
*	XBLOCK_MEM - with array memory, only
*	XMR	   - with memory variable information
*	XINTERP    - with instance table and interpretation stack information
* 8/88 - dummy_mr moved from FERRET.PARM to here
* 1/89 - added mr_unstand_grid and mr_regrid_trans
* V200:  5/89 - major changes for FERRET 2.00.  4D-symmetrical memory variables
* 	      - delete priorities handled through linked lists
*	      - eliminated "named" variables ("nvar")
*	      - all cvar-related stuff into XCALC_VARS
* 	 2/90 - max_uvars 20 --> 100
* V200 Unix/RISC port - eliminated REAL*8 boundary alignment problem
*		        by placing REAL*8 variables first
*    10/22/92 - added uvar_units, increased uvar_name_code to *24,
*	        increased max_uvar to 250
* V301: increased mem_blk_size x4  !!!
* V312: 5/17/94  removed "memory" array from COMMON altogether

* V402: 7/20/95 - added uvar_dset (for LET/D=...)
* V420: 11/95   - added hash pile for "un_cached" results
*	12/95	- added uvar_mod_pseudo to postpone modulo ops on uvars with
*		  pseudo vars X,Y,Z,T,I,J,K, or L
* V450: 7/97   - added uvar_parent and increates max_uvar
* V491: 12/97  - increased max_uvar_items from 40 to 100 *kob*
* v500: 3/99 - increased uvar_name_code, uvar_units to 64 and uvar_title
*              to 128
* V510: 8/99 *sh* allow other categories of cached mvars (mpv_nocache area)
*	12/99 *sh* added uvar_lo/hi_ss/ww and uvar_by_ss
*		(also fixed messed up comments)
* V510: 5/00 *sh* added variable uvar_bad_data
* V530: 8/00 *sh* added variable mr_c_pointer and mr_type
* 	10/00 *sh* - increased max_intrp to support more complex commands
*		     and uvar_text_len to support longer expressions
* V533: 6/01 *sh* added variable mr_delta
*	7/01 *sh* added variable uvar_data_type
* V534: 9/01 *sh* doubled default memory size
* v5.50 *acm*9/02 - up max_uvar from 400 to 2000
* v552  *acm4/03 - increase uvar_name_code to 128 (also change test in xeq_define)
* V600 2/06 *kob* - declare uvar_name_code_head etc as double, for 64-bit build
* V608 9/07 *acm*  increase uvar_text_len to 2048; var defs can contain long URLs
* V609 1/08 *acm*  increase max_mrs, pmv_npiles, max_intrp and max_uvar_items. 
*                  The first 3 of these needed for LAS scripts doing comparisons 
*                  along with seasonal averages; max_uvar_items reported once or 
*                  twice as a limit that users have run into.
* V61  3/08 *acm*  increase max_mrs again to 501.
* V62  2/09 *acm*  increase initial memory by 4.
* V671 7/11  *acm* Ticket 1868 IFV - masking expressions with ifValid, treating 
*		   zero as valid. 
*       2/12 *kms* Add E and F dimensions (set to nferdims);
*                  added mr_lo_s5 & 6, mr_hi_s5 & 6;
*                  reordered to remove padding
* V685 1/13  *acm* implement LET/REMOTE
* V690 9/13-1/14 *sh*  added aux var regridding,
*	           including is_aux_ptr, and uvar_curvi_var/cat
*		   added space at the top of the isp stack for nferdims auxvars

* Terminology:
*	"mr"	- "memory resident"
*	("mv")	  table of information about variables currently stored in
*		  memory
*	"mblk"	- related to management of array "memory" where bulk data is
*		  stored
*	"uvar"	- information about user-defined variables (and implicit user-
*		  defined variables given as command arguments)
*	"is"	- pertaining to the "interpretation stack" on which user 
*		  variables are evaluated, axis transformations are executed
*		  and grids in awkward planes are assembled

* BULK MEMORY MANAGEMENT:
*  The free bulk memory list is organized as follows:
*     o Each contiguous region of free memory is identified by its starting
*	block number in from array "memory" - usually "mblk"
*     o Each contiguous region of free memory contains its size (mblk_size)
*	and link pointers to the surrounding free regions (mblk_&link)
*     o The linked list is ordered by increasing mblk value
*  Bulk memory in use is removed from the free list.  Its starting block #
*   is found in "mr_blk1" (of the memory resident table) of the variable
*   using this memory.  Its size is redundantly stored (an historical artifact)
*   in both "mr_nblks" and mblk_size( start_block )

* MEMORY RESIDENT TABLE MANAGEMENT:
*  The slots of the memory variable table are organized as a number of doubly
*   linked lists using mv_flink & mv_blink.  When a variable is to be stored in
*   memory its context (data set, variable, category, etc.) is hashed to 
*   produce a pile number (which linked list contains it).  This greatly
*   reduces the number of table slots that must be searched locating a variable
*   in memory.  The start link for each list is in subscript -1*pile# of
*   mv_flink.
*  Unused table slots are organized into a singly linked list starting at
*   subscript 0 of mv_flink.

* DELETION PRIORITIES
*  Deletion priorities are handled through a doubly linked deletion priority
*   list.  The most recently used/acquired variables are added to the head of
*   the list indicating the lowest priority for deletion.  Variables may be
*   removed from the list if they are in-progress or in-use.  See mr_protected.

* explanation of selected variables:
*	mr_blk1     - First memory block of contiguous storage for this var.
*	mr_nblks    -	Number of contiguous storage blocks for this variable
*			See further documemtation in GET_MEMORY
*	mr_trans    - designates what mathematical transformations have been
*			applied to the data along each axis (see FERRET.PARM)
*	mv_flink      - forward and backwards links into the memory variable
*	mv_blink	table.  Stored variables are hashed into pmv_npiles
*			piles with start pointers stored in the negative
*			subscripts of these arrays
*	mblk_flink    - sizes and links of free contiguous regions
*	mblk_size	available in array "memory"
*	mblk_blink
*
*	mr_del_flink  -	forward and backwards links for the chain of variables
*	mr_del_blink	that are available to be deleted if memory space runs
*			short
*	mr_del_last_mblk - memory region freed by the last deletion
*	mr_del_last_size - size of that memory region
*
*	mr_protected  - flags variables as "deleted", "in_progress",
*			"perm_protrcted" or "not_protected".  Variables which
*			are needed as future components of calculations may
*			be reserved (protecting them from deletion) by
*			incrementing mr_protected.  This mechanism allows
*			multiple calculations to claim the same component and
*			still easily keep track of when all claims on the
*			component have been released.
*	
*       mr_naux   	- number of auxiliary variables used in regridding
*  	mr_aux_var,_cat	- var and cat of auxiliary vars (always in parent dset)
*	uvar_title	- title text for plots, etc. of user-defined variables
*	uvar_title_w_text
*			- logical to determine if variable definition is part 
*			  of title
*	uvar_name_code	- 128 character user variable name
*	uvar_units	- units string for variable
*	uvar_text	- text of the algebraic expression defining the variable
*	uvar_num_items	- number of "items" (functions,variables,operators,...)
*			  in the text
*	uvar_item_type	- coded (see alg_ in GFDLPROGRAM.PARM) item types
*	uvar_item_start	- positions in text for starts of item text substrings
*	uvar_item_end	- positions in text for ends   of item text substrings
*	uvar_grid	- defining grid for the expression
*	uvar_data_type	- data type for the expression
*	uvar_aux_var	- points to the curvi aux coord var for each axis
*	uvar_aux_cat	- points to the curvi aux coord var for each axis
*	uvar_aux_stat	- tells if aux axis has been regridded or remains free
*	uvar_need_dset  - flag if the uvar def'n is independent of dset
*	uvar_given	- indicate degree to which definition of uvar specifies
*			  limits along each axis
*	uvar_dset	- name of data set to which uvar **belongs** (7/95)
*	uvar_by_ss	- when uvlims are given in expression this tells how
*	uvar_lo/hi_ss	- when uvlims are given in expression this tells what
*	uvar_lo/hi_ww	- when uvlims are given in expression this tells what
*	uvar_bad_data	- missing value flag to be used for this variable
*	has_uvar_gc	- variable is a grid-changing variable

*	isp	 	- interpretation stack pointer
*	is_act   	- activity currently in progress
*	is_cx		- default context buffer at current stack level
*	is_big_cx	- context of full expression at current stack level
*	is_phase 	- current  looping value for stack level
*	is_obj   	- class of object for stack level
*	is_axis  	- grid axis of transformation for this level
*	is_uvar  	- pointer to text,name,etc. of uvar
*	is_mr		- pointer to memory grid for result
*	is_sum   	- stores a value that is accumulated at stack level
*	is_aux_ptr      - pointer to nferdims of curvilinear vars at stack top

*	uvar_remote	- is the user-variable a LET/REMOTE variable
*	rvar_on_server	- indicates if F-TDS server knows about the LET def
*	rvar_uvar	- associates the remote variable with a uvar
*	rvar_dset	- dataset that hosts the remote definition
*	rvar_varid	- netCDF var id of the remotely defined variable

********************************************************************************
******			PARAMETER DEFINITIONS				  ******

* memory storage capacity
	INTEGER		max_mrs,
     .			max_mr_avail,
     .			pmem_blk_size,
     .			pmax_mem_blks,
     .			pmv_npiles,
     .			pmv_nocache_pile,
     .			pmv_work_var_pile,
     .			pmv_adjoint_var_pile,
     .			pmv_lowest_head,
     .			dummy_mr
	PARAMETER     ( max_mrs   = 501,
     .			dummy_mr  = max_mrs,
     .			max_mr_avail = max_mrs - 1,
     .			pmem_blk_size = 2*(160*100*4/10), !2* 9/01 see ferret.h
     .			pmax_mem_blks   = 2000,
     .			pmv_npiles     = 299,	! prime # of hash piles
     .			pmv_nocache_pile = -pmv_npiles - 1,
     .			pmv_work_var_pile = -pmv_npiles - 2,
     .			pmv_adjoint_var_pile = -pmv_npiles - 3,
     .			pmv_lowest_head = -pmv_npiles - 5)  ! -4, -5 unused
! pmv_adjoint_pile reserved for future EF's returning multiple results

	INTEGER		max_uvar,
     .			max_uvar_items,
     .			uvar_text_len,
     .			max_intrp,
     .			max_rvar
	PARAMETER     (	max_uvar      	  = 2000,! total # uvars incl. "EX#."
     .			max_uvar_items    =  200,! complexity of uvar expression
     .			uvar_text_len	  = 2048,! max length of uvar expression
     .			max_intrp	  =  400 ,! max depth of interp stack
     .			max_rvar	  = 2000  )

********************************************************************************
******				COMMON DECLARATION			  ******

	COMMON / XMEM_DESCR /
     .		mem_blk_size,
     .		max_mem_blks

* Reordered as REAL*8, REAL (which may be REAL*8 or REAL*4), INTEGER, LOGICAL,
* CHARACTER to eliminate padding requirements from the compiler.
* uvar_name_code_head should be immediately followed by uvar_name_code_padding
* uvar_num_items_head should be immediately followed by uvar_num_items_padding
	COMMON / XMR / 
     .		mr_lo_ww	( nferdims, max_mrs ),
     .		mr_hi_ww	( nferdims, max_mrs ),
     .		mr_delta	( nferdims, max_mrs ),
     .		uvar_lo_ww	( nferdims, max_uvar ),
     .		uvar_hi_ww	( nferdims, max_uvar ),
     .		mr_c_pointer    ( max_mrs ),
     .          uvar_name_code_head,
     .          uvar_name_code_padding,
     .          uvar_num_items_head,
     .          uvar_num_items_padding,
     .
     .		mr_trans_arg	( nferdims, max_mrs ),
     .		mr_bad_data   	( max_mrs ),
     .		uvar_bad_data	( max_uvar ),
     .		is_sum  	( max_intrp ),
     .
     .		mr_trans	( nferdims, max_mrs ),
     .		mr_regrid_trans	( nferdims, max_mrs ),
     .		mr_lo_ss	( max_mrs, nferdims ),
     .		mr_hi_ss	( max_mrs, nferdims ),
     .		mr_protected	( max_mrs ),
     .		mr_blk1		( max_mrs ),
     .		mr_nblks	( max_mrs ),
     .		mr_data_set	( max_mrs ),
     .		mr_category	( max_mrs ),
     .		mr_variable	( max_mrs ),
     .		mr_grid   	( max_mrs ),
     .		mr_type   	( max_mrs ),
     .		mr_naux   	( max_mrs ),
     .		mr_aux_var	( nferdims, max_mrs ),
     .		mr_aux_cat	( nferdims, max_mrs ),
     .		mblk_flink      ( 0:pmax_mem_blks ),
     .		mblk_blink      ( 0:pmax_mem_blks ),
     .		mblk_size       ( 0:pmax_mem_blks ),
     .		mv_flink        ( pmv_lowest_head:max_mrs ),
     .		mv_blink        ( pmv_lowest_head:max_mrs ),
     .		mr_del_flink    ( 0:max_mrs ),
     .		mr_del_blink    ( 0:max_mrs ),
     .		mr_del_last_mblk,
     .		mr_del_last_size,
     .		num_uvars_in_cmnd,
     .		uvar_lo_ss	 ( max_uvar, nferdims ),
     .		uvar_hi_ss	 ( max_uvar, nferdims ),
     .		uvar_num_items   ( max_uvar ),
     .		uvar_parent	 ( max_uvar ),
     .		uvar_grid	 ( max_uvar, 0:max_gfdl_dsets ),
     .		uvar_data_type	 ( max_uvar, 0:max_gfdl_dsets ),
     .		uvar_aux_var	 ( max_uvar, nferdims, 0:max_gfdl_dsets ),
     .		uvar_aux_cat	 ( max_uvar, nferdims, 0:max_gfdl_dsets ),
     .		uvar_aux_stat	 ( max_uvar, nferdims ),
     .		uvar_item_start	 ( max_uvar_items, max_uvar ),
     .		uvar_item_end	 ( max_uvar_items, max_uvar ),
     .		uvar_item_type	 ( max_uvar_items, max_uvar ),
     .		uvar_given	 ( nferdims, max_uvar ),
     .		uvar_dset	 ( max_uvar ),
     .		uvar_remote	 ( max_uvar ),
     .		rvar_on_server	 ( max_rvar ),
     .		rvar_uvar	 ( max_rvar ),
     .		rvar_dset	 ( max_rvar ),
     .		rvar_varid	 ( max_rvar ),
     .          deleted_list_result(max_uvar),
     .          string_array_result(max_uvar),
     .		max_usable_intrp,
     .		isp,
     .		is_act		( max_intrp ),
     .		is_cx		( max_intrp ),
     .		is_big_cx	( max_intrp ),
     .		is_phase	( max_intrp ),
     .		is_obj  	( max_intrp ),
     .		is_axis 	( max_intrp ),
     .		is_uvar 	( max_intrp ),
     .		is_mr		( max_intrp ),
     .		is_aux_ptr 	( max_intrp ),
     .
     .		mr_unstand_grid	 ( max_mrs ),
     .		uvar_by_ss	 ( nferdims, max_uvar ),
     .		uvar_mod_pseudo	 ( nferdims, max_uvar ),
     .		uvar_ifv	 ( max_uvar ),
     .		uvar_title_w_text( max_uvar ),
     .		uvar_need_dset	 ( max_uvar ),
     .		has_uvar_gc,
     .
     .		uvar_text	 ( max_uvar ),
     .		uvar_title	 ( max_uvar ),
     .		uvar_name_code	 ( max_uvar ),
     .		uvar_units	 ( max_uvar )

********************************************************************************
******			COMMON VARIABLE TYPE DECLARATIONS		  ******

	INTEGER	mem_blk_size,
     .		max_mem_blks

	INTEGER	mblk_flink,
     .		mblk_blink,
     .		mblk_size

	INTEGER	mv_flink,
     .		mv_blink,
     .		mr_del_flink,
     .		mr_del_blink,
     .		mr_del_last_mblk,
     .		mr_del_last_size

	INTEGER		num_uvars_in_cmnd

	LOGICAL		mr_unstand_grid

	REAL		mr_bad_data  	,
     .			mr_trans_arg	,
     .			uvar_bad_data

	REAL*8		mr_lo_ww	,
     .			mr_hi_ww	,
     .			mr_delta	,
     .			uvar_lo_ww	,
     .			uvar_hi_ww	,
     .			mr_c_pointer      ! see note
! Note: the actual data type for mr_c_pointer is **char
! we allocate 8 bytes for 64-bit pointers

	INTEGER		mr_lo_ss	,
     .			mr_hi_ss	,
     .			mr_trans	,
     .			mr_data_set	,
     .			mr_category	,
     .			mr_variable	,
     .			mr_protected	,
     .			mr_blk1		,
     .			mr_nblks	,
     .			mr_grid 	,
     .			mr_type 	,
     .			mr_naux		,
     .			mr_aux_var	,
     .			mr_aux_cat	,
     .			mr_regrid_trans

	CHARACTER*128	uvar_title, uvar_name_code
	CHARACTER*64	uvar_units
	CHARACTER*2048	uvar_text	
	LOGICAL		uvar_title_w_text,
     .			uvar_need_dset,
     .			uvar_mod_pseudo,
     .			uvar_by_ss,
     .			has_uvar_gc,
     .			uvar_ifv,
     .			uvar_remote,
     .			rvar_on_server
	REAL*8          uvar_name_code_head,
     .                  uvar_name_code_padding,       
     .                  uvar_num_items_head,
     .                  uvar_num_items_padding
        INTEGER		uvar_num_items  ,
     .			uvar_grid	,
     .			uvar_data_type	,
     .			uvar_aux_var	,
     .			uvar_aux_cat	,
     .			uvar_aux_stat	,
     .			uvar_item_start	,
     .			uvar_item_end	,
     .			uvar_item_type	,
     .			uvar_given	,
     .			uvar_parent	,
     .			uvar_dset       ,
     .			uvar_lo_ss	,
     .			uvar_hi_ss      ,
     .                  deleted_list_result,
     .                  string_array_result,
     .			rvar_uvar,
     .			rvar_dset,
     .			rvar_varid

	INTEGER		isp,
     .			max_usable_intrp,
     .			is_act  ,
     .			is_cx ,
     .			is_big_cx ,
     .			is_phase,
     .			is_obj  ,
     .			is_axis ,
     .			is_uvar ,
     .			is_mr,
     .			is_aux_ptr
	REAL		is_sum

* equivalences to assist with declaration statements
	INTEGER mr_lo_s1( max_mrs ),
     .		mr_lo_s2( max_mrs ),
     .		mr_lo_s3( max_mrs ),
     .		mr_lo_s4( max_mrs ),
     .		mr_lo_s5( max_mrs ),
     .		mr_lo_s6( max_mrs ),
     .		mr_hi_s1( max_mrs ),
     .		mr_hi_s2( max_mrs ),
     .		mr_hi_s3( max_mrs ),
     .		mr_hi_s4( max_mrs ),
     .		mr_hi_s5( max_mrs ),
     .		mr_hi_s6( max_mrs )
	EQUIVALENCE
     .		( mr_lo_s1, mr_lo_ss(1,1) ),
     .		( mr_lo_s2, mr_lo_ss(1,2) ),
     .		( mr_lo_s3, mr_lo_ss(1,3) ),
     .		( mr_lo_s4, mr_lo_ss(1,4) ),
     .		( mr_lo_s5, mr_lo_ss(1,5) ),
     .		( mr_lo_s6, mr_lo_ss(1,6) ),
     .		( mr_hi_s1, mr_hi_ss(1,1) ),
     .		( mr_hi_s2, mr_hi_ss(1,2) ),
     .		( mr_hi_s3, mr_hi_ss(1,3) ),
     .		( mr_hi_s4, mr_hi_ss(1,4) ),
     .		( mr_hi_s5, mr_hi_ss(1,5) ),
     .		( mr_hi_s6, mr_hi_ss(1,6) )

