[Dart-dev] [5623] DART/branches/development/models/cam/model_mod.f90: remove direct call to init_ran1.
nancy at ucar.edu
nancy at ucar.edu
Mon Mar 26 16:28:06 MDT 2012
Revision: 5623
Author: nancy
Date: 2012-03-26 16:28:06 -0600 (Mon, 26 Mar 2012)
Log Message:
-----------
remove direct call to init_ran1. you can give a seed to the normal
public interface init_random_seq(). also changed the way the seed
was computed for the parallel case. before, if there was more than
a single ensemble member per task it would have generated identical
random number seeds for different members, giving a duplicate state
for multiple members. (not a common case with this model; usually
we run with a single member per MPI task.) but fixed now either way.
Modified Paths:
--------------
DART/branches/development/models/cam/model_mod.f90
-------------- next part --------------
Modified: DART/branches/development/models/cam/model_mod.f90
===================================================================
--- DART/branches/development/models/cam/model_mod.f90 2012-03-26 21:47:11 UTC (rev 5622)
+++ DART/branches/development/models/cam/model_mod.f90 2012-03-26 22:28:06 UTC (rev 5623)
@@ -257,7 +257,6 @@
! Examples are EFGWORO, FRACLDV from the gravity wave drag parameterization study
!-----------------------------------------------------------------------------
-use random_nr_mod, only : init_ran1
use random_seq_mod, only : random_seq_type, init_random_seq, random_gaussian
! end of use statements
@@ -500,11 +499,6 @@
! Random sequence and init for pert_model_state
logical :: first_pert_call = .true.
type(random_seq_type) :: random_seq
-! Variable for keeping track of which ensemble member is to be perturbed
-! by pert_model_state, which is called by filter for each ensemble member
-! for a cold start.
-integer :: num_tasks
-integer :: my_task
integer :: ens_member = 0
logical :: do_out
@@ -642,13 +636,8 @@
else
do_out = do_output()
!write(*,*) 'do_out = ',do_out
- ! static_init_model is called once(?) for each task(?).
+ ! static_init_model is called once for each MPI task.
! There may be more or fewer ensemble members than tasks.
- ! No problem if there are fewer.
- ! In pert_model_state generate a unique ens_member from my_task and globally stored info
- ! about previous calls to pert_model_state.
- num_tasks = task_count()
- my_task = my_task_id()
end if
! Record the namelist values
@@ -4014,8 +4003,6 @@
! listed in pert_names is set to a different constant value for each
! ensemble member. Those values come from 'pert_base_vals'.
-! added to give each ens member a different sequence when perturbing model parameter fields
-
real(r8), intent(in) :: state(:)
real(r8), intent(out) :: pert_state(:)
logical, intent(out) :: interf_provided
@@ -4025,45 +4012,36 @@
integer :: i, j, k, m, pert_fld, mode, field_num
integer :: dim1, dim2, dim3, member
real(r8) :: pert_val
+integer, save :: seed
! FIX for 1D 0D fields?
-! perturb model parameters for the filter_ics.
-! Use the (single) state value as the "ens_mean" here.
+! perturb model state vector values for the filter initial conditions.
+! the input is a single model state vector that has (different) gaussian
+! noise added to each member to generate an initial ensemble.
interf_provided = .true.
call init_model_instance(var_temp)
call vector_to_prog_var(state,var_temp)
-! If first call, then initialize random sequence for perturbations.
-! init_random_seq only needed for documentation; initializing the module.
+! If first call, then initialize a seed to use for initializing random sequences.
if (first_pert_call) then
- call init_random_seq(random_seq)
+ ! this line generates a unique base number, and subsequent calls add 1
+ ! each time (which happens if there are multiple ensemble members/task).
+ ! it is assuming there are no more than 1000 ensembles/task, which seems safe
+ ! given the current sizes of state vecs and hardware memory. this will make
+ ! the results reproduce for runs with the same number of MPI tasks. it will
+ ! NOT give the same random sequence if you change the task count.
+ seed = (my_task_id()+1) * 1000
first_pert_call = .false.
end if
-! init_random_seq calls init_ran1, but I need to call init_ran1 with a different seed/temp
-! for each ens_member. Get a new seed by keeping track of the previous seed.
+! After using the seed, increment by one so if this routine is called again
+! for a different ensemble member it will generate a different set of nums.
+call init_random_seq(random_seq, seed)
+seed = seed + 1
-! Not needed; ens_member is read into static_init_model, after incrementing by the calling
-! script/program.
-! ens_member = ens_member + 1
-
-! init_ran1 wants negative seeds for some reason. The algorithm subtracts seed from some
-! large number, divides by a smaller number, and uses the remainder for other calcs.
-! The rest of DART also increments by -1, so I'll trust that this gives a different
-! random sequence for each seed.
-if (ens_member == 0) then
- ! Change ens_member from 0 for first time pert_model_state is called for by a process.
- ens_member = my_task + 1
-else
- ! Subsequent calls from the same process need unique ensemble member #s.
- ! Adding num_tasks to the previous value should yield the right total set of ens_members.
- ens_member = ens_member + num_tasks
-endif
-call init_ran1(random_seq,-1*ens_member)
-
pert_fld = 1
do while (pert_names(pert_fld) /= ' ')
More information about the Dart-dev
mailing list