/**
 * @class EigenVisIter
 * @brief Perform eigen factorization of the visibilities
 *
 * This task performs the factorization of the visibility matrix into
 * ``num_ev`` eigenvectors and eigenvalues and stores them in reserve space
 * in the ``VisBuffer``. They are stored in descending order of the eigenvalue.
 *
 * This is performed by using a subspace iteration method with an augmented
 * Rayleigh-Ritz step and a progressive matrix completion of masked values.
 *
 * @par Buffers
 * @buffer in_buf The stream to eigen decompose.
 *         @buffer_format VisBuffer structured
 *         @buffer_metadata VisMetadata
 * @buffer out_buf Output stream with the calculated eigen-pairs.
 *         @buffer_format VisBuffer structured
 *         @buffer_metadata VisMetadata
 *
 * @conf  num_elements     Int. The number of elements (i.e. inputs) in the
 *                         correlator data.
 * @conf  block_size       Int. The block size of the packed data.
 * @conf  num_ev           UInt. The number of eigenvectors to be calculated as
 *                         an approximation to the visibilities.
 * @conf  bands_filled     List of pairs of ints, default empty. Ranges of diagonal
 *                         bands to mask out before the factorization. These are
 *                         iteratively filled within the eigen decomposition code.
 * @conf  block_fill_size  UInt, default 0. Mask out blocks of this size on the diagonal.
 * @conf  exclude_inputs   List of UInts, optional. Inputs to exclude (rows and
 *                         columns to set to zero) in visibilities prior to
 *                         factorization.
 * @conf  tol_eval         Float, default 1e-6. Fractional change in evals must be less
 *                         than this for convergence.
 * @conf  tol_evec         Float, default 1e-5. Total eigenvector overlap must be less
 *                         than this.
 * @conf  max_iterations   UInt. Maximum number of iterations to compute.
 * @conf  num_ev_conv      UInt. Test only the top `num_ev_conv` eigenpairs for convergence.
 * @conf  krylov           UInt, default 2. Size of the Krylov basis to use.
 * @conf  subspace         UInt, default 3. Number of subspace iteration substeps.
 *
 * @par Metrics
 * @metric kotekan_eigenvisiter_comp_time_seconds
 *         Time required to find eigenvectors. An exponential moving average over
 *         ~10 samples.
 * @metric kotekan_eigenvisiter_eigenvalue
 *         The value of each eigenvalue calculated, or the RMS.
 * @metric kotekan_eigenvisiter_iterations
 *         Number of iterations required to compute the last sample.
 * @metric kotekan_eigenvisiter_eigenvalue_convergence
 *         Eigenvalue convergence parameter of the last sample.
 * @metric kotekan_eigenvisiter_eigenvector_convergence
 *         Eigenvector convergence parameter of the last sample.
 *
 * @author Richard Shaw, Kiyoshi Masui
 */


/**
 * @class networkInputPowerStream
 * @brief Stage to take an intensity stream and stream to a remote client.
 *
 * This is a consumer stage which takes intensity data from a buffer and streams
 * it via TCP (and some day UDP) to a remote client, primarily for visualization purposes.
 *
 * In TCP mode, the stage should continually attempt to establish a TCP connection,
 * then transmit data once successful.
 *
 * @par Buffers
 * @buffer out_buf Input kotekan buffer containing power data to be sent.
 *     @buffer_format Array of @c uint
 *     @buffer_metadata none
 *
 * @conf   samples_per_data_set   Int. Number of time samples to sum.
 * @conf   integration_length     Int. Number of time samples to sum.
 * @conf   num_freq               Int. Number of time samples to sum.
 * @conf   num_elements           Int. Number of time samples to sum.
 * @conf   port                   Int. Number of time samples to sum.
 * @conf   ip                     Int. Number of time samples to sum.
 * @conf   protocol               String. Should be @c "TCP" or @c "UDP"
 *
 * @warning UDP stream receiption doesn't work at the moment.
 * @note    Lots of updating required once buffers are typed...
 *
 * @author Keith Vanderlinde
 *
 */


/**
 * @class nDiskFileWrite
 * @brief Consumer ``kotekan::Stage`` which writes VDIF-formatted input  data on multiple
 * drives.
 *
 * This is a consumer which initiates n threads to write to ``n`` disks. Each drive will receive
 * data from every
 * ``n``th buffer, stored within a common-named subfolder. Within each folder the data files will be
 * numbered incrementally across the disks.
 *
 * @par Buffers
 * @buffer in_buf The kotkean buffer holing the data to be written
 *  @buffer_format Array of VDIF frames.
 *  @buffer_metadata none
 *
 * @conf num_disks      Int , the number of drives to read from
 * @conf disk_base      String, the path to the mounted drives
 * @conf disk_set       String, the disk name.
 * @conf write_to_disk  Bool, whether to actually save, alternately operating in dummy mode
 * @conf instrument_name String, used in filenames and stored to metadata text file.
 * @conf write_metadata_and_gains  Bool, Default true.  Flag to control if VDIF/ARO style gains
 *                                 and metadata are copied to the acquisition folder.
 *
 * @todo    Make more general, to support more than just ICEboard-generated data.
 *
 * Worked Example with n = 3:
 *
 * kotekan::Config Parameters:
 *
 * - num_disk: 3
 * - disk_base: /drives/
 * - disk_set: /D/
 * - instrument_name: aro
 *
 * This will output data in files like:
 *
 * Drive 0:
 *
 * - /drives/D/0/20170805T155218Z_aro_vdif/settings.txt
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000000.vdif
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000003.vdif
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000006.vdif
 *
 * Drive 1:
 *
 * - /drives/D/1/20170805T155218Z_aro_vdif/settings.txt
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000001.vdif
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000004.vdif
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000007.vdif
 *
 * Drive 2:
 *
 * - /drives/D/2/20170805T155218Z_aro_vdif/settings.txt
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000002.vdif
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000005.vdif
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000008.vdif
 *
 * @author Andre Renard
 */


/**
 * @class visTransform
 * @brief Merge a set of GPU buffers into a single VisBuffer stream.
 *
 * This task takes data coming out of a collecton of GPU streams and merges and
 * reformats it into a single stream in the new VisBuffer format that is used
 * for the receiver.
 *
 * @par Buffers
 * @buffer in_bufs The set of buffers coming out the GPU buffers
 *         @buffer_format GPU packed upper triangle
 *         @buffer_metadata chimeMetadata
 * @buffer out_buf The merged and transformed buffer
 *         @buffer_format VisBuffer structured
 *         @buffer_metadata VisMetadata
 *
 * @conf  num_elements      Int. The number of elements (i.e. inputs) in the
 *                          correlator data.
 * @conf  block_size        Int. The block size of the packed data.
 * @conf  num_ev            Int. The number of eigenvectors to be stored
 * @conf  input_reorder     Array of [int, int, string]. The reordering mapping.
 *                          Only the first element of each sub-array is used and
 *                          it is the the index of the input to move into this
 *                          new location. The remaining elements of the subarray
 *                          are for correctly labelling the input in
 *                          ``VisWriter``.
 *
 * @author Richard Shaw
 */


/**
 * @brief Sends a buffer and metadata over TCP.
 *
 * Will attempt to connect to a remote server (likely another kotekan instance)
 * and send frames and metadata as they arrive.
 *
 * If the remote server is down, or the connection breaks, this stage will
 * drop incoming frames, and try to reconnect to the server after @c reconnect_time
 * seconds.
 *
 *
 *
 * @par buffers
 * @buffer buf The buffer to send to the remote server.
 *        @buffer_format any
 *        @buffer_metadata any
 *
 * @conf server_ip       String, the IP address of the server to send data too.
 * @conf server_port     Int, default 11024. The port number on the remote server.
 * @conf send_timeout    Int, default 20. The number of seconds
 *                         before @c send() times out and closes the connection.
 * @conf reconnect_time  Int, default 5.  The number of seconds between
 *                         connection attempts to the remote server.
 * @conf drop_frames     Bool, default true.  Whether to drop frames when buffer fills.
 * @conf drop_threshold  Float, default 0.6  Drop incoming frames if the fraction of full frames
 *                         to empty frames exceeds this value.  A value of 1.0 means only drop
 *                         frames if the connection is down, otherwise generate back-pressure
 *                         This setting has no effect if drop_frames is false
 *
 * @par Metrics
 * @metric kotekan_buffer_send_dropped_frame_count
 *         The number of frames dropped because @c send() is running too slow.
 *
 * @todo Add the rest of the comments here.
 * @todo we might also add counters for dropped frames because the connection
 *       is down, and frames that are lost because of connection errors.
 *
 * @author Andre Renard
 */


/**
 * @class hdf5FileWrite
 * @brief Stream a buffer to disk.
 *
 * This stage is intended to be used for code development and in tests, not in a production
 * pipeline. (In a production pipeline one would have to cycle file names.)
 *
 * @par Buffers:
 * @buffer in_buf Buffer to write to disk.
 *     @buffer_format Any
 *     @buffer_metadata Any
 *
 * @conf base_dir  String. Directory to write into.
 * @conf file_name String. Base filename to write.
 * @conf exit_after_n_frames  Int. Stop writing after this many frames, Default 0 = unlimited
 *       frames.
 * @conf exit_with_n_writers  Int. Exit after this many HDF5 writers finished writing, Default 0 =
 *       unlimited writers.
 *
 * @par Metrics
 * @metric kotekan_hdf5filewrite_write_time_seconds
 *         The write time to write out the last frame.
 *
 * @author Erik Schnetter
 **/


/**
 * @class visDebug
 * @brief Output some useful properties about the buffer for debugging
 *
 * The output is produced by calling ``VisFrameView::summary``
 *
 * @par Buffers
 * @buffer in_buf The buffer to debug
 *         @buffer_format VisBuffer structured
 *         @buffer_metadata VisMetadata
 *
 * @conf    output_period    Int. Print output every `output_period` frames.
 *                           Default is every 1000 frames.
 *
 * @par Metrics
 * @metric kotekan_visdebug_frames_by_freq_total
 *         The total frames seen per frequency.
 * @metric kotekan_visdebug_frames_by_dataset_total
 *         The total frames seen per dataset.
 *
 * @author Richard Shaw
 */


/*
 * @class rfiRecord
 * @brief Consumer ``kotekan::Stage`` which consumes and record a buffer filled with
 * spectral kurtosis estimates or feed variance, and writes it to disk.
 *
 * @par Buffers
 * @buffer rfi_in       The kotekan buffer containing spectral kurtosis estimates to be read by the
 * stage.
 *      @buffer_format  Array of @c floats
 *      @buffer_metadata chimeMetadata
 *
 * @conf   samples_per_data_set Int.    Number of time samples in a data set.
 * @conf   frames_per_file      Int.    Number of frames of data to write into each file
 * @conf   updatable_config     String. Path to updatable config block containing the two fields:
 *                                      "write_to_disk", bool for if we should write data
 *                                      "output_dir", string the location to write data files.
 *
 * @author Jacob Taylor and Andre Renard
 */


