how to call the function get_3dfld

Bug reports, work arounds and fixes

Moderators: arango, robertson

Post Reply
Message
Author
xiaozhu557
Posts: 62
Joined: Fri Sep 11, 2009 1:48 pm
Location: nmefc

how to call the function get_3dfld

#1 Post by xiaozhu557 »

Hello all,
I want to add a 3D mixing coefficient and input it to the model as a forcing parameter. I have defined it in mod_forces.F as follow,

Code: Select all

# ifdef ECOSIM
      allocate ( FORCES(ng) % SpecIr(LBi:UBi,LBj:UBj,NBands) )
      allocate ( FORCES(ng) % avcos(LBi:UBi,LBj:UBj,NBands) )
# endif

!=======================================================================
# ifdef WAVE_MIXING
      allocate ( FORCES(ng) % bv(LBi:UBi,LBj:UBj,0:N(ng)) )
      allocate ( FORCES(ng) % bvG(LBi:UBi,LBj:UBj,0:N(ng),2) )
# endif
!=======================================================================

#endif
#if defined TANGENT || defined TL_IOMS
!
!  Tangent linear model state
!
      allocate ( FORCES(ng) % tl_sustr(LBi:UBi,LBj:UBj) )
      allocate ( FORCES(ng) % tl_svstr(LBi:UBi,LBj:UBj) )
This means that the variable's size is bv(xi_rho,eta_rho,s_w)
Then I read in the data from forcing file in subroutine get_data.F as follow,

Code: Select all

#  if !defined ANA_M3CLIMA && defined M3CLIMATOLOGY
      CALL get_3dfld (ng, iNLM, idUclm, CLM(ng)%ncid,                   &
     &                1, CLM(ng), update(1),                            &
     &                LBi, UBi, LBj, UBj, 1, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % umask(LBi,LBj),                        &
#   endif
     &                CLIMA(ng) % uclmG(LBi,LBj,1,1))
      IF (exit_flag.ne.NoError) RETURN

      CALL get_3dfld (ng, iNLM, idVclm, CLM(ng)%ncid,                   &
     &                1, CLM(ng), update(1),                            &
     &                LBi, UBi, LBj, UBj, 1, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % vmask(LBi,LBj),                        &
#   endif
     &                CLIMA(ng) % vclmG(LBi,LBj,1,1))
      IF (exit_flag.ne.NoError) RETURN
#  endif
# endif
#endif

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#if defined SOLVE3D && defined WAVE_MIXING
      CALL get_3dfld (ng, iNLM, idWbv, ncFRCid(idWbv,ng),               &
     &                nFfiles(ng), FRC(1,ng), update(1),                &
     &                LBi, UBi, LBj, UBj, 0, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % rmask(LBi,LBj),                        &
#   endif 
     &                FORCES(ng) % bvG(LBi,LBj,1,1))
      IF (exit_flag.ne.NoError) RETURN
#endif
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I have got an error message as segmentation fault while calling the subroutine get_3dfld with more than one processors to run ROMS. But it can work fine with only one processor to run ROMS.
So it is wired for me.

But if I defined it as

Code: Select all

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ifdef WAVE_MIXING
      allocate ( FORCES(ng) % bv(LBi:UBi,LBj:UBj,N(ng)) )
      allocate ( FORCES(ng) % bvG(LBi:UBi,LBj:UBj,N(ng),2) )
# endif
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
This means that the variable's size is bv(xi_rho,eta_rho,s_rho)
And read it with

Code: Select all

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#if defined SOLVE3D && defined WAVE_MIXING
      CALL get_3dfld (ng, iNLM, idWbv, ncFRCid(idWbv,ng),               &
     &                nFfiles(ng), FRC(1,ng), update(1),                &
     &                LBi, UBi, LBj, UBj, 1, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % rmask(LBi,LBj),                        &
#   endif 
     &                FORCES(ng) % bvG(LBi,LBj,1,1))
      IF (exit_flag.ne.NoError) RETURN
