Refactor phys_buffer.F90

Current phys_buffer API:

     phys_buffer also provides public access to the derived pbuf field so there is code throughout cam physics that looks like:

         

real(r8), pointer, dimension(:,:) :: iciwpconv

iciwpconv  => pbuf(iciwpconv_idx)%fld_ptr(1,1:pcols,1:pver,lchnk, 1)

Limitations of current phys_buffer API:

The current pbuf API has several limitations that we would like to overcome.

  1. Only r8 variables are allowed, this should be extended to allow integers
  2. Dimensionality of variables is limited - the cam physics decomposition has pcols in the innermost dimension and chunks in the outermost.   Current design allows for a dimension inside pcols (almost never used), a dimension outside chunks (again almost never used) and a single dimension between them which is frequently overloaded to support 2 or more actual dimensions needed in this location.  The new API should remove the options of inner and outer dimensions and allow for a variable number of middle dimensions from 0 to some fixed but easily modifiable maximum. 
  3. The pbuf structure itself should not be public, functions in this module should provide pointers to or copies of individual fields in the structure.

(eaton, 4/5/11) I agree with this.

Comparison to other similar functionality:

The functionality of cam_history_buffers is very similar to that of phys_buffers - I would propose that a replacement be created with an eye toward replacing both. 

(eaton, 4/5/11) Not sure about this. Do you think that cam_history could directly use the pbuf?

(edwards, 4/8) I did, but the current discussion has moved away from that idea.  

Proposed new API:

(eaton, 4/5/11)

I don't see a need for pbuf_add_dim. That's a cam_history kind of functionality that isn't needed for the pbuf. The user of pbuf should never need to refer to the pbuf dimensions by name, or by an id. Only by size, just like for a Fortran array.

What is the 'decomp' arg of pbuf_add_var for?

I think it's reasonable to assume that pcols will be the first index of the data array. But I'm wondering whether we want to include the begchunk:endchunk dimension as part of the data array, or whether we should allocate the pbuf array with a begchunk:endchunk dimension so that it could be treated more like the physics state.

I'm not sold on pbuf_get_var_copy. I haven't seen any need for this to date. I'd prefer to have a minimal interface and require the user to copy data outside the pbuf interface if that's needed.

I think the pbuf_get method should return a pointer to the entire field by default, but provide optional array args, start/end, to allow access to an array subsection.

(eaton, 4/6/11)
Our discussion today largely focussed on the restart capability. One of the things I really like about the original pbuf design is that the user didn't need to be concerned about restart – as long as the pbuf field was 'global' scope it would end up in the restart file. I'd like to maintain this simplicity which is why I'm not in favor of the pbuf_add_dim method which requires the user to think about something that's only relevant for the restart file.

Here's another idea. What about removing all the restart methods from the pbuf module and just passing pbuf as an argument to the restart_physics methods. Let restart_physics be entirely responsible for getting the global pbuf fields to the restart file. This would be similar to what's currently done for the cam_out export fields which are also dealt with directly by the restart_physics methods.

Franis has convinced me that 'physpkg' and 'global' scope are not as obvious as using a terminology that implies fields are persistent or not (like the argument in Jim's proposed pbuf_add_var method). Scope is more a programming concept that most physical scientists aren't familiar with.