/**
 * @brief Merges frames from many buffers into one buffer.
 *
 * Merges the frames in order in a round-robin pattern. This means
 * the frame arrival rate must be the same for all input buffers.
 *
 * If this stage is the only comsumer of the input buffers then
 * the operation is zero-copy, it just swaps the frames.  However
 * if there is more than one comsumer on the input buffer then it
 * does a full memcpy of the frame.
 *
 * @warning The sizes of the frames must be the same in all buffers, and the
 *       metadata types and underlying pools must also be the same.
 *
 *
 * @par Buffers
 * @buffer in_bufs Array of input buffers to merge frames from.
 *                 This is a named array of input buffers in the format:
 *                 - internal_name_0: buffer_name_0
 *                 - internal_name_1: buffer_name_1
 *                 .
 *                 Or it can be provided without internal names:
 *                 - buffer_name_0
 *                 - buffer_name_1
 *                 .
 *                 The use of internal names is only needed if a subclass
 *                 of this function requires internal names to select frame.
 *        @buffer_format any, but all must be the same type.
 *        @buffer_metadata any, but all must be the same type.
 *
 * @buffer out_buf Buffer to get all the frames from the @c in_bufs
 *        @buffer_format Matches the input buffers
 *        @buffer_metadata Matches the input buffers
 *
 * @conf timeout       Double. Default -1.0   Timeout in seconds for waiting
 *                       for a frame on any of the input buffers.
 *                       Set to a negative number for no timeout.
 *
 * @author Andre Renard
 */


/**
 * @class nDiskFileRead
 * @brief Producer ``kotekan::Stage`` which reads VDIF data from multiple drives into a
 * ``Buffer``
 *
 * This is a producer which initiates n threads to read from n disks. Each disk must contain data in
 * the same folders as specified in the kotekan config file. Within each folder the data files must
 * be numbered incrementally across the disks. Since the file format is the most important aspect of
 * this stage, a worked example for a set of 3 disks is shown below.
 *
 * @par Buffers
 * @buffer out_buf The kotkean buffer to hold the data read from the drives
 * 	@buffer_format Array of unsigned char, just copies the file.
 * 	@buffer_metadata none
 *
 * @conf num_disks		Int , the number of drives to read from (Example: 10)
 * @conf disk_base		String, the path to the mounted drives (Example: '/drives/')
 * @conf disk_set		String, the disk name (Example: 'D')
 * @conf capture		String, the subfolder of the current data set (Example:
 * 20170805T155218Z_aro_vdif)
 * @conf starting_file_index 	Int, an offset for where to start in the data set (Example: 10232)
 *
 * @warning 	Not getting the file format correct will usually result in a segmentation fault. It
 * can be hard to figure out what is happening, so be extra cautious.
 *
 * @todo	Add rest server commands.
 *
 * Worked Example with n = 3:
 *
 * kotekan::Config Parameters:
 *
 * - num_disk: 3
 * - disk_base: /drives/
 * - disk_set: /D/
 * - capture: 20170805T155218Z_aro_vdif
 * - starting_index: 0
 *
 * What the file paths should look like:
 *
 * Drive 0:
 *
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000000.vdif
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000003.vdif
 * - /drives/D/0/20170805T155218Z_aro_vdif/0000006.vdif
 *
 * Drive 1:
 *
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000001.vdif
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000004.vdif
 * - /drives/D/1/20170805T155218Z_aro_vdif/0000007.vdif
 *
 * Drive 2:
 *
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000002.vdif
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000005.vdif
 * - /drives/D/2/20170805T155218Z_aro_vdif/0000008.vdif
 *
 * @author Jacob Taylor
 */


/**
 * @class basebandReadout
 * @brief Stage for extracting one frequency from the baseband buffer and putting it into a new
 * frame.
 *
 * This task manages a kotekan buffer, keeping it mostly full such that it subsets
 * of the data can be written upon triggered request.
 *
 * @par Buffers
 * @buffer in_buf buffer to manage and read. Must be several frames larger than
 *                ``num_frames_buffer`` config parameter.
 *         @buffer_format DPDK baseband ``samples_per_data_set x num_elements`` bytes
 *         @buffer_metadata chimeMetadata
 *
 * @buffer out_buf The extracted single frequency baseband output
 *         @buffer_format DPDK baseband ``samples_per_data_set x num_elements`` bytes
 *         @buffer_metadata BasebandMetadata
 *
 * @conf  num_elements          Int. The number of elements (i.e. inputs) in the
 *                              correlator data.
 * @conf  samples_per_data_set  Int. The number of time samples in a frame.
 * @conf  max_dump_samples      Int, default 2^30. Maximum number of samples in
 *                              baseband dump. Memory used for dumps limited to
 *                              3 x num_elements x this_number.
 * @conf  num_frames_buffer     Int. Number of buffer frames to simultaneously keep
 *                              full of data. Should be few less than in_buf length.
 * @conf  num_local_freq        UInt. Number of frequencies in each GPU frame.
 *
 * @par Metrics
 * @metric kotekan_baseband_readout_total
 *         The count of requests handled by an instance of this stage.
 *         Labels:
 *         - status: 'done', 'error', 'no_data'
 *         - freq_id: channel frequency received by this stage
 * @metric kotekan_baseband_readout_dropped_frames_total
 *         The count of DPDK frames dropped because the output buffer is backed up
 * @metric kotekan_baseband_readout_in_progress
 *         Indicator set to 1 when a per-frequency writeout is in progress, 0 otherwise
 * @metric kotekan_baseband_readout_sent_frames_total
 *         The count of baseband frames sent to the output buffer for transmission
 *
 * @author Kiyoshi Masui, Davor Cubranic
 */


/**
 * @class airspyInput
 * @brief Producer ``kotekan::Stage`` which streams radio data from an AirSpy SDR device
 * into a
 * ``Buffer``.
 *
 * This is a simple producer which initializes an AirSpy dongle (https://airspy.com)
 * in streaming mode, filling samples into the provided kotekan buffer.
 * It is agnostic about buffer framesize, simply filling in its data until a frame is full,
 * marking it so, requesting a new one, and continuing.
 * An internal sub-frame pointer is used to position data in subsequent callbacks within frames.
 * A pthread mutex is used to ensure callbacks don't clobber one another.
 *
 * This producer depends on ``libairspy``.
 *
 * @par Buffers
 * @buffer out_buf The kotekan buffer which will be fed, can be any size.
 *     @buffer_format Array of @c shorts
 *     @buffer_metadata none
 *
 * @conf   freq        Float (default 1420.0). LO tuning frequency, in MHz.
 * @conf   sample_bw   Float (default 2.5). Bandwidth to sample from the airspy, in MHz.
 * @conf   gain_lna    Int (default 5). Gain setting of the LNA, in the range 0-14.
 * @conf   gain_mix    Int (default 5). Gain setting of the mixer amplifier, from 0-15.
 * @conf   gain_if     Int (default 5). Gain setting of the IF amplifier, from 0-15.
 * @conf   biast_power Bool (default false). Whether or not to enable the 4.5V DC bias on the AirSpy
 * RF input.
 *
 * @warning Just realized that if things bog down and new 2 callbacks come while one is active,
 *          the order of the others will be undefined. This stage may produce out-of-order
 *          samples.
 * @remark  Only operates in I/Q mode currently, and only with packed int16_t samples.
 *          No support for raw samples, etc.
 * @todo    Only handles one device currently -- add checks and index handling.
 *          Undefined behaviour (segfault) if it doesn't exist or is already in use.
 *
 * @author Keith Vanderlinde
 *
 */


/**
 * @class countCheck
 * @brief Stage that checks for acquisition re-start.
 *
 * This stage finds the unix time at the start of the acquisition from
 * the FPGA counts and the current unix time, assuming 390625 FPGA
 * counts per second.
 * It stores this value and checks each frame to look for changes.
 * If the initial time changes by more than 'start_time_tolerance' (default=3)
 * seconds, the stage raises SIGTERM.
 *
 * @par Buffers
 * @buffer in_buf The buffer whose fpga count will be checked
 *         @buffer_format VisBuffer structured
 *         @buffer_metadata VisMetadata
 *
 * @conf  start_time_tolerance  int. Tolerance for the start time error in
 *                                   seconds. Default is 3.
 *
 * @author Mateus A Fandino
 */


/**
 * @class Valve
 * @brief ``kotekan::Stage`` that drops incoming frames when its output buffer
 * is full.
 *
 * This can have quite a small input buffer, since it drops frame from here, if
 * the output buffer is full.
 *
 * @par Buffers
 * @buffer in_buf The kotekan buffer from which frames are read, can be any size.
 *         @buffer_format GPU packed upper triangle
 *         @buffer_metadata chimeMetadata
 * @buffer out_buf The kotekan buffer which will be fed the subset of visibilities.
 *         @buffer_format GPU packed upper triangle
 *         @buffer_metadata chimeMetadata
 *
 * @par Metrics
 * @metric kotekan_valve_dropped_frames_total
 *        The number of frames dropped.
 *
 *
 * @author  Rick Nitsche
 *
 */


/**
 * @class ReceiveFlags
 * @brief Receives input flags and adds them to the output buffer.
 *
 * This stage registeres as a subscriber to an updatable config block. The
 * full name of the block should be defined in the value \<updatable_block\>
 *
 * @note If there are no other consumers on the input buffer it will be able to
 *       do a much faster zero copy transfer of the frame from input to output
 *       buffer.
 *
 * @par Buffers
 * @buffer in_buf The input stream.
 *         @buffer_format VisBuffer.
 *         @buffer_metadata VisMetadata
 * @buffer out_buf The output stream.
 *         @buffer_format VisBuffer.
 *         @buffer_metadata VisMetadata
 *
 * @conf   num_elements     Int.    The number of elements (i.e. inputs) in the
 *   correlator data.
 * @conf   updatable_block  String. The full name of the updatable_block that
 *   will provide new flagging values (e.g. "/dynamic_block/flagging").
 *
 * @par Metrics
 * @metric kotekan_receiveflags_late_update_count The number of updates received
 *     too late (The start time of the update is older than the currently
 *     processed frame).
 * @metric kotekan_receiveflags_late_frame_count The number of frames received
 *     late (The frames timestamp is older then all start times of stored
 *     updates).
 * @metric kotekan_receiveflags_update_age_seconds The time difference in
 *   seconds between the current frame being processed and the time stamp of
 *   the flag update being applied.
 *
 * @author Rick Nitsche
 */


/**
 * @class networkPowerStream
 * @brief Stage to take an intensity stream and stream to a remote client.
 *
 * This is a consumer stage which takes intensity data from a buffer and streams
 * it via TCP (and some day UDP) to a remote client, primarily for visualization purposes.
 *
 * In TCP mode, the stage should continually attempt to establish a TCP connection,
 * then transmit data once successful.
 *
 * @par Buffers
 * @buffer in_buf Input kotekan buffer containing power data to be sent.
 *     @buffer_format Array of @c uint
 *     @buffer_metadata none
 *
 * @conf   samples_per_data_set   Int. Number of time samples to sum.
 * @conf   power_integration_length     Int. Number of time samples to sum.
 * @conf   num_freq               Int. Number of time samples to sum.
 * @conf   num_elements           Int. Number of time samples to sum.
 * @conf   freq0                  Float (default 1420.0).
 * @conf   sample_bw              Float (default 10.0).
 * @conf   dest_port               Int. Number of time samples to sum.
 * @conf   dest_server_ip           Int. Number of time samples to sum.
 * @conf   dest_protocol          String. Should be @c "TCP" or @c "UDP"
 *
 * @warning UDP stream doesn't work at the moment.
 * @note    Lots of updating required once buffers are typed...
 *
 * @author Keith Vanderlinde
 *
 */


