anuga.Internal_boundary_operator

class anuga.Internal_boundary_operator(domain, internal_boundary_function, width=1.0, height=1.0, end_points=None, exchange_lines=None, enquiry_points=None, invert_elevation=None, apron=0.0, enquiry_gap=0.0, use_velocity_head=False, zero_outflow_momentum=False, force_constant_inlet_elevations=True, smoothing_timescale=0.0, compute_discharge_implicitly=True, description=None, label=None, structure_type='internal_boundary', logging=False, verbose=True)[source]

Bases: Structure_operator

Internal boundary operator driven by a user-supplied discharge function.

The internal_boundary_function must accept 2 input arguments (hw, tw) and return Q:

  • hw is the stage (or energy) at enquiry_point[0]

  • tw is the stage (or energy) at enquiry_point[1]

  • if flow is from hw to tw, Q should be positive, otherwise negative

def internal_boundary_function(hw, tw):
    # Compute Q here from headwater hw and tailwater tw
    return Q

smoothing_timescale > 0 can be used to make Q vary more slowly.

__init__(domain, internal_boundary_function, width=1.0, height=1.0, end_points=None, exchange_lines=None, enquiry_points=None, invert_elevation=None, apron=0.0, enquiry_gap=0.0, use_velocity_head=False, zero_outflow_momentum=False, force_constant_inlet_elevations=True, smoothing_timescale=0.0, compute_discharge_implicitly=True, description=None, label=None, structure_type='internal_boundary', logging=False, verbose=True)[source]

exchange_lines define the input lines for each inlet.

If end_points = None, then the culvert_vector is calculated in the directions from the centre of echange_line[0] to centre of exchange_line[1}

If end_points != None, then culvert_vector is unit vector in direction end_point[1] - end_point[0]

Methods

__init__(domain, internal_boundary_function)

exchange_lines define the input lines for each inlet.

activate_logging()

discharge_routine()

Both implicit and explicit methods available The former seems more stable and more accurate (in at least some cases).

discharge_routine_explicit()

Procedure to determine the inflow and outflow inlets.

discharge_routine_implicit()

Estimate discharge semi-implicitly.

get_culvert_apron()

get_culvert_barrels()

get_culvert_blockage()

get_culvert_diameter()

get_culvert_height()

get_culvert_length()

get_culvert_slope()

get_culvert_width()

get_culvert_z1()

get_culvert_z2()

get_enquiry_depths()

get_enquiry_elevations()

get_enquiry_invert_elevations()

get_enquiry_positions()

get_enquiry_specific_energys()

get_enquiry_speeds()

get_enquiry_stages()

get_enquiry_total_energys()

get_enquiry_velocity_heads()

get_enquiry_velocitys()

get_enquiry_water_depths()

get_enquiry_xmoms()

get_enquiry_xvelocitys()

get_enquiry_ymoms()

get_enquiry_yvelocitys()

get_inlets()

get_master_proc()

get_time()

get_timestep()

log_timestepping_statistics()

parallel_safe()

By default an operator is not parallel safe

print_statistics()

print_timestepping_statistics()

set_culvert_barrels(barrels)

set_culvert_blockage(blockage)

set_culvert_height(height)

set_culvert_width(width)

set_culvert_z1(z1)

set_culvert_z2(z2)

set_label([label])

set_logging([flag])

statistics()

timestepping_statistics()

Attributes

counter

discharge_routine()[source]

Both implicit and explicit methods available The former seems more stable and more accurate (in at least some cases). The latter will have less communication in parallel, and for some simple internal_boundary_functions there is no benefit to the implicit approach

discharge_routine_explicit()[source]

Procedure to determine the inflow and outflow inlets. Then use self.internal_boundary_function to do the actual calculation

discharge_routine_implicit()[source]

Estimate discharge semi-implicitly.

Discharge = (1-theta)*Q(H0, T0) + theta*Q(H0 + delta_H, T0 + delta_T) where H0 = headwater stage, T0 = tailwater stage, delta_H / delta_T are the changes in headwater / tailwater stage over a timestep, Q is the discharge function, and theta is a constant in [0, 1] setting the degree of implicitness (currently hard-coded).

This effectively assumes:

  1. Q is a function of stage, not energy (so mass change relates directly to delta_H, delta_T). This could be generalised to the energy case.

  2. The stage is computed on the exchange line (or the change in stage at the enquiry point is effectively the same as on the exchange line).