# Path: topoflow/components/infil_base.py
# class infil_component( BMI_base.BMI_component):
#     def set_constants(self):       
#     def initialize(self, cfg_file=None, mode="nondriver",
#                    SILENT=False):
#     def update(self, dt=-1.0):
#     def finalize(self):
#     def build_layer_z_vector(self):
#     def build_layered_var(self, var_list_for_layers):
#     def set_computed_input_vars(self):
#     def check_input_types(self):
#     def update_surface_influx(self):
#     def update_infil_rate(self):
#     def adjust_infil_rate(self):
#     def update_IN_integral(self):
#     def update_Rg(self):
#     def update_Rg_integral(self):
#     def update_I(self):
#     def update_q0(self):
#     def check_infiltration(self):
#     def check_low_rainrate(self):
#     def open_input_files(self):
#     def read_input_files(self):
#     def close_input_files(self):
#     def update_outfile_names(self):
#     def open_output_files(self):
#     def write_output_files(self, time_seconds=None):
#     def close_output_files(self):
#     def save_grids(self):
#     def save_pixel_values(self):
#     def save_profiles(self):
#     def save_cubes(self):
#         ALL_SCALARS = (nmax == 1)
#         SM     = self.SM        # (2/3/13, new framework)
#         CHECK_LOW_RAIN = not(self.RICHARDS)
#         SM      = self.SM       # (2/3/13, new framework)
#             OK = np.isfinite( self.IN )
#             OK = (nbad == 0)
#             G  = model_input.read_next(self.G_unit[k], self.G_type[k], rti)
# 
# Path: topoflow/utils/model_input.py
# def open_file(var_type, input_file):
# def read_next2(self, var_name, rti, dtype='Float32', factor=1.0):
# def read_next(file_unit, var_type, rti, \
#               dtype='Float32', factor=1.0):
# def read_scalar(file_unit, dtype='Float32'):
# def read_grid(file_unit, rti, dtype='Float32'):
# def close_file(file_unit):
#     END_OF_FILE = (file_pos == file_size)
# 
# Path: topoflow/utils/tf_utils.py
# def TF_Print(string):
#     """Print a string to the TopoFlow output log window."""
# 
#     #------------------------------------------
#     # For now, just print to terminal window.
#     # Later, this will be method in tf_gui.py.
#     #------------------------------------------
#     print string
# 
# def TF_String(number, FORMAT=None):
# 
#     return idl_func.string(number, format=FORMAT).strip()


import numpy as np
import os
from topoflow.components import infil_base
from topoflow.utils import model_input
from topoflow.utils.tf_utils import TF_Print, TF_String
    n_tries = np.int16(0)
    n_max = np.int16(20)
    while (n_tries < n_max) and not(CONVERGED):
    #------------------------------------------
    # We're using eqn. (6.27) in Smith's book
    # for t(f) and solving it for f(t_end).
    #------------------------------------------
        term1 = (t_end - self.tp) * dK * (np.float64(1) - gam) / (G * dq)
        term2 = np.log(np.float64(1) + (gam * dK) / (f - Ks)) / gam
        term3 = np.log((f - Ki) / (f - Ks))
        term4 = np.log(np.float64(1) + (gam * dK) / (fp - Ks)) / gam
        term5 = np.log((fp - Ki) / (fp - Ks))
        h = term1 - term2 + term3 + term4 - term5   #(eq 0)
        #---------------------------------------------
        termA = dK / (f - Ks)
        termB = np.float64(1) / ((f - Ks) + (gam * dK))
        termC = np.float64(1) / (f - Ki)
        dh_df = termA * (termB - termC)
        del_f = -(h / dh_df)
        f = f + del_f
        CONVERGED = (np.absolute(del_f) <= tol)
        n_tries = n_tries + 1
    
    #--------------------------------------
    #Did Newton-Raphson fail to converge ?
    #--------------------------------------
    if not(CONVERGED):    
        TF_Print('********************************************')
        TF_Print('  ERROR:  Failure to converge.')
        TF_Print('  Max number of iterations exceeded')