/**
 * @class asdfFileWrite
 * @brief Stream a buffer to disk.
 *
 * @par Buffers:
 * @buffer in_buf Buffer to write to disk.
 *     @buffer_format Any
 *     @buffer_metadata Any
 *
 * @conf base_dir  String. Directory to write into.
 * @conf file_name String. Base filename to write.
 * @conf exit_after_n_frames  Int. Stop writing after this many frames, Default 0 = unlimited
 *       frames.
 * @conf exit_with_n_writers  Int. Exit after this many ASDF writers finished writing, Default 0 =
 *       unlimited writers.
 *
 * @par Metrics
 * @metric kotekan_asdffilewrite_write_time_seconds
 *         The write time to write out the last frame.
 *
 * @author Erik Schnetter
 **/


/**
 * @class HFBWriter
 * @brief Stage to write raw absorber data.
 *
 * This class inherits from the BaseWriter base class and writes raw absorber data
 * @author James Willis
 **/


/**
 * @class pulsarNetworkProcess
 * @brief pulsarNetworkProcess Network transmission stage for Pulsar obs
 *
 *
 * This is an Kotekan stage that collects packetized data from the pulsarPostProcess and
 * transmits 10 beams from pulsarPostProcess to 10 links of pulsar backend.
 * pulsarNetworkProcess distributes the out going traffic to two VLANS (10.15 & 10.16 ) of single 1
 *Gig port. The total pulsar data rate is ~0.26 gbps. The node IP address is derived by parsing the
 *hostname.
 *
 * @par Buffers
 * @buffer in_buf The kotkean buffer to hold the packets to be transmitted to pulsar nodes
 * 	@buffer_format Array of unsigned char.
 * 	@buffer_metadata none
 *
 * @conf   udp_pulsar_packet_size  Int (default 6288). packet size including header
 * @conf   udp_pulsar_port_number  Int (default 1414). udp Port number for pulsar streams
 * @conf   number_of_nodes      Int (default 256). Number of L0 nodes
 * @conf   number_of_subnets    Int (default 2). Number of subnets or VLANS used for transmission of
 *PULSAR data
 * @conf   my_node_id           Int (parsed from the hostname) esimated from the location of node
 *from node location.
 *
 * @todo   Resolve the issue of NTP clock vs Monotonic clock.
 * @todo   Should run further tests
 *
 * @author Arun Naidu
 *
 *
 **/


/**
 * @class compressLostSamples
 * @brief Compresses the lost samples buffer into an array of
 *        @c samples_per_data_set/compression_factor values with the number of individual
 *        samples lost in each block of @c compression_factor values.
 *
 * @par Buffers
 * @buffer in_buf Kotekan buffer of lost samples.
 *     @buffer_format Array of @c chars
 * @buffer out_buf Kotekan buffer of compressed lost samples.
 *     @buffer_format Array of @c uint32_t
 *
 * @conf   samples_per_data_set  Int.    No. of samples.
 * @conf   compression_factor    Int.    Number of samples to group.
 * @conf   zero_all_in_group     bool.   If this set to true then one or more samples is lost in
 *                                       a @c compression_factor group, then consider that to be
 *                                       a total of @c compression_factor lost samples for the
 *                                       metadata lost_samples value.
 *
 * @author James Willis, Andre Renard
 *
 */


/**
 * @class ensureOrdered
 * @brief Check frames are coming through in order and reorder them otherwise.
 *        Not used presently.
 */


/**
 * @class cudaCorrelatorAstron
 * @brief cudaCommand for doing an N2 correlation. Uses John Romein's Tensor-based kernel.
 *
 * Kernel Reference: The Tensor-Core Correlator, John Romein, ASTRON,
 * Netherlands Institute for Radio Astronomy
 * https://doi.org/10.1051/0004-6361/202141896
 *
 * @author Keith Vanderlinde, kernels by John Romein
 *
 */


/**
 * @class cudaFRBBeamReformer
 * @brief cudaCommand for doing final FRB beamforming.  This follows the cudaFRBBeamFormer.
 *
 * Core code was developed by Nada El-Falou in https://github.com/nadafalou/CHORD/blob/main/mmul.cu
 *
 * The phase matrix for the beam locations uses the correct math but
 * with a lot of placeholder assumptions.  This will need to get
 * revisited in post-MVP development.
 */


/**
 * @class cudaSyncInput
 * @brief A synchronization point meant as a shortcut for the common case of waiting
 * on the input stream before starting the default kernel stream.
 *
 * This command is equivalent to a cudaSyncStream with @c cuda_stream
 * = 2 (the default kernel stream), waiting on stream 0 (the default
 * input stream).
 *
 * @author Dustin Lang
 */


/**
 * @class chordMVPSetup
 * @brief A CUDA GPU command for setting up buffers for our Minimum Viable Pipeline demo.
 *
 * Currently, this only sets up a couple of GPU buffer views to hack
 * our way around shortcomings in the MVP-era prototype code.
 *
 * Specifically:
 * - cudaUpchannelize produces outputs of size 2048.
 * - cudaFRBBeamformer consumes inputs of multiples of 48.
 * These don't match, so the cudaFRBBeamformer code manages a buffer
 * of leftover data that will get processed with the next frame of
 * data.  We want cudaUpchannelize to always be writing into a fixed
 * output array, so we make that an offset view into the buffer that
 * cudaFRBBeamformer will use for its input.  It then copies its
 * leftover bit of data from last time just before the
 * cudaUpchannelize output, computes the correct starting address in
 * the input buffer, and calls the GPU kernel with that pointer.
 *
 * - we use a buffer view to create an array of the right size (but
 * not the right contents!) to feed to an upchannelizer and create the
 * "Fine Visibility" matrix.  (We should subset the frequencies, but
 * for MVP purposes we just need to test the rate.  The data layout
 * has T varying most slowly, so we can do a time subset just with
 * array views, while doing the Frequency subset would require a
 * cudaMemcpy3DAsync
 *
 * @author Dustin Lang
 */


/**
 * @class cudaOutputDataZero
 * @brief cudaCommand for copying zeros onto the GPU,
 * e.g. to initialize output buffers.
 *
 * This is a cudaCommand that async copies a buffer of zeros from CPU to GPU.
 *
 * @par GPU Memory
 * @gpu_mem output           Buffer to zero, arbitrary size
 *     @gpu_mem_type         staging
 *     @gpu_mem_format       Any
 *
 * @conf   data_length       Int, size of buffer to zero in Bytes.
 *
 * @author Keith Vanderlinde
 *
 */


/**
 * @class cudaCommand
 * @brief Base class for defining CUDA commands to execute on GPUs
 *
 * This is a base class for CUDA commands to run on NVidia hardware.
 * Kernels and other operations (I/O) should derive from this class,
 * which handles a lot of queueing and device interface issues.
 *
 * @conf cuda_stream  The ID of the CUDA stream to use for this command, defaults to one of
 *                    0, 1, 2, for command types COPY_IN, COPY_OUT, and KERNEL respectively.
 *                    This number must be less than @c num_cuda_streams set in cudaProcess.
 * @conf required_flag  A string flag name.  If set, the @c cudaPipelineState object will be
 *                    checked for this flag, and this command will only run if that flag is set.
 *
 * @author Keith Vanderlinde and Andre Renard
 */


/**
 * @class cudaOutputData
 * @brief cudaCommand for copying data onto the GPU.
 *
 * This is a cudaCommand that async copies a buffer from GPU to CPU.
 * This code also passes metadata along from another buffer.
 *
 * @author Keith Vanderlinde and Andre Renard
 */


/**
 * @class cudaRechunk
 * @brief cudaCommand for combining GPU frames before further processing.
 *
 * @author Dustin Lang
 *
 * @par GPU Memory
 * @gpu_mem  gpu_mem_input  Input matrix of data (of unspecified type)
 *   @gpu_mem_type   staging
 *   @gpu_mem_format array of raw bytes
 * @gpu_mem  gpu_mem_output Output matrix of data (of unspecified type)
 *   @gpu_mem_type   staging
 *   @gpu_mem_format Array of raw bytes
 *
 * @conf cols_input  - Int
 * @conf cols_output - Int
 * @conf rows        - Int
 *
 * The input array is assumed to be of size (cols_input x rows) bytes.
 *
 * The output array is assumed to be of size (cols_output x rows) bytes.
 *
 * Assuming you have:
 * - Input matrix size R x C, element size S
 * - Number of input matrices to be concatenated = N
 *
 * If you want to "hstack" the input arrays -- that is, keeping the
 * number of rows the same -- then you can set the cols_input,
 * cols_output, and rows values to their intuitive values, where
 * cols_input includes the element size:
 *
 *   cols_input = C * S
 *   rows = R
 *   cols_output = C * S * N
 *
 * If you want to "vstack" the input arrays -- that is, keeping the
 * number of columns the same -- then you can instead think of this as
 * simply concatenating the bytes of your input matrices, and
 * therefore you can set:
 *   cols_input  = C * R * S
 *   cols_output = C * R * S * N
 *   rows = 1
 *
 * (That is, in memory, vstack'ing is just like doing a python ravel()
 * on your arrays and then appending them.)
 *
 * (These equations also work if N is not a whole number, ie, for
 * hstacking, the output column size can be C_out x S rather than
 * (C_in x N x S); for vstacking, the output column size can be (R_out
 * x C x S) rather than (R_in x N x C x S).)
 *
 */


/**
 * @class cudaInputData
 * @brief cudaCommand for copying data onto the GPU.
 *
 * This is a cudaCommand that async copies a buffer from CPU to GPU.
 *
 * @author Keith Vanderlinde and Andre Renard
 */


/**
 * @class cudaEventContainer
 * @brief Class to handle CUDA events for pipelining kernels & copies.
 *
 * @author Keith Vanderlinde
 */


/**
 * @class cudaSyncStream
 * @brief A synchronization point between one or more cuda streams.
 *
 * This command object adds a set of cudaStreamWaitEvent events to the queue given by @c cuda_stream
 * Which wait on the last event currently in each of the streams in @c source_cuda_streams
 *
 * @conf source_cuda_streams Array of cuda streams to synchronize on
 *
 * @author Andre Renard
 */


/**
 * @class cudaSyncOutput
 * @brief A synchronization point meant as a shortcut for the common case of waiting
 * on all compute streams before starting the output stream.
 *
 * This command is equivalent to a cudaSyncStream with @c cuda_stream
 * = 1 (the default output stream), waiting on streams >= 2 (the compute streams).
 *
 * @author Dustin Lang
 */


! Module to define simple error/exit codes
! and output messages.
!


!
! Profile_Utility_Parameters
!
! Module containing parameters used in the profile utility modules.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 30-Aug-2002
!                       paul.vandelst@ssec.wisc.edu
!


!
! Fundamental_Constants
!
! Module containing various fundamental mathematical and physical constants.
!
! The fundamental constants and equations used are taken from the NIST
! Reference on Constants, Units, and Uncertainty website:
!
!   http://physics.nist.gov/cuu/Constants/
!
! See also:
!
!   Mohr, P.J. and B.N. Taylor, "CODATA recommended values of the
!     fundamental physical constants: 1998", Reviews of Modern Physics,
!     Vol.72, No.2, 2000.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 02-May-2000
!                       paul.vandelst@ssec.wisc.edu
!


