The answer to your specific question, "what is the difference between ASDIR and ASDIF and the TOA albedo?" is that they are different quantities. ASDIR and ASDIF are the *surface* albedo, for direct and diffuse visible radiation, respectively. The planetary albedo, calculated from the fluxes at the top of the model include atmospheric scattering, including clouds, and so is very different from the surface albedo.
The answer to your more general question, the title of the topic here, is much more difficult to answer. There are a number of strategies, but ultimately the solution is to carefully read the source code. For this example, one could start by going into the CAM source code and doing a search for ASDIR or ASDIFF:
Code:
grep -Iinr --exclude="*.svn*" "ASDIR" .
is how I just did it.
That is just the beginning, since often the name shows up in many files. Where I usually start is by finding the OUTFLD call, which is where the field gets written to the history file. In this case, it's in cam_diagnostics:
Code:
./physics/cam/cam_diagnostics.F90:1810: call outfld('ASDIR', cam_in%asdir, pcols, lchnk)
Inspection there just shows that this is a convenience function, as it is just writing output from the cam_in data structure, so then I would look for where this subroutine is called:
Code:
$ grep -Iinr --exclude="*.svn*" "call diag_surf" .
./physics/simple/physpkg.F90:616: call diag_surf(cam_in, cam_out, state, pbuf)
./physics/cam/physpkg.F90:1170: call diag_surf(cam_in(c), cam_out(c), phys_state(c), phys_buffer_chunk)
That's always discouraging because physpkg is the high-level driver for the whole physics package. In this specific case, however, it's pretty telling that the routine is called diag_surf, but that might not always be the case. Reading around this part of CAM's physpkg, we would find that this call is in the subroutine phys_run2, and more closely looking shows that diag_surf happens just before tphysac. That's the physics that happens "after coupling". That leaves us with the question still of where asdir came from that goes into phys_run2. Another grep and we see that phys_run2 is called by cam_run2; that subroutine has a useful comment at the top:
Code:
!-----------------------------------------------------------------------
!
! Purpose: Second phase of atmosphere model run method.
! Run the second phase physics, run methods that
! require the surface model updates. And run the
! second phase of dynamics that at least couples
! between physics to dynamics.
!
!-----------------------------------------------------------------------
This is a strong hint that the albedo must involve the surface models and/or the coupler. It can be complicated to track things back through the coupler. Some additional inspection shows that asdir variable comes into CAM from the coupler in the atm_import subroutine of atm_import_export.F90.
Code:
cam_in(c)%asdir(i) = x2a(index_x2a_Sx_avsdr, ig)
And that index is mapped to the coupler's data structure in cam_cpl_indices.F90, it's called
At this point, it really becomes hard (for me at least) to follow all the paths. I think for this case, each component model is responsible for getting the surface albedos and passing them to the coupler where they get merged into the field that CAM imports. Finding the individual calculations takes a lot of time for various reasons, including the different styles that are used in the different component models.
One place where the calculation is more straightforward is for the ocean albedo. To see this, look at seq_flux_ocnalb_mct in cime/src/drivers/mct/main/seq_flux_mct.F90. This calculation is called from cime_comp_mod. Even here, there is a lot of logic that directs the calculation. One interesting bit in this case is that if calculation is done here for the direct beam albedo, the diffuse albedo must still come from the namelist, and it looks like the default value is 0.06 (unless it is an aquaplanet compset, in which case it is 0.07). Both can be specified in the driver namelist however, as seq_flux_mct_albdif and seq_flux_mct_albdir, and both have the same default values. Indeed, it looks like for common cases, like F2000climo, this is exactly how ASDIR and ASDIF are determined for ocean locations. Ice- and land-covered areas use their own calculations, as far as I can tell.