# Path: topoflow/components/infil_base.py
# class infil_component( BMI_base.BMI_component):
#     def set_constants(self):       
#     def initialize(self, cfg_file=None, mode="nondriver",
#                    SILENT=False):
#     def update(self, dt=-1.0):
#     def finalize(self):
#     def build_layer_z_vector(self):
#     def build_layered_var(self, var_list_for_layers):
#     def set_computed_input_vars(self):
#     def check_input_types(self):
#     def update_surface_influx(self):
#     def update_infil_rate(self):
#     def adjust_infil_rate(self):
#     def update_IN_integral(self):
#     def update_Rg(self):
#     def update_Rg_integral(self):
#     def update_I(self):
#     def update_q0(self):
#     def check_infiltration(self):
#     def check_low_rainrate(self):
#     def open_input_files(self):
#     def read_input_files(self):
#     def close_input_files(self):
#     def update_outfile_names(self):
#     def open_output_files(self):
#     def write_output_files(self, time_seconds=None):
#     def close_output_files(self):
#     def save_grids(self):
#     def save_pixel_values(self):
#     def save_profiles(self):
#     def save_cubes(self):
#         ALL_SCALARS = (nmax == 1)
#         SM     = self.SM        # (2/3/13, new framework)
#         CHECK_LOW_RAIN = not(self.RICHARDS)
#         SM      = self.SM       # (2/3/13, new framework)
#             OK = np.isfinite( self.IN )
#             OK = (nbad == 0)
#             G  = model_input.read_next(self.G_unit[k], self.G_type[k], rti)
# 
# Path: topoflow/utils/model_input.py
# def open_file(var_type, input_file):
# def read_next2(self, var_name, rti, dtype='Float32', factor=1.0):
# def read_next(file_unit, var_type, rti, \
#               dtype='Float32', factor=1.0):
# def read_scalar(file_unit, dtype='Float32'):
# def read_grid(file_unit, rti, dtype='Float32'):
# def close_file(file_unit):
#     END_OF_FILE = (file_pos == file_size)
# 
# Path: topoflow/utils/tf_utils.py
# def TF_Print(string):
#     """Print a string to the TopoFlow output log window."""
# 
#     #------------------------------------------
#     # For now, just print to terminal window.
#     # Later, this will be method in tf_gui.py.
#     #------------------------------------------
#     print string
# 
# def TF_String(number, FORMAT=None):
# 
#     return idl_func.string(number, format=FORMAT).strip()


# Path: topoflow/components/infil_smith_parlange.py
import numpy as np
import os
from topoflow.components import infil_base
from topoflow.utils import model_input
from topoflow.utils.tf_utils import TF_Print, TF_String

    n_tries = np.int16(0)
    n_max = np.int16(20)
    while (n_tries < n_max) and not(CONVERGED):
    #------------------------------------------
    # We're using eqn. (6.27) in Smith's book
    # for t(f) and solving it for f(t_end).
    #------------------------------------------
        term1 = (t_end - self.tp) * dK * (np.float64(1) - gam) / (G * dq)
        term2 = np.log(np.float64(1) + (gam * dK) / (f - Ks)) / gam
        term3 = np.log((f - Ki) / (f - Ks))
        term4 = np.log(np.float64(1) + (gam * dK) / (fp - Ks)) / gam
        term5 = np.log((fp - Ki) / (fp - Ks))
        h = term1 - term2 + term3 + term4 - term5   #(eq 0)
        #---------------------------------------------
        termA = dK / (f - Ks)
        termB = np.float64(1) / ((f - Ks) + (gam * dK))
        termC = np.float64(1) / (f - Ki)
        dh_df = termA * (termB - termC)
        del_f = -(h / dh_df)
        f = f + del_f
        CONVERGED = (np.absolute(del_f) <= tol)
        n_tries = n_tries + 1
    
    #--------------------------------------
    #Did Newton-Raphson fail to converge ?
    #--------------------------------------
    if not(CONVERGED):    
        TF_Print('********************************************')
        TF_Print('  ERROR:  Failure to converge.')
        TF_Print('  Max number of iterations exceeded')

        TF_Print('  while computing infiltration rate.')