Scheduled Downtime
On Tuesday 24 October 2023 @ 5pm MT the forums will be in read only mode in preparation for the downtime. On Wednesday 25 October 2023 @ 5am MT, this website will be down for maintenance and expected to return online later in the morning.
Normal Operations
The forums are back online with normal operations. If you notice any issues or errors related to the forums, please reach out to help@ucar.edu

pbuf index initialization to be used in external module

nuvolet

Toni Viudez
Member
Greetings,

I am trying to use a subroutine (modal_aero_sw) which is in the module modal_aer_opt.F90 (CEAM2.2/CAM6) in order to extract some aerosols optical information (tauxar, wa, ga, fa), which I need.

call modal_aero_sw(list_idx, state, pbuf, nnite, idxnite, tauxar, wa, ga, fa)

This subroutine has some input parameters between one of them is pbuf.
Is there anyone who knows how to get initialized that pbuf input? Or I can call this subroutine without having and error like this when I try to create a case:

ERROR: GET_PBUF1D_FIELD_BY_INDEX: index (125) out of range

Looking at that module, it looks like pbuf is pointing

type(physics_buffer_desc), pointer :: pbuf(:)

and at the beginning of module modal_aer_opt.F90

use physics_buffer, only : pbuf_get_index,physics_buffer_desc, pbuf_get_field

I also found in this forum a threat similar, I believe, to my problem (Questions on physics_buffer), but I still do not get how to associate it to my question.

Thanks in advance
 

peverley

Courtney Peverley
Moderator
Staff member
Hi Toni,

From where are you trying to call the modal_aero_sw subroutine? The pbuf variable is passed around a lot in the physics code, so you should be able to grab it and pass it in to whatever module/subroutine you're working in.

If you tell me what routine(s) you're modifying, I can help more.

Courtney
 

nuvolet

Toni Viudez
Member
Hi Courtney,

I am trying to call the modal_aero_sw subroutine from the nudging.F90. As mentioned in my initial question I want to use tauxar (layer extinction optical depth), wa (layer single-scatter albedo), ga (asymmetry factor) and fa (forward scattered fraction).
I am modifying this nudging module (nudging.F90) in order to nudge aerosols.
Thanks

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Hi again Toni,

Thanks for the information. You should be able to pass pbuf into whichever subroutine you're editing in nudging.F90 via physpkg.F90. For example, if you're adding the modal_aero_sw call to nudging_timestep_tend, you can add pbuf to the calling list in physpkg.F90:

if ((Nudge_Model) .and. (Nudge_ON)) then
call nudging_timestep_tend(state,ptend,pbuf)
...

Then, in nudging.F90, you would add:

subroutine nudging_timestep_tend(phys_state,phys_tend,pbuf)
...
type(physics_ptend), intent(out):: phys_tend
type(physics_buffer_desc), pointer :: pbuf(:)

Does that help?
Courtney
 

nuvolet

Toni Viudez
Member
Hi Courtney,

I will try that suggestion to see if it works.
Therefore, besides to modify nudging.F90, I also have to modify physpkg.F90, right?
And then before I build the case send those 2 monied modules to the cime/scripts/$casename/SourceMods/src.cam/, right/?
Thanks in advance for your help.

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Yes, the first code block is a modification to physpkg.F90.

And yes, for ease of future use and reproducing your experiments, you'll want to put both of those files in SourceMods.

Courtney
 

nuvolet

Toni Viudez
Member
Hi again Toni,

Thanks for the information. You should be able to pass pbuf into whichever subroutine you're editing in nudging.F90 via physpkg.F90. For example, if you're adding the modal_aero_sw call to nudging_timestep_tend, you can add pbuf to the calling list in physpkg.F90:



Then, in nudging.F90, you would add:



Does that help?
Courtney
Hi again Courtney,

I tried your suggestion and now the error I got is when I declared other input parameters to call modal_aero_sw, in this case idxnite and nnite, where I get these error messages:

