From 245cc6d455d9878062dc2523dec7b7df419e289c Mon Sep 17 00:00:00 2001 From: adausilio Date: Thu, 7 Mar 2024 11:26:55 +0100 Subject: [PATCH] Add FARM model as threed sphere refs #1 --- .gitignore | 5 + .vscode/launch.json | 53 ++- models/FARM/model_mod.f90 | 492 ++++++++++++++++++++ models/FARM/work/filter_input_list.txt | 3 + models/FARM/work/filter_output_list.txt | 20 + models/FARM/work/handle_time_conventions.py | 16 + models/FARM/work/input.nml | 211 +++++++++ models/FARM/work/quickbuild.sh | 59 +++ 8 files changed, 856 insertions(+), 3 deletions(-) create mode 100644 models/FARM/model_mod.f90 create mode 100644 models/FARM/work/filter_input_list.txt create mode 100644 models/FARM/work/filter_output_list.txt create mode 100644 models/FARM/work/handle_time_conventions.py create mode 100644 models/FARM/work/input.nml create mode 100755 models/FARM/work/quickbuild.sh diff --git a/.gitignore b/.gitignore index 1dd60a6f9..921982b97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.mod *.o +*.nc.gz *.swp *__pycache__* *obscount.txt @@ -227,3 +228,7 @@ test_ran_unif !wakeup_filter/ models/lorenz_63/ models/lorenz_63/work/ +observations/obs_converters/MADIS/data/satwnd_input.nc +observations/obs_converters/S5P_TROPOMI_L3/data/S5p_NO2_16685.nc +observations/obs_converters/S5P_TROPOMI_L3/data/satwnd_input.nc +observations/obs_converters/S5P_TROPOMI_L3/work/S5p_NO2_16685.nc diff --git a/.vscode/launch.json b/.vscode/launch.json index 3846ea0df..365271bad 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,15 +1,16 @@ { "version" : "0.2.0", "configurations": [ + {"name":"Python Debugger: Current File","type":"debugpy","request":"launch","program":"${file}","console":"integratedTerminal"}, { - "name" : "Run DART", + "name" : "Run convert tropomi", "type" : "cppdbg", "request": "launch", - "program": "/mnt/mumbai_n4r5/dausilio/projects/DART/models/FARM_DA/work/model_mod_check", + "program": "/mnt/mumbai_n4r5/dausilio/projects/DART/observations/obs_converters/S5P_TROPOMI_L3/work/convert_s5p_tropomi_l3", "args": [], "stopAtEntry": true, - "cwd" : "/mnt/mumbai_n4r5/dausilio/projects/DART/models/FARM_DA/work", + "cwd" : "/mnt/mumbai_n4r5/dausilio/projects/DART/observations/obs_converters/S5P_TROPOMI_L3/work/", "externalConsole": false, "MIMode": "gdb", "preLaunchTask": "", @@ -25,6 +26,52 @@ } ], }, + { + "name" : "Run filter", + "type" : "cppdbg", + "request": "launch", + "program": "/mnt/mumbai_n4r5/dausilio/projects/DART/models/FARM/work/filter", + "args": [], + "stopAtEntry": true, + "cwd" : "/mnt/mumbai_n4r5/dausilio/projects/DART/models/FARM/work/", + "externalConsole": false, + "MIMode": "gdb", + "preLaunchTask": "", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Fix pretty-printing for gdb", + "text": "set charset UTF-8" + } + ], + }, + { + "name" : "Run Lorenz case", + "type" : "cppdbg", + "request": "launch", + "program": "/mnt/mumbai_n4r5/dausilio/projects/DART/models/lorenz_63/work/filter", + "args": [], + "stopAtEntry": true, + "cwd" : "/mnt/mumbai_n4r5/dausilio/projects/DART/models/lorenz_63/work/", + "externalConsole": false, + "MIMode": "gdb", + "preLaunchTask": "", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Fix pretty-printing for gdb", + "text": "set charset UTF-8" + } + ], + }, { "name": "Intel Debug Attach", "type": "cppvsdbg", diff --git a/models/FARM/model_mod.f90 b/models/FARM/model_mod.f90 new file mode 100644 index 000000000..3ef94058f --- /dev/null +++ b/models/FARM/model_mod.f90 @@ -0,0 +1,492 @@ +! DART software - Copyright UCAR. This open source software is provided +! by UCAR, "as is", without charge, subject to all terms of use at +! http://www.image.ucar.edu/DAReS/DART/DART_download +! + +module model_mod + +! This is a template showing the interfaces required for a model to be compliant +! with the DART data assimilation infrastructure. Do not change the arguments +! for the public routines. + + use types_mod, only : r8, i8, MISSING_R8, MISSING_I, vtablenamelength + + use time_manager_mod, only : time_type, set_time, set_calendar_type + + use location_mod, only : location_type, get_close_type, & + loc_get_close_obs => get_close_obs, & + loc_get_close_state => get_close_state, & + set_location, set_location_missing + + use utilities_mod, only : register_module, error_handler, & + E_ERR, E_MSG, & + nmlfileunit, do_output, do_nml_file, do_nml_term, & + find_namelist_in_file, check_namelist_read, string_to_integer, & + string_to_real, string_to_logical, to_upper + + use obs_kind_mod, only: QTY_NO2, get_index_for_quantity, get_num_quantities, get_name_for_quantity + use netcdf_utilities_mod, only : nc_add_global_attribute, nc_synchronize_file, & + nc_add_global_creation_time, & + nc_begin_define_mode, nc_end_define_mode, & + nc_open_file_readonly, nc_get_dimension_size, & + nc_variable_exists, nc_get_variable, nc_get_variable_size + + use state_structure_mod, only : add_domain, get_domain_size, get_model_variable_indices + + use ensemble_manager_mod, only : ensemble_type + +! These routines are passed through from default_model_mod. +! To write model specific versions of these routines +! remove the routine from this use statement and add your code to +! this the file. + use default_model_mod, only : pert_model_copies, read_model_time, write_model_time, & + init_time => fail_init_time, & + init_conditions => fail_init_conditions, & + convert_vertical_obs, convert_vertical_state, adv_1step + + implicit none + private + +! routines required by DART code - will be called from filter and other +! DART executables. + public :: get_model_size, & + get_state_meta_data, & + model_interpolate, & + end_model, & + static_init_model, & + nc_write_model_atts, & + get_close_obs, & + get_close_state, & + pert_model_copies, & + convert_vertical_obs, & + convert_vertical_state, & + read_model_time, & + adv_1step, & + init_time, & + init_conditions, & + shortest_time_between_assimilations, & + write_model_time + + + character(len=256), parameter :: source = "model_mod.f90" + logical :: module_initialized = .false. + integer :: dom_id ! used to access the state structure + type(time_type) :: assimilation_time_step + +! Example Namelist +! Use the namelist for options to be set at runtime. + character(len=256) :: farm_template_filename = './farminput.nc' + integer :: time_step_days = 0 + integer :: time_step_seconds = 3600 + integer, parameter :: MAX_NUM_STATE_VARIABLES = 30 + integer, parameter :: MAX_NUM_COLUMNS = 5 + +! state_variables defines the contents of the state vector. +! each line of this input should have the form: +! +! netcdf_variable_name, dart_quantity, clamp_min, clamp_max, update_variable +! +! all items must be strings (even if numerical values). +! for no clamping, use the string 'NA' +! to have the assimilation change the variable use 'UPDATE', else 'NO_UPDATE' + + character(len=300) :: state_variables(MAX_NUM_STATE_VARIABLES * MAX_NUM_COLUMNS) = ' ' + namelist /model_nml/ & + farm_template_filename, & + time_step_days, & + time_step_seconds, & + state_variables + +!> Metadata from the template netCDF file that describes +!> where the variable data is located and what size it is. + type farm_1d_array + integer :: nsize + real(r8), allocatable :: vals(:) + end type + + + type farm_grid + type(farm_1d_array) :: lons + type(farm_1d_array) :: lats + type(farm_1d_array) :: levs + !corner points + real :: west + real :: south + real :: east + real :: north + !grid size + integer :: nlon + integer :: nlat + integer :: nlev + !Lon Lat grid specs + real :: delta_lon + real :: delta_lat + end type farm_grid + + type(farm_grid) :: grid_data + + integer, parameter :: MAX_STATE_VARIABLES = 1 + integer, parameter :: num_state_table_columns = 5 + +contains + +!------------------------------------------------------------------ +! +! Called to do one time initialization of the model. As examples, +! might define information about the model size or model timestep. +! In models that require pre-computed static data, for instance +! spherical harmonic weights, these would also be computed here. + + subroutine static_init_model() + + integer :: iunit, io + + module_initialized = .true. + +! Print module information to log file and stdout. + call register_module(source) + + call find_namelist_in_file("input.nml", "model_nml", iunit) + read(iunit, nml = model_nml, iostat = io) + call check_namelist_read(iunit, io, "model_nml") + +! Record the namelist values used for the run + if (do_nml_file()) write(nmlfileunit, nml=model_nml) + if (do_nml_term()) write( * , nml=model_nml) + + call get_FARM_grid(farm_template_filename) + + call set_calendar_type('GREGORIAN') + + call set_farm_variable_info(farm_template_filename, state_variables) + + + assimilation_time_step = set_time(time_step_seconds, & + time_step_days) + + end subroutine static_init_model + +!------------------------------------------------------------------ +! Returns the number of items in the state vector as an integer. + + function get_model_size() + + integer(i8) :: get_model_size + + if ( .not. module_initialized ) call static_init_model + + get_model_size = get_domain_size(dom_id) + + end function get_model_size + + +!------------------------------------------------------------------ +! Given a state handle, a location, and a state quantity, +! interpolates the state variable fields to that location and returns +! the values in expected_obs. The istatus variables should be returned as +! 0 unless there is some problem in computing the interpolation in +! which case a positive istatus should be returned. +! +! For applications in which only perfect model experiments +! with identity observations (i.e. only the value of a particular +! state variable is observed), this can be a NULL INTERFACE. + + subroutine model_interpolate(state_handle, ens_size, location, qty, expected_obs, istatus) + + + type(ensemble_type), intent(in) :: state_handle + integer, intent(in) :: ens_size + type(location_type), intent(in) :: location + integer, intent(in) :: qty + real(r8), intent(out) :: expected_obs(ens_size) !< array of interpolated values + integer, intent(out) :: istatus(ens_size) + + if ( .not. module_initialized ) call static_init_model + + expected_obs(:) = MISSING_R8 + + + istatus(:) = 1 + + end subroutine model_interpolate + + + +!------------------------------------------------------------------ +! Returns the smallest increment in time that the model is capable +! of advancing the state in a given implementation, or the shortest +! time you want the model to advance between assimilations. + + function shortest_time_between_assimilations() + + type(time_type) :: shortest_time_between_assimilations + + if ( .not. module_initialized ) call static_init_model + + shortest_time_between_assimilations = assimilation_time_step + + end function shortest_time_between_assimilations + + + +!------------------------------------------------------------------ +! Given an integer index into the state vector, returns the +! associated location and optionally the physical quantity. +! +! Parameters: +! - index_in: Integer index into the state vector. +! - location: Output parameter for the associated location. +! - var_type: Optional output parameter for the physical quantity. +!------------------------------------------------------------------ + + subroutine get_state_meta_data(index_in, location, var_type) + + integer(i8), intent(in) :: index_in + type(location_type), intent(out) :: location + integer, optional, intent(out) :: var_type + logical, parameter :: debug = .false. + character(len=*), parameter :: routine = 'get_state_meta_data' + ! Local variables + integer :: iloc, vloc, jloc + integer :: myvarid, myqty + ! Ensure the module is initialized + if ( .not. module_initialized ) call static_init_model + + ! Get variable indices and associated quantity + call get_model_variable_indices(index_in, iloc, jloc, vloc, var_id = myvarid, dom_id = dom_id, kind_index=myqty) + ! Check dimensions + if (grid_data%lons%nsize <= iloc .or. grid_data%lats%nsize <= jloc) then + call error_handler(E_MSG, routine, text = "Invalid index: Out of bounds for grid dimensions.") + end if + + ! Set the location using set_location() + location = set_location(real(grid_data%lons%vals(iloc), r8), real(grid_data%lats%vals(jloc), r8), grid_data%levs%vals(vloc), 3) + if (present(var_type)) var_type = myqty + + end subroutine get_state_meta_data +!------------------------------------------------------------------ +! Any model specific distance calcualtion can be done here + subroutine get_close_obs(gc, base_loc, base_type, locs, loc_qtys, loc_types, & + num_close, close_ind, dist, ens_handle) + + type(get_close_type), intent(in) :: gc ! handle to a get_close structure + integer, intent(in) :: base_type ! observation TYPE + type(location_type), intent(inout) :: base_loc ! location of interest + type(location_type), intent(inout) :: locs(:) ! obs locations + integer, intent(in) :: loc_qtys(:) ! QTYS for obs + integer, intent(in) :: loc_types(:) ! TYPES for obs + integer, intent(out) :: num_close ! how many are close + integer, intent(out) :: close_ind(:) ! incidies into the locs array + real(r8), optional, intent(out) :: dist(:) ! distances in radians + type(ensemble_type), optional, intent(in) :: ens_handle + + character(len=*), parameter :: routine = 'get_close_obs' + + call loc_get_close_obs(gc, base_loc, base_type, locs, loc_qtys, loc_types, & + num_close, close_ind, dist, ens_handle) + + end subroutine get_close_obs + + +!------------------------------------------------------------------ +! Any model specific distance calcualtion can be done here + subroutine get_close_state(gc, base_loc, base_type, locs, loc_qtys, loc_indx, & + num_close, close_ind, dist, ens_handle) + + type(get_close_type), intent(in) :: gc ! handle to a get_close structure + type(location_type), intent(inout) :: base_loc ! location of interest + integer, intent(in) :: base_type ! observation TYPE + type(location_type), intent(inout) :: locs(:) ! state locations + integer, intent(in) :: loc_qtys(:) ! QTYs for state + integer(i8), intent(in) :: loc_indx(:) ! indices into DART state vector + integer, intent(out) :: num_close ! how many are close + integer, intent(out) :: close_ind(:) ! indices into the locs array + real(r8), optional, intent(out) :: dist(:) ! distances in radians + type(ensemble_type), optional, intent(in) :: ens_handle + + character(len=*), parameter :: routine = 'get_close_state' + + + call loc_get_close_state(gc, base_loc, base_type, locs, loc_qtys, loc_indx, & + num_close, close_ind, dist, ens_handle) + + + end subroutine get_close_state + + +!------------------------------------------------------------------ +! Does any shutdown and clean-up needed for model. Can be a NULL +! INTERFACE if the model has no need to clean up storage, etc. + + subroutine end_model() + + + end subroutine end_model + + +!------------------------------------------------------------------ +! write any additional attributes to the output and diagnostic files + + subroutine nc_write_model_atts(ncid, domain_id) + + integer, intent(in) :: ncid ! netCDF file identifier + integer, intent(in) :: domain_id + + if ( .not. module_initialized ) call static_init_model + +! put file into define mode. + + call nc_begin_define_mode(ncid) + + call nc_add_global_creation_time(ncid) + + call nc_add_global_attribute(ncid, "model_source", source ) + call nc_add_global_attribute(ncid, "model", "template") + + call nc_end_define_mode(ncid) + +! Flush the buffer and leave netCDF file open + call nc_synchronize_file(ncid) + + end subroutine nc_write_model_atts + + subroutine fill_farm_1d_array(ncid, varname, grid_array) + integer, intent(in) :: ncid + character(len=*), intent(in) :: varname + type(farm_1d_array), intent(inout) :: grid_array + + character(len=*), parameter :: routine = 'fill_farm_1d_array' + + if(nc_variable_exists(ncid, varname)) then + + call nc_get_variable_size(ncid, varname, grid_array%nsize) + allocate(grid_array%vals(grid_array%nsize)) + + call nc_get_variable(ncid, varname, grid_array%vals, routine) + endif + + end subroutine fill_farm_1d_array + + + !------------------------------------------------------------------------------------------------------------------ + !> Read the data from the various FARM grid arrays + subroutine get_FARM_grid(file_name) + !A.D'A: based on templates it reads the netcdf for the definition + !stores grid information for the moment very similar to SATDA_OFFLINE + character(len=*), intent(in) :: file_name + integer :: ncid, DimID, TimeDimID + + character(len=*), parameter :: routine = 'read_FARM_definition' + + call error_handler(E_MSG,routine,'reading restart ['//trim(file_name)//']') + + ncid = nc_open_file_readonly(file_name, routine) + + ! longitude - FARM uses values +/- 180, DART uses values [0,360] + grid_data%nlon = nc_get_dimension_size(ncid, 'x', routine) + call fill_farm_1d_array(ncid, 'x', grid_data%lons) + where (grid_data%lons%vals < 0.0_r8) grid_data%lons%vals = grid_data%lons%vals + 360.0_r8 + + ! latitiude + grid_data%nlat = nc_get_dimension_size(ncid, 'y', routine) + call fill_farm_1d_array(ncid, 'y', grid_data%lats) + + ! level [m] + grid_data%nlev = nc_get_dimension_size(ncid, 'z', routine) + call fill_farm_1d_array(ncid, 'z', grid_data%levs) + + ! Get lon and lat grid specs + grid_data%west = grid_data%lons%vals(1) + grid_data%east= grid_data%lons%vals(grid_data%nlon) + grid_data%south = grid_data%lats%vals(1) + grid_data%north = grid_data%lats%vals(grid_data%nlat) + grid_data%delta_lon = abs((grid_data%lons%vals(1)-grid_data%lons%vals(2))) + grid_data%delta_lat = abs((grid_data%lats%vals(1)-grid_data%lats%vals(2))) + + end subroutine get_FARM_grid + +!----------------------------------------------------------------------- +!> +!> Fill the array of requested variables, dart kinds, possible min/max +!> values and whether or not to update the field in the output file. +!> Then calls 'add_domain()' to tell the DART code which variables to +!> read into the state vector after this code returns. +!> +!>@param variable_array the list of variables and kinds from model_mod_nml +!>@param nfields the number of variable/Quantity pairs specified + + subroutine set_farm_variable_info(farm_template_filename, variable_array) + + character(len=*), intent(in) :: farm_template_filename + character(len=*), intent(in) :: variable_array(:) + + character(len=*), parameter :: routine = 'set_farm_variable_info:' + + integer :: i, nfields + integer, parameter :: MAX_STRING_LEN = 128 + + character(len=MAX_STRING_LEN) :: varname ! column 1, NetCDF variable name + character(len=MAX_STRING_LEN) :: dartstr ! column 2, DART Quantity + character(len=MAX_STRING_LEN) :: minvalstr ! column 3, Clamp min val + character(len=MAX_STRING_LEN) :: maxvalstr ! column 4, Clamp max val + character(len=MAX_STRING_LEN) :: updatestr ! column 5, Update output or not + + character(len=vtablenamelength) :: var_names(MAX_STATE_VARIABLES) = ' ' + logical :: update_list(MAX_STATE_VARIABLES) = .FALSE. + integer :: kind_list(MAX_STATE_VARIABLES) = MISSING_I + real(r8) :: clamp_vals(MAX_STATE_VARIABLES,2) = MISSING_R8 + + nfields = 0 + ParseVariables : do i = 1, MAX_STATE_VARIABLES + + varname = variable_array(num_state_table_columns*i-4) + dartstr = variable_array(num_state_table_columns*i-3) + minvalstr = variable_array(num_state_table_columns*i-2) + maxvalstr = variable_array(num_state_table_columns*i-1) + updatestr = variable_array(num_state_table_columns*i ) + + if ( varname == ' ' .and. dartstr == ' ' ) exit ParseVariables ! Found end of list. + + ! if ( varname == ' ' .or. dartstr == ' ' ) then + ! string1 = 'model_nml:model "state_variables" not fully specified' + ! call error_handler(E_ERR,routine,string1,source,revision,revdate) + ! endif + + ! Make sure DART kind is valid + + ! if( get_index_for_quantity(dartstr) < 0 ) then + ! write(string1,'(3A)') 'there is no obs_kind "', trim(dartstr), '" in obs_kind_mod.f90' + ! call error_handler(E_ERR,routine,string1,source,revision,revdate) + ! endif + + call to_upper(minvalstr) + call to_upper(maxvalstr) + call to_upper(updatestr) + + var_names( i) = varname + kind_list( i) = get_index_for_quantity(dartstr) + clamp_vals(i,1) = string_to_real(minvalstr) + clamp_vals(i,2) = string_to_real(maxvalstr) + update_list( i) = string_to_logical(updatestr, 'UPDATE') + + nfields = nfields + 1 + + enddo ParseVariables + + ! if (nfields == MAX_STATE_VARIABLES) then + ! write(string1,'(2A)') 'WARNING: There is a possibility you need to increase ', & + ! 'MAX_STATE_VARIABLES in the global variables in model_mod.f90' + + ! write(string2,'(A,i4,A)') 'WARNING: you have specified at least ', nfields, & + ! ' perhaps more' + + ! call error_handler(E_MSG,routine,string1,source,revision,revdate,text2=string2) + ! endif + + ! CAM only has a single domain (only a single grid, no nests or multiple grids) + + dom_id = add_domain(farm_template_filename, nfields, var_names, kind_list, & + clamp_vals, update_list) + + end subroutine set_farm_variable_info +end module model_mod diff --git a/models/FARM/work/filter_input_list.txt b/models/FARM/work/filter_input_list.txt new file mode 100644 index 000000000..769db41b0 --- /dev/null +++ b/models/FARM/work/filter_input_list.txt @@ -0,0 +1,3 @@ +conc_g2_20210105.nc +conc_g2_20210106.nc +conc_g2_20210107.nc \ No newline at end of file diff --git a/models/FARM/work/filter_output_list.txt b/models/FARM/work/filter_output_list.txt new file mode 100644 index 000000000..f9e5956b6 --- /dev/null +++ b/models/FARM/work/filter_output_list.txt @@ -0,0 +1,20 @@ +1.nc +2.nc +3.nc +4.nc +5.nc +6.nc +7.nc +8.nc +9.nc +10.nc +11.nc +12.nc +13.nc +14.nc +15.nc +16.nc +17.nc +18.nc +19.nc +20.nc \ No newline at end of file diff --git a/models/FARM/work/handle_time_conventions.py b/models/FARM/work/handle_time_conventions.py new file mode 100644 index 000000000..4a31c822d --- /dev/null +++ b/models/FARM/work/handle_time_conventions.py @@ -0,0 +1,16 @@ +import netCDF4 + +file_name_list = ["conc_g2_20210105.nc", "conc_g2_20210106.nc", "conc_g2_20210107.nc"] +for file_name in file_name_list: + nc_file = netCDF4.Dataset(file_name, "r+") + + # Convert time to days since 1900-01-01 + nc_file["time"][:] = nc_file["time"][:] / 24 + nc_file["time"].units = "days since 1900-01-01" + nc_file["time"].calendar = "gregorian" + + # remove scale_factor and offset from the file + del nc_file["c_NO2"].add_offset + del nc_file["c_NO2"].scale_factor + + nc_file.close() diff --git a/models/FARM/work/input.nml b/models/FARM/work/input.nml new file mode 100644 index 000000000..27f09dcc3 --- /dev/null +++ b/models/FARM/work/input.nml @@ -0,0 +1,211 @@ +&probit_transform_nml + / + +&algorithm_info_nml + qceff_table_filename = '' + / + +&perfect_model_obs_nml + read_input_state_from_file = .false., + single_file_in = .false. + !AD'A the path is 100% wrong + input_state_files = "farminput.nc" + + write_output_state_to_file = .true., + single_file_out = .true. + output_state_files = "perfect_output.nc" + output_interval = 1, + + async = 0, + adv_ens_command = "./advance_model.csh", + + obs_seq_in_file_name = "obs_seq.in", + obs_seq_out_file_name = "obs_seq.out", + init_time_days = 153406, + init_time_seconds = 0, + first_obs_days = 153406, + first_obs_seconds = -1, + last_obs_days = -1, + last_obs_seconds = -1, + + trace_execution = .false., + output_timestamps = .false., + print_every_nth_obs = -1, + output_forward_op_errors = .false., + silence = .false., + / + +&filter_nml + single_file_in = .false., + input_state_files = '' + input_state_file_list = 'filter_input_list.txt' + + stages_to_write = 'preassim', 'analysis', 'output' + + single_file_out = .true., + output_state_files = '' + output_state_file_list = 'filter_output_list.txt' + output_interval = 1, + output_members = .true. + num_output_state_members = 5, + output_mean = .true. + output_sd = .true. + write_all_stages_at_end = .false. + + ens_size = 5, + num_groups = 1, + ! AD'A we should try with this setting to not genereate 50 ensemble + perturb_from_single_instance = .true., + perturbation_amplitude = 0.2, + distributed_state = .true. + + async = 0, + adv_ens_command = "", + + obs_sequence_in_name = "obs_seq.out", + obs_sequence_out_name = "obs_seq.final", + num_output_obs_members = 20, + init_time_days = 153406, + init_time_seconds = 39960, + first_obs_days = 153406, + first_obs_seconds = 0, + last_obs_days = -1, + last_obs_seconds = -1, + + inf_flavor = 0, 0, + inf_initial_from_restart = .false., .false., + inf_sd_initial_from_restart = .false., .false., + inf_deterministic = .true., .true., + inf_initial = 1.0, 1.0, + inf_lower_bound = 1.0, 1.0, + inf_upper_bound = 100.0, 1000000.0, + inf_damping = 1.0, 1.0, + inf_sd_initial = 0.0, 0.0, + inf_sd_lower_bound = 0.0, 0.0, + inf_sd_max_change = 1.05, 1.05, + + trace_execution = .false., + output_timestamps = .false., + output_forward_op_errors = .false., + silence = .false., + / + + +&ensemble_manager_nml + / + +&assim_tools_nml + cutoff = 1000000.0 + sort_obs_inc = .false., + spread_restoration = .false., + sampling_error_correction = .false., + adaptive_localization_threshold = -1, + distribute_mean = .false. + output_localization_diagnostics = .false., + localization_diagnostics_file = 'localization_diagnostics', + print_every_nth_obs = 0 + / + +&cov_cutoff_nml + select_localization = 1 + / + +®_factor_nml + select_regression = 1, + input_reg_file = "time_mean_reg", + save_reg_diagnostics = .false., + reg_diagnostics_file = "reg_diagnostics" + / + +&obs_sequence_nml + write_binary_obs_sequence = .false. + / + +&obs_kind_nml + assimilate_these_obs_types = 'SAT_NO2_TROPOMI' + evaluate_these_obs_types = '' + / + +&location_nml + / + +&model_nml + farm_template_filename = 'farminput.nc' + state_variables = 'c_NO2', 'QTY_NO2', 'NA', 'NA', 'UPDATE' + time_step_days = 0, +!A.D using DA_SATOFFLINE approach + time_step_seconds = 180 + state_variables = 'c_NO2', 'QTY_NO2', 'NA', 'NA', 'UPDATE' + / + +&utilities_nml + TERMLEVEL = 1, + module_details = .false., + logfilename = 'dart_log.out', + nmlfilename = 'dart_log.nml', + write_nml = 'none' + / + +&preprocess_nml + input_obs_qty_mod_file = '../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90' + output_obs_qty_mod_file = '../../../assimilation_code/modules/observations/obs_kind_mod.f90' + input_obs_def_mod_file = '../../../observations/forward_operators/DEFAULT_obs_def_mod.F90' + obs_type_files = '../../../observations/forward_operators/obs_def_SAT_NO2_TROPOMI_mod.f90', + quantity_files = '../../../assimilation_code/modules/observations/atmosphere_quantities_mod.f90', + '../../../assimilation_code/modules/observations/space_quantities_mod.f90', + '../../../assimilation_code/modules/observations/chemistry_quantities_mod.f90' + output_obs_def_mod_file = '../../../observations/forward_operators/obs_def_mod.f90' + / + +&obs_sequence_tool_nml + filename_seq = 'obs_seq.one', 'obs_seq.two', + filename_out = 'obs_seq.processed', + first_obs_days = -1, + first_obs_seconds = -1, + last_obs_days = -1, + last_obs_seconds = -1, + print_only = .false., + gregorian_cal = .false. + / + +&obs_diag_nml + obs_sequence_name = 'obs_seq.final', + bin_width_days = -1, + bin_width_seconds = -1, + init_skip_days = 0, + init_skip_seconds = 0, + Nregions = 3, + trusted_obs = 'null', + lonlim1 = 0.00, 0.00, 0.50 + lonlim2 = 1.01, 0.50, 1.01 + reg_names = 'whole', 'yin', 'yang' + create_rank_histogram = .true., + outliers_in_histogram = .true., + use_zero_error_obs = .false., + verbose = .false. + / + +&state_vector_io_nml + / + +&model_mod_check_nml + input_state_files = 'farminput.nc' + output_state_files = 'mmc_output.nc' + test1thru = 0 + run_tests = 1,2,3,4,5,7 + x_ind = 55800 + loc_of_interest = 19.20000000, 47.80600000, 0.325 + quantity_of_interest = 'c_NO2' + interp_test_dx = 0.02 + interp_test_xrange = 0.0, 1.0 + verbose = .true. + / + +&quality_control_nml + input_qc_threshold = 3.0, + outlier_threshold = -1.0, + / +&obs_def_SAT_NO2_TROPOMI_nml + / +/ + diff --git a/models/FARM/work/quickbuild.sh b/models/FARM/work/quickbuild.sh new file mode 100755 index 000000000..d5fe31d16 --- /dev/null +++ b/models/FARM/work/quickbuild.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# DART software - Copyright UCAR. This open source software is provided +# by UCAR, "as is", without charge, subject to all terms of use at +# http://www.image.ucar.edu/DAReS/DART/DART_download + +main() { + +export DART=$(git rev-parse --show-toplevel) +source "$DART"/build_templates/buildfunctions.sh + +MODEL=FARM +LOCATION=threed_sphere + + +programs=( +closest_member_tool +filter +model_mod_check +perfect_model_obs +) + +serial_programs=( +create_fixed_network_seq +create_obs_sequence +fill_inflation_restart +integrate_model +obs_common_subset +obs_diag +obs_sequence_tool +) + +model_programs=( +) + +model_serial_programs=( +) + +# quickbuild arguments +arguments "$@" + +# clean the directory +\rm -f -- *.o *.mod Makefile .cppdefs + +# build any NetCDF files from .cdl files +cdl_to_netcdf + +# build and run preprocess before making any other DART executables +buildpreprocess + +# build +buildit + +# clean up +\rm -f -- *.o *.mod + +} + +main "$@"