!
! Units_Conversion
!
! Module containing routines to convert atmospheric profile
! concentration units.
!
!
! CONTAINS:
!       Specific amount <-> mixing ratio
!       --------------------------------
!         SA_to_MR:       Function to convert gas concentrations from
!                         specific amount to mixing ratio.
!
!         MR_to_SA:       Function to convert gas concentrations from
!                         mixing ratio to specific amount.
!
!
!       Relative humidity <-> mixing ratio
!       ----------------------------------
!         RH_to_MR:       Function to convert water vapor amounts from
!                         relative humidity to mixing ratio.
!
!         MR_to_RH:       Function to convert water vapor amounts from
!                         mixing ratio to relative humidity.
!
!
!       Mixing ratio <-> ppmv
!       ---------------------
!         MR_to_PPMV:     Function to convert gas concentrations from
!                         mixing ratio to parts-per-million by volume.
!
!         PPMV_to_MR:     Function to convert gas concentrations from
!                         parts-per-million by volume to mixing ratio.
!
!
!       Partial pressure <-> ppmv
!       -------------------------
!         PPMV_to_PP:     Function to convert gas concentrations from
!                         parts-per-million by volume to partial pressure.
!
!         PP_to_PPMV:     Function to convert gas concentrations from
!                         partial pressure to parts-per-million by volume.
!
!
!       Partial pressure <-> mixing ratio
!       ---------------------------------
!         MR_to_PP:       Function to convert gas concentrations from mixing
!                         ratio to partial pressure in hectoPascals
!
!         PP_to_MR:       Function to convert gas concentrations from partial
!                         pressure in hectoPascals to mixing ratio in g/kg.
!
!
!       Partial pressure <-> mass density
!       ---------------------------------
!         PP_to_MD:       Function to convert gas concentrations in pressure
!                         units to mass density.
!
!         MD_to_PP:       Function to convert gas concentration mass density
!                         to partial pressure.
!
!
!       Partial pressure <-> number density
!       -----------------------------------
!         PP_to_ND:       Function to convert gas concentrations from (partial)
!                         pressures in hectoPascals to molecules/m^3.
!
!         ND_to_PP:       Function to convert gas concentrations from number
!                         densities in molecules/m^3 to (partial) pressures
!                         in hectoPascals.
!
!
!       Number density <-> ppmv
!       -----------------------
!         PPMV_to_ND:     Function to convert gas concentrations from
!                         parts-per-million by volume to molecules/m^3.
!
!         ND_to_PPMV:     Function to convert gas concentrations from number
!                         densities in molecules/m^3 to parts-per-million
!                         by volume.
!
!
!       Column density <-> ppmv
!       -----------------------
!         PPMV_to_KMOL:   Function to convert gas concentrations from parts-per-
!                         million by volume to kilomoles per cm^2.
!
!         KMOL_to_PPMV:   Function to convert gas concentrations from kilomoles
!                         per cm^2 to parts-per-million by volume.
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, 01-May-2000
!                       paul.vandelst@noaa.gov
!


!
! Compare_Float_Numbers
!
! Module containing routines to perform equality and relational
! comparisons on floating point numbers.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 01-Apr-2003
!                       paul.vandelst@ssec.wisc.edu
!


!
! Atmospheric_Properties
!
! Module containing utility routines to calculate various and sundry
! atmospheric properties.
!
! CONTAINS:
!       MW_Air:                   Function to calculate the effective, water
!                                 vapor weighted molecular weight of air.
!
!       Density:                  Function to calculate gas density using
!                                 the ideal gas law.
!
!       SVP_Water:                Function to calculate the saturation vapor
!                                 pressure over water.
!
!       SVP_Ice:                  Function to calculate the saturation vapor
!                                 pressure over ice.
!
!       Saturation_Mixing_Ratio:  Function to calculate the saturation mixing
!                                 ratio.
!
!       Virtual_Temperature:      Function to calculate the virtual
!                                 temperature, or its inverse.
!
!       Potential_Temperature:    Function to calculate the potential
!                                 temperature, or its inverse.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 01-May-2000
!                       paul.vandelst@noaa.gov
!


!
! Level_Layer_Conversion
!
! Module containing routines to convert LEVEL atmospheric profile
! quantities to LAYER quantities.
!
! CONTAINS:
!       Effective_Layer_TP:          Function to calculate the effective (or density
!                                    weighted) temperature and pressure for an
!                                    atmospheric layer.
!
!       Create_Sublevels:            Function to create the sublevels required to
!                                    accurately integrate gas amounts within a layer.
!
!       Integrate_Sublevels:         Function to integrate the temperature and
!                                    absorber amounts to produce average layer
!                                    values.
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 01-May-2000
!                       paul.vandelst@ssec.wisc.edu
!


!
! Type_Kinds
!
! Module to hold specification kinds for variable declaration, as well as
! associated descriptors.
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 12-Jun-2000
!                       paul.vandelst@ssec.wisc.edu
!


!
! Geopotential
!
! Module containing routines for calculating geopotential heights.
!
! CONTAINS:
!       Geopotential_Height:     Function to calculate the geopotential height
!                                for an input profile.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 01-May-2000
!                       paul.vandelst@ssec.wisc.edu
!


!
! Profile_Utility module
!
! Container module for all the Profile_Utility modules and dependencies.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 05-May-2006
!                       paul.vandelst@ssec.wisc.edu
!


!-----------------------BEGIN NOTICE -- DO NOT EDIT-----------------------
! NASA Goddard Space Flight Center
! Land Information System Framework (LISF)
! Version 7.5
!
! Copyright (c) 2024 United States Government as represented by the
! Administrator of the National Aeronautics and Space Administration.
! All Rights Reserved.
!-------------------------END NOTICE -- DO NOT EDIT-----------------------
!
! CRTM_Surface_Define
!
! Module defining the CRTM Surface structure and containing routines
! to manipulate it.
!
!
! CREATION HISTORY:
!       Written by:  Yong Han,       yong.han@noaa.gov
!                    Quanhua Liu,    quanhua.liu@noaa.gov
!                    Paul van Delst, paul.vandelst@noaa.gov
!                    07-May-2004
!


!-----------------------BEGIN NOTICE -- DO NOT EDIT-----------------------
! NASA Goddard Space Flight Center
! Land Information System Framework (LISF)
! Version 7.5
!
! Copyright (c) 2024 United States Government as represented by the
! Administrator of the National Aeronautics and Space Administration.
! All Rights Reserved.
!-------------------------END NOTICE -- DO NOT EDIT-----------------------
!
! NESDIS_LandEM_Module
!
! Module containing the NESDIS microwave land emissivity model
!
!
! CREATION HISTORY:
!       Written by:     Banghua Yan, QSS Group Inc., 01-Jun-2005
!                       Banghua.Yan@noaa.gov
!                       Fuzhong Weng, NOAA/NESDIS/ORA,
!                       Fuzhong.Weng@noaa.gov
!


!-----------------------BEGIN NOTICE -- DO NOT EDIT-----------------------
! NASA Goddard Space Flight Center
! Land Information System Framework (LISF)
! Version 7.5
!
! Copyright (c) 2024 United States Government as represented by the
! Administrator of the National Aeronautics and Space Administration.
! All Rights Reserved.
!-------------------------END NOTICE -- DO NOT EDIT-----------------------
!
! CRTM_MW_Land_SfcOptics
!
! Module to compute the surface optical properties for LAND surfaces at
! microwave frequencies required for determining the LAND surface
! contribution to the radiative transfer.
!
! This module is provided to allow developers to "wrap" their existing
! codes inside the provided functions to simplify integration into
! the main CRTM_SfcOptics module.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, CIMSS/SSEC 23-Jun-2005
!                       paul.vandelst@ssec.wisc.edu
!


!-----------------------BEGIN NOTICE -- DO NOT EDIT-----------------------
! NASA Goddard Space Flight Center
! Land Information System Framework (LISF)
! Version 7.5
!
! Copyright (c) 2024 United States Government as represented by the
! Administrator of the National Aeronautics and Space Administration.
! All Rights Reserved.
!-------------------------END NOTICE -- DO NOT EDIT-----------------------
!
! CRTM_MW_Snow_SfcOptics
!
! Module to compute the surface optical properties for SNOW surfaces at
! microwave frequencies required for determining the SNOW surface
! contribution to the radiative transfer.
!
! This module is provided to allow developers to "wrap" their existing
! codes inside the provided functions to simplify integration into
! the main CRTM_SfcOptics module.
!
!
! CREATION HISTORY:
!       Written by:     Paul van Delst, 23-Jun-2005
!                       paul.vandelst@noaa.gov
!
!       Modified by:    Banghua Yan, 03-Oct-2007
!                       Banghua.Yan@noaa.gov
!


! SUMMA - Structure for Unifying Multiple Modeling Alternatives
! Copyright (C) 2014-2015 NCAR/RAL
!
! This file is part of SUMMA
!
! For more information see: http://www.ral.ucar.edu/projects/summa
!
! This program is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program.  If not, see <http://www.gnu.org/licenses/>.


! SUMMA - Structure for Unifying Multiple Modeling Alternatives
! Copyright (C) 2014-2015 NCAR/RAL
!
! This file is part of SUMMA
!
! For more information see: http://www.ral.ucar.edu/projects/summa
!
! This program is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program.  If not, see <http://www.gnu.org/licenses/>.
! used to manage output statistics of the model and forcing variables


! cable_radiation.f90
!
! Source file containing radiation routines for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!   cable_radiation, and
! The subroutines included are:
!   init_radiation,
!   radiation
! The functions included are:
!   sinbet,
!   spitter
!
! Most user-defined types (e.g. met%tk) are defined in cable_types module
! in cable_variables.f90


! soil_snow.f90
!
! Soil and snow routines source file for CABLE
!
! Science development by Eva Kowalczyk, CSIRO Marine and Atmospheric Research
!
! Fortran-95 coding by Harvey Davies, Gab Abramowitz, Martin Dix and Bernard Pak
! Please report bugs to bernard.pak@csiro.au
!
! Major rewrite to modular format in Nov 2007 by Eva Kowalczyk
! Gab Abramowitz added tiling/veg patches April 2008
!
! This file contains the soil_snow_module only
! which has the following subroutines:
!   trimb,
!   smoisturev,
!   snowdensity,
!   snow_melting,
!   snow_accum,
!   surfbv,
!   snow_albedo,
!   stempv,
!   stempvsn,
!   snowcheck,
!   snowl_adjust,
!   soilfreeze,
!   remove_trans, and
!   soil_snow
!


! cable_carbon.f90
!
! Carbon store routines source file for CABLE
!
! The flow of carbon between the vegetation compartments and soil is described
! by a simple carbon pool model of Dickinson et al 1998, J. Climate, 11,
! 2823-2836.
! Model implementation by Eva Kowalczyk, CSIRO Marine and Atmospheric Research.
!
! bugs to bernard.pak@csiro.au
!
! This file contains the carbon_module only, which consists of 2 subroutines:
!   carbon_pl, and
!   soilcarb