integer, intent(in) :: idxnite(nnite) ! local column indices of night columns
1
Error: Symbol at (1) is not a DUMMY variable

integer, intent(in) :: nnite(:) ! number of night columns
1
Error: Symbol at (1) is not a DUMMY variable

And

call modal_aero_sw(list_idx, state, pbuf, nnite, idxnite, &
1
Error: Rank mismatch in argument ‘nnite’ at (1) (scalar and rank-1)
gmake: *** [nudging.o] Error 1

At least I do not have more problems with pbuf

Thanks again for your help.

Toni
 

nuvolet

Toni Viudez
Member
Hi again Courtney,

I have been trying to look how complete the call to modal_aer_opt by these 2 other parameters (nnite and idxnite), and do not see where CAM gets those values?.
Do you know where I could get them?.

Thanks again in advance

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Hi Toni,

It may be helpful to use physics/rrtmg/radiation.F90 as an example. The code around line 900 uses the solar zenith angle to determine night/day column indices. You'll have to add "use" statements for any new subroutines you're calling (like get_rlat_all_p).

Hope that helps.

Courtney
 

nuvolet

Toni Viudez
Member
Hi Toni,

It may be helpful to use physics/rrtmg/radiation.F90 as an example. The code around line 900 uses the solar zenith angle to determine night/day column indices. You'll have to add "use" statements for any new subroutines you're calling (like get_rlat_all_p).

Hope that helps.

Courtney
Hi Courtney,

I made changes like you suggested, by adding in my nudging module the lines where using get_rlat_all_p and get cosine solar zenith angle for current time step, then I am able to have the parameters nnite and idxnite.
Nevertheless, I receive a new error inside the physpckg.F90 at the line the I included the pbuf parameters, like this:

call nudging_timestep_init(state,ptend,pbuf)
1
Error: Rank mismatch in argument ‘phys_state’ at (1) (rank-1 and scalar)

I wonder if this mismatch is in the nudging.F90 module I am modifying and when is called by physpkg.F90 or in the physpkg.F90 itself?.

Thanks in advance for you priceless help.

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Hi Toni,

The phys_state input variable to nudging_timestep_init() is an array of physics_state variables. It looks like you're trying to call nudging_timstep_init() from tphysac (is that correct)? In tphysac, the state variable you have is of dimension 1.

Instead of calling nudging_timestep_init() from tphysac, it should work to call it from phys_run2, where you have the full array of state variables.

Does that help?

Courtney
 

nuvolet

Toni Viudez
Member
Hi Courtney,

I will try but I see that the only place in physpkg.F90 where the nudging is updated is in tphysac.
Additionally it is where pbuf is sued, while in physical_run2 is pbuf2d.
I will see what I can get.

Thanks in advance.

Toni
 

nuvolet

Toni Viudez
Member
Hi Toni,

The phys_state input variable to nudging_timestep_init() is an array of physics_state variables. It looks like you're trying to call nudging_timstep_init() from tphysac (is that correct)? In tphysac, the state variable you have is of dimension 1.

Instead of calling nudging_timestep_init() from tphysac, it should work to call it from phys_run2, where you have the full array of state variables.

Does that help?

Courtney
OK, I commented all the lines I made for calling nudging_timestep_init() from tphysac, which include:

Code:
!     use nudging,            only: Nudge_Model,Nudge_ON,nudging_timestep_tend,nudging_timestep_init
...
    ! Update Nudging values, if neededs
    !----------------------------------
    if((Nudge_Model).and.(Nudge_ON)) then
      call nudging_timestep_tend(state,ptend,pbuf)     
!       call nudging_timestep_init(state,ptend,pbuf)
      call physics_update(state,ptend,ztodt,tend)
      call check_energy_chng(state, tend, "nudging", nstep, ztodt, zero, zero, zero, zero)
    endif

And then I added same lines commented above in physics_run2 plus renamed the subroutine like:

Code:
  subroutine phys_run2(phys_state, ztodt, phys_tend, pbuf2d,  cam_out, &
       cam_in, state,tend,pbuf )
...
    type(physics_state), intent(inout) :: state
    type(physics_tend ), intent(inout) :: tend
    type(physics_buffer_desc), pointer :: pbuf(:)
    type(physics_ptend)     :: ptend

And I am still getting the same error regarding physical_state:

call nudging_timestep_init(state,ptend,pbuf)
1
Error: Rank mismatch in argument ‘phys_state’ at (1) (rank-1 and scalar)
gmake: *** [physpkg.o] Error 1

Thanks

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Hi Toni,

Where in phys_run2 did you add your call to nudging_timestep_init?

Courtney
 

nuvolet

Toni Viudez
Member
Hi Courtney,

First of all I apologized for my late response. I have been on leave and believe or not without access to Internet.
Regarding where I added my call to nudging_timestep_init in physical_run2, I did it at the end of the subroutine.
Just after the last call before the end:

Code:
#ifdef TRACER_CHECK
    call gmean_mass ('after tphysac FV:WET)', phys_state)
#endif

    call t_startf ('carma_accumulate_stats')
    call carma_accumulate_stats()
    call t_stopf ('carma_accumulate_stats')

    call t_startf ('physpkg_st2')
    call pbuf_deallocate(pbuf2d, 'physpkg')

    call pbuf_update_tim_idx()
    call diag_deallocate()
    call t_stopf ('physpkg_st2')
    
    ! ----- Addition 12/15/22
    ! Update Nudging values, if needed
    !----------------------------------
    if((Nudge_Model).and.(Nudge_ON)) then
      call nudging_timestep_init(state,ptend,pbuf)
    endif   

  end subroutine phys_run2

Thanks again for you help, and Happy New Year!!

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
Hi Toni,

This might not be your problem, but it looks like the variables you're using in your call to nudging_timestep_init may not correlate to the variables in the phys_run2 subroutine.

Could you try:

call nudging_timestep_init(phys_state, phys_tend, pbuf2d)

You'll also need to change the pbuf input variable in your nudging_timestep_init calling list to be 2D

Hope that helps?

Courtney
 

nuvolet

Toni Viudez
Member
Hi Courtney,

I'll try that.
Should I also need to change pbuf for pbuf2d inside the nudging module where is nudging_timestep_init defined?.
Thanks

Toni
 

nuvolet

Toni Viudez
Member
Hi again Courtney,

I tried what you suggested.
I also used the pbuf2d instead of pbuf in the nudging.F90 where I am trying to call modal_aero_sw to get some aerosol optical properties which I will use in further steps.
Now, when I create the new case I got this message:

Code:
        call modal_aero_sw(list_idx, state, pbuf, nnite, idxnite, &
                                               1
Error: Symbol ‘pbuf’ at (1) has no IMPLICIT type; did you mean ‘pbuf2d’?
gmake: *** [nudging.o] Error 1

which when I looked at that subroutine, it is defined by default by the pbuf.

Thanks

Toni
 

peverley

Courtney Peverley
Moderator
Staff member
OK I see the problem. modal_aero_sw need the 1D pbuf so you'll need to loop over the 2D pbuf.

You can try moving the call to nudging_timeste_init up into the end of this loop in physpkg.F90:

do c=begchunk,endchunk
ncol = get_ncols_p(c)
phys_buffer_chunk => pbuf_get_chunk(pbuf2d, c)
!
! surface diagnostics for history files
!
call t_startf('diag_surf')
call diag_surf(cam_in(c), cam_out(c), phys_state(c), phys_buffer_chunk)
call t_stopf('diag_surf')

call tphysac(ztodt, cam_in(c), &
cam_out(c), &
phys_state(c), phys_tend(c), phys_buffer_chunk)
call nudging_timestep_init(phys_state, phys_tend, phys_buffer_chunk)
end do
You'll also need to change pbuf2 back to pbuf inside the nudging module.

Courtney
 
Top