#endif
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
It can work fine. So I am confused about the subroutine get_3dfld. Does not it been used to read the variable with size s_w, and just works with s_rho? Or do I have made a mistake to use this subroutine?

I would like appreciate your any hint very much. Thanks.

User avatar
arango
Site Admin
Posts: 1138
Joined: Wed Feb 26, 2003 4:41 pm
Location: DMCS, Rutgers University
Contact:

Re: how to call the function get_3dfld

#2 Post by arango »

The routine get_3dfld can read any 3D field. You just need to specify the correct range for the vertical dimension: 0, N(ng)

Code: Select all

#if defined SOLVE3D && defined WAVE_MIXING
      CALL get_3dfld (ng, iNLM, idWbv, ncFRCid(idWbv,ng),               &
     &                nFfiles(ng), FRC(1,ng), update(1),                &
     &                LBi, UBi, LBj, UBj, 0, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % rmask(LBi,LBj),                        &
#   endif
     &                FORCES(ng) % bvG(LBi,LBj,1,1))
      IF (exit_flag.ne.NoError) RETURN
#endif
Also, you need to be sure that you added the proper metadata in varinfo.dat for the new variable and code the appropriate logic for idWbv in mod_ncparam.F.

xiaozhu557
Posts: 62
Joined: Fri Sep 11, 2009 1:48 pm
Location: nmefc

Re: how to call the function get_3dfld

#3 Post by xiaozhu557 »

Thanks for your replying, arango.
Also, you need to be sure that you added the proper metadata in varinfo.dat for the new variable and code the appropriate logic for idWbv in mod_ncparam.F.
Yes, I have added it, I am sure. Or I can not compile it successful.

Now my question is why the modifications can not work when I run the model with multiprocessor and define the variable bvG as

Code: Select all

allocate ( FORCES(ng) % bvG(LBi:UBi,LBj:UBj,0:N(ng)) )
Is it correct if I set the bvG's size as (ocean_time,s_w,eta_rho,xi_rho) in the forcing file? If not correct, how should I define it in mod_forces.F

How should I modify them in order to make them work with bvG(ocean_time,s_w,eta_rho,xi_rho) and run with multi-processor?

In this case, how Should I call the subroutine get_3dfld?

Where is my mistake? Thanks.

User avatar
arango
Site Admin
Posts: 1138
Joined: Wed Feb 26, 2003 4:41 pm
Location: DMCS, Rutgers University
Contact:

Re: how to call the function get_3dfld

#4 Post by arango »

Nope, it has to be a 4D-array to store the two time snapshots that are used to linearly interpolate input data at each time-step:

Code: Select all

# ifdef WAVE_MIXING
      allocate ( FORCES(ng) % bv(LBi:UBi,LBj:UBj,0:N(ng)) )
      allocate ( FORCES(ng) % bvG(LBi:UBi,LBj:UBj,0:N(ng),2) )
# endif
Then, you need to pass array bvG with zero-pointer for the third dimension. This is basic Fortran coding. If you read the top of get_3dfld.F and follow the logic, you will be understand what I am talking about :!: All these routines are well documented. Perhaps, you should read mode about Fortran before start coding...

Code: Select all

#if defined SOLVE3D && defined WAVE_MIXING
      CALL get_3dfld (ng, iNLM, idWbv, ncFRCid(idWbv,ng),               &
     &                nFfiles(ng), FRC(1,ng), update(1),                &
     &                LBi, UBi, LBj, UBj, 0, N(ng), 2, 1,               &
#   ifdef MASKING
     &                GRID(ng) % rmask(LBi,LBj),                        &
#   endif
     &                FORCES(ng) % bvG(LBi,LBj,0,1))
      IF (exit_flag.ne.NoError) RETURN
#endif

xiaozhu557
Posts: 62
Joined: Fri Sep 11, 2009 1:48 pm
Location: nmefc

Re: how to call the function get_3dfld

#5 Post by xiaozhu557 »

But why it can work when I run the model with only one processor? This is exactly confused me. Thanks.

Post Reply