! cable_canopy.f90
!
! Source file containing canopy code for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!   canopy_module
! The subroutines included are:
!   define_canopy
! The functions included are:
!   qsatf,
!   ej3x,
!   ej4x,
!   xvcmxt4,
!   xvcmxt3,
!   xejmxt3,
!   psim,
!   psis,
!   rplant, and
!   rsoil
!
! Most user-defined types (e.g. met%tk) are defined in cable_types module
! in cable_variables.f90


! cable_albedo.f90
!
! Source file containing albedo routine for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!   albedo_module
! The subroutines included are:
!   surface_albedo
!
! Most user-defined types (e.g. met%tk) are defined in cable_types module
! in cable_variables.f90


! cable_constants.f90
!
! Source file containing constants for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!  math_constants
!  physical_constants
!  other_constants
!  photosynthetic_constants
!  spatial_heterogeneity


! cable_dimensions.f90
!
! Source file containing dimensions variables for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach


! cable_air.f90
!
! Source file containing air routines for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!   air_module,
! The subroutines included are:
!   define_air,
!
! Most user-defined types (e.g. met%tk) are defined in cable_types module
! in cable_variables.f90


! cable_types.f90
!
! This file declares the main derived type variables for
! CABLE and contains the interface that allocates them.
!
! Development by (alphabetically) Gab Abramowitz, Harvey Davies,
! Martin Dix, Vanessa Haverd, Eva Kowalczyk, Ray Leuning,
! Mike Raupach, Ying-Ping Wang.
!
! bugs to bernard.pak@csiro.au
!
! The modules included are:
!   cable_types,
!     which contains subroutines:
!      alloc_*_type, and
!      dealloc_*_type


! cable_constants.f90
!
! Source file containing constants for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!  math_constants
!  physical_constants
!  other_constants
!  photosynthetic_constants
!  spatial_heterogeneity
!=========================================================================


! cable_canopy_vh.f90
!********************************************************************************
! Edited by VH and MC 16/10/09: Moved incanopy T to top of iteration loop;
! moved stability calc to top of iteration loop;
! removed restriction on fevc due to extractible water;
! introduced tolerances for qvair and Tvair to reduce number of iterations
! merge wet canopy calc into leaf T iteration loop
! recalc wetbal and drybal
! fwsoil modified to max(alpha2)
! initialised all local variables
!********************************************************************************
! Science development by Ying-Ping Wang, Eva Kowalczyk, Mike Raupach,
! Ray Leuning et al at CSIRO Marine and Atmospheric Research.
!
! Fortran-95 coding by Harvey Davies, Gab Abramowitz and Martin Dix
! bugs to gabsun@gmail.com.
!
! This file contains module canopy_module and subroutine define_canopy.
! The functions included are:
!   qsatf,
!   ej3
!   ej4x,
!   xvcmxt4,
!   xvcmxt3,
!   xejmxt3,
!   psim,
!   psis,
!   rplant, and
!   rsoil
!


! cable_roughness.f90
!
! Source file containing roughness routines for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!   cable_roughness
! The subroutines included are:
!   rough_resist
!
! Most user-defined types (e.g. met%tk) are defined in cable_types module
! in cable_variables.f90


! cable_constants.f90
!
! Source file containing constants for CABLE
!
! Development by Ying-Ping Wang, Eva Kowalczyk, Ray Leuning
! Gab Abramowitz, Martin Dix, Harvey Davies, Mike Raupach,
!
! bugs to bernard.pak@csiro.au
!
! This file contains modules:
!  math_constants
!  physical_constants
!  other_constants
!  photosynthetic_constants
!  spatial_heterogeneity
!=========================================================================
!=========================================================================


!
! Original code by P.J. Ross 2001-2007  See: Ross, P.J. (2003)
!     Modeling soil water and solute transport - fast, simplified numerical solutions. Agron. J. 95:1352-1361.
!
! Modified by V. Haverd 2008: matrix expanded by factor of 2 to allow solution of coupled heat/moisture fluxes
! Explicit calculation of heat/moisture fluxes at surface
! Switchable option for litter
! Isotope subroutine (V. Haverd and M. Cuntz, September 2008)
!
! Frozen Soil (V. Haverd Sep 2010 - Jan 2011)
! Pond lumped with top soil layer (V. Haverd Jan 2011)
! Snow included in layers -2:0 (V. Haverd Jan 2011)
! Convergence test for dthetaldT (V.Haverd Feb 2011)
! Include heat advection by liquid water flux (V.Haverd Feb 2011)
!


!-----------------------BEGIN NOTICE -- DO NOT EDIT-----------------------
! NASA Goddard Space Flight Center
! Land Information System Framework (LISF)
! Version 7.5
!
! Copyright (c) 2024 United States Government as represented by the
! Administrator of the National Aeronautics and Space Administration.
! All Rights Reserved.
!-------------------------END NOTICE -- DO NOT EDIT-----------------------


! File %M% from Library %Q%
! Version %I% from %G% extracted: %H%
!------------------------------------------------------------------------------


! File %M% from Library %Q%
! Version %I% from %G% extracted: %H%
!+ Data module for global parameters
!-------------------------------------------------------------------------------


!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
! The `halofit' code models the nonlinear evolution of cold matter
! cosmological power spectra. The full details of the way in which
! this is done are presented in Smith et al. (2002), MNRAS, ?, ?.
!
! The code `halofit' was written by R. E. Smith & J. A. Peacock.
! See http://www.astro.upenn.edu/~res,
!
! Subsequent updates as below
! Only tested for basic models with power law initial power spectra
! References for variant versions are
!   halofit_original: astro-ph/0207664
!   halofit_peacock: http://www.roe.ac.uk/~jap/haloes/
!   halofit_bird: arXiv: 1109.4416
!   halofit_takahashi: arXiv: 1208.2701
!   halofit_mead: arXiv:1505.07833,1602.02154
! Adapted for F90 and CAMB, AL March 2005
!!BR09 Oct 09: generalized expressions for om(z) and ol(z) to include w
! RT12 Oct: update some fitting parameters in the code to enhance
!           the power spectrum at small scales (arXiv:1208.2701)
!!JD 08/13: generalized expressions for om(z) and ol(z) to include
!           w_0 and w_a
! SPB14 Feb: update the fitting parameters for neutrinos to work with RT12
!           modifications
! AL Sept 14: added halofit_version parameter to change approximation used;
!   separate halofit.f90 is no longer needed as equations.f90 defined fixed wa_ppf
! Jan 15: Suggested change from Simeon Bird to avoid issues with very large Omm and neutrinos
!AM Mar 16: Added in HMcode
!AM May 16: Fixed some small bugs and added better neutrino approximations
!AL Jun16: put in partial openmp for HMcode (needs restructure to do properly)
!AM Sep 16: Attempted fix of strange bug. No more modules with unallocated arrays as inputs
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


!Lensing the C_l using the deflection angle from the computed lensing potential
!power spectrum.
!lensing_method=1: using an accurate curved-sky correlation function method
!lensing_method=2: using the flat-sky lower order result of astro-ph/9505109
!                  and astro-ph/9803150 as in CMBFAST
!lensing_method=3: using inaccurate full sky harmonic method of astro-ph/0001303
!The flat sky result is accurate to about 0.1% in TT, and 0.4% in EE and is
!about a factor of two faster than lensing_method=1.
!lensing_method=3 is only present for comparison and is not recommended in any regime
!Set accurate_BB=T if you want BB accurately by integrating the full angular range
!otherwise it saves a large amount of time by only integrating the small scales
!accute_BB only does *not* include any non-linear corrections or ensure you have
!chosen sufficiently high l_max and k_max, so does not neccessarily give an accurate
!result
!Uses the un-lensed Cls and the computed lensing potential power spectrum.
!Usual values of k_max are fine for all but the lensed BB Cls
!To get the lensed BB accurate around l=1000 you need to go to l_max >2000, and
!higher for higher l. Since this probes small scales in the lensing power spectrum you
!also need to go to higher k_max - for concordance models something like
!k_eta_max_scalar=10000. At l>1000 you can expect to need higher k_max, and for
!non-linear evolution to cause a significant error.
!Correlation function routines by AL+AC Nov 2004 with flat-sky borrowings from CMBFAST
!Curved sky results use the method of astro-ph/xxx.
!Full sky harmonic lensing routines by Gayoung Chon and AC.
!Ref: astro-ph/0001303 by W. Hu.
!For better derivations see also astro-ph/0301064 and astro-ph/0301031
!Adapted for CAMB and optimized by AL.
!Uses f90 version of "J1-RECURSION OF 3J-COEFFICIENTS" by K. Schulten and R.G. Gordon
!obtainable from the CPC program library (www.cpc.cs.qub.ac.uk).
!March 2006: fixed problem with l_max when generating with tensors (thanks Chad Fendt)


!This module provides the initial power spectra, parameterized as an expansion in ln k
!
! ln P_s = ln A_s + (n_s -1)*ln(k/k_0_scalar) + n_{run}/2 * ln(k/k_0_scalar)^2 + n_{runrun}/6 * ln(k/k_0_scalar)^3
!
! so if n_{run} = 0, n_{runrun}=0
!
! P_s = A_s (k/k_0_scalar)^(n_s-1)
!
!for the scalar spectrum, when n_s=an(in) is the in'th spectral index. k_0_scalar
!is a pivot scale, fixed here to 0.05/Mpc (change it below as desired or via .ini file).
!
!The tensor spectrum has three different supported parameterizations giving
!
! ln P_t = ln A_t + n_t*ln(k/k_0_tensor) + n_{t,run}/2 * ln(k/k_0_tensor)^2
!
! tensor_parameterization==tensor_param_indeptilt (=1) (default, same as CAMB pre-April 2014)
!
! A_t = r A_s
!
! tensor_parameterization==tensor_param_rpivot (=2)
!
! A_t = r P_s(k_0_tensor)
!
! tensor_parameterization==tensor_param_AT (=3)
!
! A_t =  tensor_amp
!
!The absolute normalization of the Cls is unimportant here, but the relative ratio
!of the tensor and scalar Cls generated with this module will be correct for general models
!
!December 2003 - changed default tensor pivot to 0.05 (consistent with CMBFAST 4.5)
!April 2014 added different tensor parameterizations, running of running and running of tensors


! Modules used by cmbmain and other routines.
!     Code for Anisotropies in the Microwave Background
!     by Antony Lewis (http://cosmologist.info) and Anthony Challinor
!     See readme.html for documentation.
!
!     Based on CMBFAST  by  Uros Seljak and Matias Zaldarriaga, itself based
!     on Boltzmann code written by Edmund Bertschinger, Chung-Pei Ma and Paul Bode.
!     Original CMBFAST copyright and disclaimer:
!
!     Copyright 1996 by Harvard-Smithsonian Center for Astrophysics and
!     the Massachusetts Institute of Technology.  All rights reserved.
!
!     THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. OR C.f.A. MAKE NO
!     REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
!     By way of example, but not limitation,
!     M.I.T. AND C.f.A MAKE NO REPRESENTATIONS OR WARRANTIES OF
!     MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
!     THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
!     ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
!
!     portions of this software are based on the COSMICS package of
!     E. Bertschinger.  See the LICENSE file of the COSMICS distribution
!     for restrictions on the modification and distribution of this software.


!Default parameterization using theta = r_s/D_a instead of H_0, and tau instead of z_re
!and log(A_s) instead of A_s
!Less general, but should give better performance
!
!The well-determined parameter A_s exp(-2tau) should be found by the covariance matrix
!parameter 3 is 100*theta, parameter 4 is tau, others same as params_H except A->log(A)
!Theta is much better constrained than H_0
!
!Also a background-only parameterization, e.g. for use with just supernoave etc


!>------------------------------------------------------------
!!  date / time delta module
!!
!!  Defines a time_delta_t object
!!
!!  Permits subtraction of two time objects resulting in a time_delta object
!!  time_delta can be accessed in days, hours, minutes, or seconds
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!------------------------------------------------------------


!>------------------------------------------------------------
!! Module provides geographic interpolation procedures
!! Various functions used for spatial interpolation from low-res
!! forcing grid to high-res model grid.
!!
!! <pre>
!!  Entry points:
!!      geo_LUT     : creates a geographic look uptable to convert one
!!                    grid to another
!!      geo_interp  : interpolates from one grid to another and
!!                    loops over the third dimension
!!      geo_interp2d: interpolates from one grid to another
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!------------------------------------------------------------


!>------------------------------------------------------------
!!  Module to provide vertical interpolation
!!  includes setting up a vertical Look Up Table (vLUT)
!!  and performing vertical interpolation (vinterp)
!!
!!  Similar in concept to the geo module
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!------------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  Model Initialization includes allocating memory for boundary and domain
!!      data structures.  It reads all of the options from the namelist
!!      file (or files).  It also reads in Lat/Lon and Terrain data.  This module
!!      also sets up geographic (and vertical) look uptables for the forcing data
!!      Finally, there is a driver routine to initialize all model physics packages
!!
!!   The module has been updated to allow arbitrary named variables
!!       this allows the use of e.g. ERAi, but still is not as flexible as it could be
!!
!!   The use of various python wrapper scripts in helpers/ makes it easy to add new
!!       datasets, and make them conform to the expectations of the current system.
!!      For now there are no plans to near term plans to substantially modify this.
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  Main time stepping module.
!!  Calculates a stable time step (dt) and loops over physics calls
!!  Also updates boundaries every time step.
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  A tool to track model versions and print useful changes between model versions
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!>------------------------------------------------
!! Contains type definitions for a variety of model data strucutres
!! Also defines model constants (e.g. gravity, and MAXFILELENGTH)
!!
!! <pre>
!! General Field Definitions
!!
!! ---- 3D fields ---- NX x NZ x NY
!! u        = wind in east direction                        [m/s]
!! v        = wind in north direction                       [m/s]
!! w        = wind in vertical direction                    [m/s] (possibly scaled by dx/dz)
!!
!! p        = pressure                                      [pa]
!! th       = potential temperature                         [K]
!!
!! qv       = water vapor (mixing ratio)                    [kg/kg]
!! cloud    = cloud water                                   [kg/kg]
!! ice      = cloud ice                                     [kg/kg]
!! qrain    = rain mixing ratio                             [kg/kg]
!! qsnow    = snow mixing ratio                             [kg/kg]
!! qgrau    = graupel mixing ratio                          [kg/kg]
!! nice     = ice number concentration                      [1/cm^3]
!! nrain    = rain number concentration                     [1/cm^3]
!!
!! rho      = dry air density                               [kg/m^3]
!! pii      = exner function                                []
!!
!! ---- 2D fields ---- NX x NY
!!      ---- moisture fluxes ----
!! rain     = rain+crain+snow+graupel                       [mm]
!! crain    = convective rain at surface                    [mm]
!! snow     = snow at surface                               [mm]
!! graupel  = graupel at surface                            [mm]
!!
!!      ---- energy fluxes ----
!! sensible_heat = Sensible heat flux from surface          [W/m^2]
!! latent_heat   = Latent heat flux from surface            [W/m^2]
!! pbl_height    = Height of the planetary boundary layer   [m]
!!
!!      ---- Radiation variables ----
!! cloudfrac    = Cloud fraction                            [0-1]
!! swdown       = Shortwave down at land surface            [W/m^2]
!! lwdown       = Longwave down at land surface             [W/m^2]
!! lwup         = Lonwave up from the land surface          [W/m^2]
!!
!! ---- Land Surface variables ----
!!   3D fields ---- NX x NZ x NY (NZ = number of soil layers)
!! soil_t       = 3D Soil temperature                       [K]
!! soil_vwc     = 3D Soil volumetric water content          [m^3/m^3]
!!
!!   3D fields ---- NX x NY x N_Times (typically 1 or 12)
!! vegfrac      = vegetation cover fraction                 [%]
!!
!!   2D fields ---- NX x NY
!! skin_t       = Land surface skin temperature             [K]
!! soil_tdeep   = Temperature at the soil column bottom     [K]
!! snow_swe     = Snow water equivalent on the land surface [mm]
!! soil_totalmoisture = Soil column total water content     [mm]
!! soil_type    = Soil type (index for SOILPARM.TBL)        [1-n]
!! veg_type     = Vegetation type (index for VEGPARM.TBL)   [1-n]
!! landmask     = Map of Land vs Water grid cells           [0,1,2]
!!
!! ---- NOTE ----
!! dX_dt variables are the increment in boundary conditions between internal model time steps
!! some of these are 2d, some are 3d
!!
!! ---- model structure ----
!! terrain  = surface elevation                             [m]
!! z        = model layer height (at mid point)             [m]
!! dz       = Model layer thickness (between mass levels)   [m]
!! dz_inter = Layer thickness (between interface levels)    [m]
!!
!! sintheta = sine of the angle between grid and geographic coords   [-]
!! costheta = cosine of the angle between grid and geographic coords [-]
!! fzs      = buffered FFT(terrain) for linear wind calculations
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!>------------------------------------------------


!>------------------------------------------------------------
!!  Noah Land Surface Model (from WRF)
!!
!!  @author
!!  various (see Chen and Dudhia 2001)
!!
!!------------------------------------------------------------


!+---+-----------------------------------------------------------------+
!.. This subroutine computes the moisture tendencies of water vapor,
!.. cloud droplets, rain, cloud ice (pristine), snow, and graupel.
!.. Prior to WRFv2.2 this code was based on Reisner et al (1998), but
!.. few of those pieces remain.  A complete description is now found in
!.. Thompson, G., P. R. Field, R. M. Rasmussen, and W. D. Hall, 2008:
!.. Explicit Forecasts of winter precipitation using an improved bulk
!.. microphysics scheme. Part II: Implementation of a new snow
!.. parameterization.  Mon. Wea. Rev., 136, 5095-5115.
!.. Prior to WRFv3.1, this code was single-moment rain prediction as
!.. described in the reference above, but in v3.1 and higher, the
!.. scheme is two-moment rain (predicted rain number concentration).
!..
!.. Beginning with WRFv3.6, this is also the "aerosol-aware" scheme as
!.. described in Thompson, G. and T. Eidhammer, 2014:  A study of
!.. aerosol impacts on clouds and precipitation development in a large
!.. winter cyclone.  J. Atmos. Sci., 71, 3636-3658.  Setting WRF
!.. namelist option mp_physics=8 utilizes the older one-moment cloud
!.. water with constant droplet concentration set as Nt_c (found below)
!.. while mp_physics=28 uses double-moment cloud droplet number
!.. concentration, which is not permitted to exceed Nt_c_max below.
!..
!.. Most importantly, users may wish to modify the prescribed number of
!.. cloud droplets (Nt_c; see guidelines mentioned below).  Otherwise,
!.. users may alter the rain and graupel size distribution parameters
!.. to use exponential (Marshal-Palmer) or generalized gamma shape.
!.. The snow field assumes a combination of two gamma functions (from
!.. Field et al. 2005) and would require significant modifications
!.. throughout the entire code to alter its shape as well as accretion
!.. rates.  Users may also alter the constants used for density of rain,
!.. graupel, ice, and snow, but the latter is not constant when using
!.. Paul Field's snow distribution and moments methods.  Other values
!.. users can modify include the constants for mass and/or velocity
!.. power law relations and assumed capacitances used in deposition/
!.. sublimation/evaporation/melting.
!.. Remaining values should probably be left alone.
!..
!..Author: Greg Thompson, NCAR-RAL, gthompsn@ucar.edu, 303-497-2805
!..Last modified: 01 Aug 2016   Aerosol additions to v3.5.1 code 9/2013
!..                 Cloud fraction additions 11/2014 part of pre-v3.7
!+---+-----------------------------------------------------------------+
!wrft:model_layer:physics
!+---+-----------------------------------------------------------------+
!


!>----------------------------------------------------------------------
!!   This subroutine computes the moisture tendencies of water vapor,
!!   cloud droplets, rain, cloud ice (pristine), snow, and graupel.
!!
!!   Prior to WRFv2.2 this code was based on Reisner et al (1998), but
!!   few of those pieces remain.  A complete description is now found in
!!   Thompson, G., P. R. Field, R. M. Rasmussen, and W. D. Hall, 2008:
!!   Explicit Forecasts of winter precipitation using an improved bulk
!!   microphysics scheme. Part II: Implementation of a new snow
!!   parameterization.  Mon. Wea. Rev., 136, 5095-5115.
!!   Prior to WRFv3.1, this code was single-moment rain prediction as
!!   described in the reference above, but in v3.1 and higher, the
!!   scheme is two-moment rain (predicted rain number concentration).
!!
!!   Most importantly, users may wish to modify the prescribed number of
!!   cloud droplets (Nt_c; see guidelines mentioned below).  Otherwise,
!!   users may alter the rain and graupel size distribution parameters
!!   to use exponential (Marshal-Palmer) or generalized gamma shape.
!!   The snow field assumes a combination of two gamma functions (from
!!   Field et al. 2005) and would require significant modifications
!!   throughout the entire code to alter its shape as well as accretion
!!   rates.  Users may also alter the constants used for density of rain,
!!   graupel, ice, and snow, but the latter is not constant when using
!!   Paul Field's snow distribution and moments methods.  Other values
!!   users can modify include the constants for mass and/or velocity
!!   power law relations and assumed capacitances used in deposition/
!!   sublimation/evaporation/melting.
!!   Remaining values should probably be left alone.
!!
!!  Modifications for ICAR include OPENMP paralellization and the ability
!!  to input many important parameters so they are no longer hard coded
!!
!!  @author Greg Thompson, NCAR-RAL, gthompsn@ucar.edu, 303-497-2805
!!  Last modified: 27 Jul 2012
!!
!!--------------------------------------------------------------------
!wrft:model_layer:physics
!+---+-----------------------------------------------------------------+
!


!>------------------------------------
!! Tiedtke cumulus scheme from WRF.
!!
!!------------------------------------
!-----------------------------------------------------------------------
!
!WRF:MODEL_LAYER:PHYSICS
!
!####################TIEDTKE SCHEME#########################
!   Taken from the IPRC iRAM - Yuqing Wang, University of Hawaii
!   Added by Chunxi Zhang and Yuqing Wang to WRF3.2, May, 2010
!   refenrence: Tiedtke (1989, MWR, 117, 1779-1800)
!               Nordeng, T.E., (1995), CAPE closure and organized entrainment/detrainment
!               Yuqing Wang et al. (2003,J. Climate, 16, 1721-1738) for improvements
!                                                  for cloud top detrainment
!                       (2004, Mon. Wea. Rev., 132, 274-296), improvements for PBL clouds
!                        (2007,Mon. Wea. Rev., 135, 567-585), diurnal cycle of precipitation
!   This scheme is on testing
!###########################################################


!>----------------------------------------------------------
!! Not really a land surface model, use coarse model fluxes
!!
!! This code was used in very early versions
!! of ICAR and is maintained for now just in case it becomes of interest again.
!! Takes sensible and latent heat fluxes supplied by coarse model and adds them in
!! this code is generally deprecated.
!!
!! Also provides simple PBL mixing, and radiative cooling
!!  (which shouldn't be here.)
!!
!! The entry point to the code is lsm_basic(domain,options,dt)
!!
!! <pre>
!! Call tree graph :
!! lsm_basic->
!!  [->],
!!  [->],
!!  [->]
!!
!! High level routine descriptions / purpose
!!
!! Driver inputs: domain,options,dt
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>----------------------------------------------------------
!! Very simple microphysics code modeled after the microphysics of SB04
!! used in Smith and Barstad '04 (the linear model).
!!
!! Clouds (solid and liquid) form and evaporate instantly
!! Clouds convert to rain (or snow) with a time constant tau [s]
!!   typically rain_tau ~500s snow_tau ~2000s
!! Fall speeds in SB04 assume 10m/s (rain) and 1.5m/s (snow).
!! In SB04 this is treated by means of a time constant (=height/speed).
!! Here it is modeled explicitly with these fall speeds
!!
!! The entry point to the code is mp_simple_driver.
!!
!! <pre>
!! Call tree graph :
!! mp_simple_driver->mp_simple->
!!   [mp_conversions->
!!       [cloud_conversion->sat_mr,
!!        cloud2hydrometeor,
!!        phase_change],
!!   sediment]
!!
!! High level routine descriptions / purpose
!!   mp_simple_driver    - loops over X,Y grid cells, calls mp_simple on columns
!!   mp_simple           - calls mp_conversions for all z, then calls sediment
!!   mp_conversions      - handles all microphysics conversions (e.g. vapor->cloud->rain[->snow->vapor],...)
!!   cloud_conversion    - uses sat_mr to calculate sub or supersaturation and changes vapor and cloud water to balance
!!                          (adjusts temperature for Latent Heating)
!!   cloud2hydrometeor   - converts cloud water to rain or snow (temperature dependant)
!!   phase_change        - handles rain and snow evaporation (can take a time constant)
!!   sediment            - advects falling rain and snow due to gravity (not wind)
!!   sat_mr              - calculate saturated water vapor mixing ratio
!!
!! Driver inputs: pressure,th,pii,rho,qv,qc,qr,qs,rain,snow,dt,dz,nx,ny,nz
!!   pressure   = pressure                      - 3D - input  - Pa     - (nx,nz,ny)
!!   th         = potential temperature         - 3D - in/out - K      - (nx,nz,ny)
!!   pii        = exner function                - 3D - input  - []     - (nx,nz,ny)
!!   rho        = air density                   - 3D - input  - kg/m^3 - (nx,nz,ny)
!!   qv         = specific humidity             - 3D - in/out - kg/kg  - (nx,nz,ny)
!!   qc         = cloud water content           - 3D - in/out - kg/kg  - (nx,nz,ny)
!!   qr         = rain water content            - 3D - in/out - kg/kg  - (nx,nz,ny)
!!   qs         = snow water content            - 3D - in/out - kg/kg  - (nx,nz,ny)
!!   rain       = accumulated rain              - 2D - output - mm     - (nx,ny)
!!   snow       = accumulated snow              - 2D - output - mm     - (nx,ny)
!!   dt         = time step                     - 0D - input  - sec.   - scalar
!!   nx         = number of ew grid cells       - 0D - input  - n      - scalar
!!   ny         = number of ns grid cells       - 0D - input  - n      - scalar
!!   nz         = number of vertical grid cells - 0D - input  - n      - scalar
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>----------------------------------------------------------
!! This module provides the linear wind theory calculations
!!
!!  Code is based primarily off equations in Barstad and Gronas (2006)
!!  @see Appendix A of Barstad and Gronas (2006) Tellus,58A,2-18
!!
!! The main entry point to the code is:
!!      linear_perturb(domain, options, vsmooth, reverse, useDensity)
!!
!! <pre>
!! Call tree graph :
!!  linear_perturb->[ setup_linwinds -> add_buffer_topo,
!!                    calc_domain_stability,
!!                    linear_winds -> various fft routines]
!!
!! High level routine descriptions / purpose
!!   calc_domain_stability    - calculates a mean Brunt Vaisala frequency over the domain
!!   linear_winds             - primary routine that calculates the linear wind perturbation
!!   add_buffer_topo          - generates a topo grid that with a surrounding buffer for the fft
!!   initialize_spatial_winds - generated the look up tables to use spatially varying linear winds
!!   setup_linwinds           - sets up module level variables and calls add_buffer_topo
!!   linear_perturb           - main entry point, calls setup on first entry for a given domain
!!
!! Inputs: domain, options, vsmooth, reverse, useDensity
!!      domain,options  = as defined in data_structures
!!      vsmooth         = number of vertical levels to smooth winds over
!!      reverse         = remove linear perturbation instead of adding it
!!      useDensity      = create a linear field that attempts to mitigate the
!!                          boussinesq approx that is embedded in the linear theory
!!                          so it advection can properly incorporate density.
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>------------------------------------------------------------
!! Module to manage the ICAR wind field, including calls to linear winds
!! importantly it also rotates the wind field into the ICAR grid and
!! balances the U, V, and W fields for "mass" conservation
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!------------------------------------------------------------


! #if ( RWORDSIZE == 4 )
! #  define VREC vsrec
! #  define VSQRT vssqrt
! #else
! #  define VREC vrec
! #  define VSQRT vsqrt
! #endif
! subroutine vssqrt(y,x,n)
!     real, intent(inout) :: y(n)
!     real, intent(in) :: x(n)
!     integer, intent(in) :: n
!     integer :: j
!     do j=1,n
!         y(j)=sqrt(x(j))
!     enddo
! end
!
! subroutine vsrec(y,x,n)
!     real, intent(inout) :: y(n)
!     real, intent(in) :: x(n)
!     integer, intent(in) :: n
!     integer :: j
!     do j=1,n
!         y(j)=1.0/(x(j))
!     enddo
! end


!> ----------------------------------------------------------------------------
!!  Driver to call different convection schemes
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!>----------------------------------------------------------
!! This module provides a wrapper to call various land surface models
!!
!! It sets up variables specific to the LSM to be used including both
!! history variables not currently stored in the domain level data
!! structure, and runtime parameters
!!
!! The main entry point to the code is lsm(domain,options,dt,model_time)
!!
!! <pre>
!! Call tree graph :
!!  lsm_init->[ allocate_noah_data,
!!              external initialization routines]
!!  lsm->[  sat_mr,
!!          calc_exchange_coefficient,
!!          external LSM routines]
!!
!! High level routine descriptions / purpose
!!   lsm_init           - allocates module data and initializes physics package
!!   lsm                - sets up and calls main physics package
!!  calc_exchange_coefficient - calculates surface exchange coefficient (for Noah)
!!  allocate_noah_data  - allocate module level data for Noah LSM
!!  apply_fluxes        - apply LSM fluxes (e.g. sensible and latent heat fluxes) to atmosphere
!!
!! Inputs: domain, options, dt, model_time
!!      domain,options  = as defined in data_structures
!!      dt              = time step (seconds)
!!      model_time      = time since beginning date (seconds)
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  A collection of flux correction schemes for advection
!!
!!  @author
!!  Dylan Reynolds (dylan.reynolds@slf.ch)
!!
!! ----------------------------------------------------------------------------


!>----------------------------------------------------------------------
!! THIS MODULE CONTAINS THE TWO-MOMENT MICROPHYSICS CODE DESCRIBED BY
!!     MORRISON ET AL. (2009, MWR)
!!
!! CHANGES FOR V3.2, RELATIVE TO MOST RECENT (BUG-FIX) CODE FOR V3.1
!!
!! 1) ADDED ACCELERATED MELTING OF GRAUPEL/SNOW DUE TO COLLISION WITH RAIN, FOLLOWING LIN ET AL. (1983)
!! 2) INCREASED MINIMUM LAMBDA FOR RAIN, AND ADDED RAIN DROP BREAKUP FOLLOWING MODIFIED VERSION
!!     OF VERLINDE AND COTTON (1993)
!! 3) CHANGE MINIMUM ALLOWED MIXING RATIOS IN DRY CONDITIONS (RH < 90%), THIS IMPROVES RADAR REFLECTIIVITY
!!     IN LOW REFLECTIVITY REGIONS
!! 4) BUG FIX TO MAXIMUM ALLOWED PARTICLE FALLSPEEDS AS A FUNCTION OF AIR DENSITY
!! 5) BUG FIX TO CALCULATION OF LIQUID WATER SATURATION VAPOR PRESSURE (CHANGE IS VERY MINOR)
!! 6) INCLUDE WRF CONSTANTS PER SUGGESTION OF JIMY
!!
!! bug fix, 5/12/10
!! 7) bug fix for saturation vapor pressure in low pressure, to avoid division by zero
!! 8) include 'EP2' WRF constant for saturation mixing ratio calculation, instead of hardwire constant
!!
!! CHANGES FOR V3.3
!! 1) MODIFICATION FOR COUPLING WITH WRF-CHEM (PREDICTED DROPLET NUMBER CONCENTRATION) AS AN OPTION
!! 2) MODIFY FALLSPEED BELOW THE LOWEST LEVEL OF PRECIPITATION, WHICH PREVENTS
!!      POTENTIAL FOR SPURIOUS ACCUMULATION OF PRECIPITATION DURING SUB-STEPPING FOR SEDIMENTATION
!! 3) BUG FIX TO LATENT HEAT RELEASE DUE TO COLLISIONS OF CLOUD ICE WITH RAIN
!! 4) CLEAN UP OF COMMENTS IN THE CODE
!!
!! additional minor bug fixes and small changes, 5/30/2011
!! minor revisions by A. Ackerman April 2011:
!! 1) replaced kinematic with dynamic viscosity
!! 2) replaced scaling by air density for cloud droplet sedimentation
!!    with viscosity-dependent Stokes expression
!! 3) use Ikawa and Saito (1991) air-density scaling for cloud ice
!! 4) corrected typo in 2nd digit of ventilation constant F2R
!!
!! additional fixes:
!! 5) TEMPERATURE FOR ACCELERATED MELTING DUE TO COLLIIONS OF SNOW AND GRAUPEL
!!    WITH RAIN SHOULD USE CELSIUS, NOT KELVIN (BUG REPORTED BY K. VAN WEVERBERG)
!! 6) NPRACS IS NOT SUBTRACTED FROM SNOW NUMBER CONCENTRATION, SINCE
!!    DECREASE IN SNOW NUMBER IS ALREADY ACCOUNTED FOR BY NSMLTS
!! 7) fix for switch for running w/o graupel/hail (cloud ice and snow only)
!!
!! hm bug fix 3/16/12
!!
!! 1) very minor change to limits on autoconversion source of rain number when cloud water is depleted
!!
!! WRFV3.5
!! hm/A. Ackerman bug fix 11/08/12
!!
!! 1) for accelerated melting from collisions, should use rain mass collected by snow, not snow mass
!!    collected by rain
!! 2) minor changes to some comments
!! 3) reduction of maximum-allowed ice concentration from 10 cm-3 to 0.3
!!    cm-3. This was done to address the problem of excessive and persistent
!!    anvil cirrus produced by the scheme.
!!
!! CHANGES FOR WRFV3.5.1
!! 1) added output for snow+cloud ice and graupel time step and accumulated
!!    surface precipitation
!! 2) bug fix to option w/o graupel/hail (IGRAUP = 1), include PRACI, PGSACW,
!!    and PGRACS as sources for snow instead of graupel/hail, bug reported by
!!    Hailong Wang (PNNL)
!! 3) very minor fix to immersion freezing rate formulation (negligible impact)
!! 4) clarifications to code comments
!! 5) minor change to shedding of rain, remove limit so that the number of
!!    collected drops can smaller than number of shed drops
!! 6) change of specific heat of liquid water from 4218 to 4187 J/kg/K
!!
!! CHANGES FOR WRFV3.6.1
!! 1) minor bug fix to melting of snow and graupel, an extra factor of air density (RHO) was removed
!!    from the calculation of PSMLT and PGMLT
!! 2) redundant initialization of PSMLT (non answer-changing)
!!
!! ----------------------------------------------------------------------
!!
!! THIS SCHEME IS A BULK DOUBLE-MOMENT SCHEME THAT PREDICTS MIXING
!! RATIOS AND NUMBER CONCENTRATIONS OF FIVE HYDROMETEOR SPECIES:
!! CLOUD DROPLETS, CLOUD (SMALL) ICE, RAIN, SNOW, AND GRAUPEL.
!!----------------------------------------------------------------------
!
!WRF:MODEL_LAYER:PHYSICS
!


!-----------------------------------------------------------------------
!
! Contains all subroutines to get time-varying mixing ratios of CO2,
! N2O, CH4, CFC11 and CFC12 into radiation schemes.
! These subroutines enable the user to specify the mixing ratios
! in the file CAMtr_volume_mixing_ratio, giving the user an easy way
! to specify trace gases concentrations.
!
! The subroutines were first developed by and put together in this module
! by C. Carouge.
!-----------------------------------------------------------------------


!>----------------------------------------------------------
!! This module provides a wrapper to call various radiation models
!! It sets up variables specific to the physics package to be used
!!
!! The main entry point to the code is rad(domain,options,dt)
!!
!! <pre>
!! Call tree graph :
!!  radiation_init->[ external initialization routines]
!!  rad->[  external radiation routines]
!!
!! High level routine descriptions / purpose
!!   radiation_init     - initializes physics package
!!   rad                - sets up and calls main physics package
!!
!! Inputs: domain, options, dt
!!      domain,options  = as defined in data_structures
!!      dt              = time step (seconds)
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>----------------------------------------------------------
!! This module provides a wrapper to call various PBL models
!! It sets up variables specific to the physics package to be used including both
!!
!! The main entry point to the code is pbl(domain,options,dt)
!!
!! <pre>
!! Call tree graph :
!!  pbl_init->[ external initialization routines]
!!  pbl->[  external PBL routines]
!!  pbl_finalize
!!
!! High level routine descriptions / purpose
!!   pbl_init           - initializes physics package
!!   pbl                - sets up and calls main physics package
!!   pbl_finalize       - permits physics package cleanup (close files, deallocate memory)
!!
!! Inputs: domain, options, dt
!!      domain,options  = as defined in data_structures
!!      dt              = time step (seconds)
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  Standard advection scheme with variable order
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!  Dylan Reynolds (dylan.reynolds@slf.ch)
!!
!! ----------------------------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  The MPDATA advection scheme
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!     path:      $Source: /cvsroot/NWP/WRFV3/phys/module_ra_rrtmg_lw.F,v $
!     author:    $Author: trn $
!     revision:  $Revision: 1.3 $
!     created:   $Date: 2009/04/16 19:54:22 $
!
! Fortran-95 implementation of the Mersenne Twister 19937, following
!   the C implementation described below (code mt19937ar-cok.c, dated 2002/2/10),
!   adapted cosmetically by making the names more general.
! Users must declare one or more variables of type randomNumberSequence in the calling
!   procedure which are then initialized using a required seed. If the
!   variable is not initialized the random numbers will all be 0.
! For example:
! program testRandoms
!   use RandomNumbers
!   type(randomNumberSequence) :: randomNumbers
!   integer                    :: i
!
!   randomNumbers = new_RandomNumberSequence(seed = 100)
!   do i = 1, 10
!     print ('(f12.10, 2x)'), getRandomReal(randomNumbers)
!   end do
! end program testRandoms
!
! Fortran-95 implementation by
!   Robert Pincus
!   NOAA-CIRES Climate Diagnostics Center
!   Boulder, CO 80305
!   email: Robert.Pincus@colorado.edu
!
! This documentation in the original C program reads:
! -------------------------------------------------------------
!    A C-program for MT19937, with initialization improved 2002/2/10.
!    Coded by Takuji Nishimura and Makoto Matsumoto.
!    This is a faster version by taking Shawn Cokus's optimization,
!    Matthe Bellew's simplification, Isaku Wada's real version.
!
!    Before using, initialize the state by using init_genrand(seed)
!    or init_by_array(init_key, key_length).
!
!    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
!    All rights reserved.
!
!    Redistribution and use in source and binary forms, with or without
!    modification, are permitted provided that the following conditions
!    are met:
!
!      1. Redistributions of source code must retain the above copyright
!         notice, this list of conditions and the following disclaimer.
!
!      2. Redistributions in binary form must reproduce the above copyright
!         notice, this list of conditions and the following disclaimer in the
!         documentation and/or other materials provided with the distribution.
!
!      3. The names of its contributors may not be used to endorse or promote
!         products derived from this software without specific prior written
!         permission.
!
!    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
!    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
!    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
!    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
!    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
!    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
!    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
!    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
!    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
!    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
!    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!
!
!    Any feedback is very welcome.
!    http://www.math.keio.ac.jp/matumoto/emt.html
!    email: matumoto@math.keio.ac.jp
! -------------------------------------------------------------


!>------------------------------------------------------------
!! Module to pre-compute terrain descriptors for thermal winds
!! and then apply a thermal wind correction based on Mahrt 1982
!! and Scire and Robe 2000
!!
!!  @author
!!  Dylan Reynolds (dylan.reynolds@slf.ch)
!!
!!------------------------------------------------------------


!>----------------------------------------------------------
!! NOTE: CODE IS INCOMPLETE AND WILL NOT WORK
!!
!! Very simple land surface model code
!!
!! Rain is partitioned into infiltration and runoff
!! Snow is accumulated on the surface, then melts, runsoff, or sublimates
!! Soil moisture is permitted to be lost to ET or subsurface flow
!!
!! ET, Sensible Heat Flux, and Longwave are partitioned using Penman Monteith.
!!
!! The entry point to the code is lsm_simple.
!!
!! <pre>
!! Call tree graph :
!! lsm_simple->
!!  [->],
!!  [->],
!!  [->]
!!
!! High level routine descriptions / purpose
!!   lsm_simple         - loops over X,Y grid cells, calls a, b, c
!!
!! Driver inputs: p,th,pii,rho,qv,rain,snow,dt,dz
!!   p   = pressure                      - 3D - input  - Pa     - (nx,nz,ny)
!!   th  = potential temperature         - 3D - in/out - K      - (nx,nz,ny)
!!   pii = inverse exner function        - 3D - input  - []     - (nx,nz,ny)
!!   rho = air density                   - 3D - input  - kg/m^3 - (nx,nz,ny)
!!   qv  = specific humidity             - 3D - in/out - kg/kg  - (nx,nz,ny)
!!   rain= rainfall                      - 2D - input  - mm     - (nx,ny)
!!   snow= snowfall                      - 2D - input  - mm     - (nx,ny)
!!   wind= wind speed                    - 2D - input  - m/s    - (nx,ny)
!!   swdown = shortwave down at surface - 2D - input  - W/m^2   - (nx,ny)
!!   lwdown = longwave down at surface  - 2D - input  - W/m^2   - (nx,ny)
!!   dt = time step                      - 0D - input  - seconds    - scalar
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


! EDG Notes: vector sqrt?
! #  define VREC vsrec
! #  define VSQRT vssqrt
! #if ( RWORDSIZE == 4 )
! #  define VREC vsrec
! #  define VSQRT vssqrt
! #else
! #  define VREC vrec
! #  define VSQRT vsqrt
! #endif


!>----------------------------------------------------------
!! This module provides a wrapper to call various microphysics models
!! It sets up variables specific to the physics package to be used including
!! history variables not currently stored in the domain level data structure
!!
!! The main entry point to the code is mp(domain,options,dt)
!!
!! <pre>
!! Call tree graph :
!!  mp_init->[ external initialization routines]
!!  mp->[   external microphysics routines]
!!  mp_finish
!!
!! High level routine descriptions / purpose
!!   mp_init            - allocates module data and initializes physics package
!!   mp                 - sets up and calls main physics package
!!   mp_finish          - deallocates module memory, place to do the same for physics
!!
!! Inputs: domain, options, dt
!!      domain,options  = as defined in data_structures
!!      dt              = time step (seconds)
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!> ----------------------------------------------------------------------------
!!  Driver to call different advection schemes
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!! ----------------------------------------------------------------------------


!>----------------------------------------------------------
!!  Simple open water flux calculations
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>------------------------------------------------------------
!! YSU PBL scheme (from WRF)
!!
!!------------------------------------------------------------
!wrf:model_layer:physics
!
!
!
!


!>------------------------------------------------------------
!! Module to pre-compute and apply near-surface corrections to
!! the domain wind field. This includes topographic
!! exposure/sheltering via the Sx parameter (Winstral et al. 2017)
!! and surface roughness.
!!
!!  @author
!!  Dylan Reynolds (dylan.reynolds@slf.ch)
!!
!!------------------------------------------------------------


!>----------------------------------------------------------
!!  Simple PBL diffusion package for ICAR
!!
!!  Local-K diffusion type PBL as in Louis (1979) as documented in Hong and Pan (1996) = HP96
!!  Hong and Pan used this for their free atmosphere diffusion, but noted differences
!!  used in the "current operational model" notably the asymptotic length scale lambda
!!
!! <pre>
!! HP96 = Hong,S.-Y. and H.-L. Pan (1996) Monthly Weather Review v127 p2322
!!       Nonlocal Boundary Layer Vertical Diffusion in a Medium Range Forecast Model
!!
!! Implemented with K,shear,stability... on half levels
!!  rho on half levels for f=k*rho*dq/dz*dt
!!  rho on full levels for q=q+f/rho
!!   q,U,V on full levels
!! </pre>
!!
!!  @author
!!  Ethan Gutmann (gutmann@ucar.edu)
!!
!!----------------------------------------------------------


!>------------------------------------------------------------
!!  Noah Land Surface Model online driver code (from WRF)
!!
!!  @author
!!  various (see Chen and Dudhia 2001)
!!
!!------------------------------------------------------------