def setupMesh(mode, x_start, x_extent, a_extent, z_layers, anomaly_coord, elem_sizes): # ----------------------------------------------------------------------------------------------------------------- # DESCRIPTION: # ----------- # This is a utility function which sets up the COMMEMI-1 mesh. # # # ARGUMENTS: # ---------- # mode :: TE or TM mode. # x_start :: horizontal start-point mesh. # x_extent :: horizontal extent of mesh. # a_extent :: vertical extent of air-layer. # z_layers :: list with coordinates of top-interfaces in Z-direction, incl. basement. # anomaly_coord :: dictionary with coordinate tuples of anomalies, counterclockwise. # elem_sizes :: mesh element sizes, large, normal, small. # # RETURNS: # -------- # <Nothing> A mesh file is written to the output folder. # # # AUTHOR: # ------- # Ralf Schaa, # The University of Queensland # # # HISTORY: # -------- # # ----------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # Imports. # ----------------------------------------------------------------------------------------------------------------- # System imports. import math # Escript modules. import esys.pycad as pycad # @UnresolvedImport import esys.finley as finley # @UnresolvedImport import esys.escript as escript # @UnresolvedImport import esys.weipa as weipa # @UnresolvedImport # <Note>: "@UnresolvedImport" ignores any warnings in Eclipse/PyDev (PyDev has trouble with external libraries). # Warn about magnetotelluric TM mode: if mode.lower() == 'tm': print("TM mode not yet supported") return None # ----------------------------------------------------------------------------------------------------------------- # Anomaly border. # ----------------------------------------------------------------------------------------------------------------- #<Note>: define the anomaly which must be 'cut out' in the main mesh. # Prepare list to store the anomaly borders: border_anomaly = [] # Cycle anomaly dictionary and define the border for each. for anomaly in anomaly_coord: # Extract the coordinates for current key: coord = anomaly_coord[anomaly] # Points defining the anomaly from left-top. points0 = [] for i in range(0, len(coord)): points0.append(pycad.Point(coord[i][0], coord[i][1], 0.0)) # Define the line segments connecting the points. lines0 = [] for i in range(0, len(points0) - 1): lines0.append(pycad.Line(points0[i], points0[i + 1])) # Connect the last segment from end to start: lines0.append(pycad.Line(points0[-1], points0[0])) # And define the border of the anomalous area. border_anomaly.append(pycad.CurveLoop(*lines0)) #___________________________________________________________________________ # -------------------------------------------------------------------------- # Get the borders for each layer (air & host). # -------------------------------------------------------------------------- # Borders around layers and the air/earth interface. borders, air_earth_interface = makeLayerCake(x_start, x_extent, z_layers) # -------------------------------------------------------------------------- # Specification of number of elements in domains. # -------------------------------------------------------------------------- #<Note>: specifying the number of mesh elements is somewhat heuristic # and is dependent on the mesh size and the anomaly sizes. coord = anomaly_coord["anomaly_1"] # First get the max-length of the anomaly to specify the number of elements. length = max( (abs(coord[2][0] - coord[0][0])), # X-length (abs(coord[2][1] - coord[0][1]))) # Y-length # Specify number of elements in air, anomaly and on air/earth interface: nr_elements_air = 1 * x_extent / elem_sizes["large"] nr_elements_anomaly = 2 * length / elem_sizes["small"] nr_elements_interface = 4 * x_extent / elem_sizes["small"] #___________________________________________________________________________ #--------------------------------------------------------------------------- # Domain definitions. #--------------------------------------------------------------------------- # Define the air & layer areas; note the 'holes' specifiers. domain_air = pycad.PlaneSurface(borders[0]) domain_host = pycad.PlaneSurface(borders[1], holes=[border_anomaly[0]]) domain_anomaly = pycad.PlaneSurface(border_anomaly[0]) # Specify the element sizes in the domains and along the interface. #<Note>: Sizes must be assigned in the order as they appear below: domain_air.setElementDistribution(nr_elements_air) domain_anomaly.setElementDistribution(nr_elements_anomaly) air_earth_interface.setElementDistribution(nr_elements_interface) # Ready to define the mesh-design.. design2D = pycad.gmsh.Design(dim=2, element_size=elem_sizes["normal"], keep_files=False) # ..and also specify the domains for tagging with property values later on: design2D.addItems(pycad.PropertySet("domain_air", domain_air), pycad.PropertySet("domain_host", domain_host), pycad.PropertySet("domain_anomaly", domain_anomaly)) # Now define the unstructured finley-mesh.. model2D = finley.MakeDomain(design2D) #___________________________________________________________________________ return model2D
def makeLayerCake(x_start, x_extent, z_layers): # --------------------------------------------------------------------------------------------- # DESCRIPTION: # ----------- # This is a utility function which sets up a 2D model with N layers. # # ARGUMENTS: # ---------- # x_start :: start coordinate of mesh. # x_extent :: horizontal extent of mesh. # z_layers :: list with interface coordinates. # # RETURNS: # -------- # borders :: borders of layers. # air_earth_interface :: line at the air/earth interface. # # AUTHOR: # ------- # Ralf Schaa, # University of Queensland # # # HISTORY: # -------- # # --------------------------------------------------------------------------------------------- import esys.pycad as pycad # @UnresolvedImport import esys.weipa as weipa # @UnresolvedImport import esys.finley as finley # @UnresolvedImport import esys.escript as escript # @UnresolvedImport # --------------------------------------------------------------------------------------------- # Point definitions. # --------------------------------------------------------------------------------------------- # Loop through all layers and define the vertices at all interfaces. scale = 1.0 points = [] for i in range(0, len(z_layers)): # Adjust scale at corners of air/earth interface: if z_layers[i] == 0: scale = 0.15 else: scale = 1.0 points.append(pycad.Point(x_start, z_layers[i], 0.0, local_scale=scale)) # Left-Corner. points.append( pycad.Point(x_start + x_extent, z_layers[i], 0.0, local_scale=scale)) # Right-Corner. # --------------------------------------------------------------------------------------------- # Line definitions. # --------------------------------------------------------------------------------------------- # Now connect the points to define the horizontal lines for all interfaces: hlines = [] for i in range(0, len(points), 2): if i <= len(points) - 1: hlines.append(pycad.Line(points[i], points[i + 1])) # Now connect the points to define the vertical lines for all interfaces: vlines_left = [] for i in range(0, len(points), 2): if i <= len(points) - 3: vlines_left.append(pycad.Line(points[i], points[i + 2])) vlines_right = [] for i in range(0, len(points), 2): if i <= len(points) - 4: vlines_right.append(pycad.Line(points[i + 1], points[i + 3])) # --------------------------------------------------------------------------------------------- # Curveloop and Area definitions. # --------------------------------------------------------------------------------------------- # Join line segments for each layer. borders = [] for i in range(0, len(z_layers) - 1): border = [hlines[i], vlines_right[i], -hlines[i + 1], -vlines_left[i]] borders.append(pycad.CurveLoop(border)) # --------------------------------------------------------------------------------------------- # Return values. # --------------------------------------------------------------------------------------------- # Explicitly specify the air-earth-boundary: air_earth_interface = hlines[1] return borders, air_earth_interface
def setup_coastal_mesh(Parameters, mesh_filename, extend_domain=True, max_length=1e5): """ Create a mesh consisting of 3 blocks, with a smaller cell size in the middle block The middle block is centered around the fresh-salt water interface, which is calculated using the Ghyben-Herzberg equation. """ #if Parameters.topo_gradient == 0: # extent_salt_water = 0 #else: # extent_salt_water = (Parameters.thickness / # (41.0 * Parameters.topo_gradient)) R = Parameters.recharge_flux B = Parameters.thickness K = Parameters.k * Parameters.rho_f_0 * 9.81 / Parameters.viscosity L = Parameters.L # calculate hydraulic head using analytical solution for confined aq # with uniform recharge + Dupuit assumptions xa = np.linspace(0, L, 101) h = R / (K * B) * (L * xa - 0.5 * xa**2) if h[-1] < (B / 40): print 'warning, calculated extent salt water toe exceeds model domain' print 'calculated h at model bnd = %0.2f m' % h[-1] print 'Ghyben-Herzberg depth of salt water interface = %0.2f m' % (h[-1] * 40) print 'thickness = %0.2f m' % Parameters.thickness if extend_domain is False: extent_salt_water = Parameters.L - Parameters.buffer_distance_land - 1.0 #print 'choosing maximum possible extent of %0.2f m for ' \ # 'designing model grid' % extent_salt_water print 'entire top right triangle at landward side of model domain has fine discretization' fine_mesh = True adjust_length = False else: adjust_length = True else: fine_mesh = False # salt water toe touches bottom of model domain a = 0.5 * R / (K * B) b = -(R * L) / (K * B) c = B / 40.0 D = np.sqrt(b**2 - 4 * a * c) extent_salt_water = (-b - D) / (2 * a) hs1 = R / (K * B) * (L * extent_salt_water - 0.5 * extent_salt_water**2) print 'calculated extent salt water toe = %0.2f m' % extent_salt_water try: assert np.abs(hs1 - B / 40.0) < 1e-3 except AssertionError: msg = 'error, something wrong with calculated extent ' \ 'salt water toe' raise ValueError(msg) if adjust_length is True: L_land = extent_salt_water + Parameters.buffer_distance_land * 2 if L_land > max_length: L_land = Parameters.L fine_mesh = True else: print 'extending model domain size to %0.3e' % L_land else: L_land = Parameters.L ############################### # use gmsh to construct domain ############################## xs = np.array([-Parameters.L_sea, extent_salt_water - Parameters.buffer_distance_sea, -Parameters.buffer_distance_sea, -Parameters.L_sea, extent_salt_water, 0, extent_salt_water + Parameters.buffer_distance_land, Parameters.buffer_distance_land, L_land, L_land, -Parameters.L_sea]) zs = xs * Parameters.topo_gradient zs[0:2] = zs[0:2] - Parameters.thickness zs[4] = zs[4] - Parameters.thickness zs[6] = zs[6] - Parameters.thickness zs[8] = zs[8] - Parameters.thickness zs[10] = 0.0 #points = create_points(xs,zs) points = [pc.Point(x, z) for x, z in zip(xs, zs)] line1 = pc.Line(points[0], points[1]) line2 = pc.Line(points[1], points[2]) line3 = pc.Line(points[2], points[3]) line4 = pc.Line(points[3], points[0]) line5 = pc.Line(points[1], points[4]) line6 = pc.Line(points[4], points[5]) line7 = pc.Line(points[5], points[2]) line8 = pc.Line(points[4], points[6]) line9 = pc.Line(points[6], points[7]) line10 = pc.Line(points[7], points[5]) line11 = pc.Line(points[6], points[8]) line12 = pc.Line(points[8], points[9]) line13 = pc.Line(points[9], points[7]) # new lines for sea surface # seabottom, x=-buffer to x=0 # -line3 (pt 3 to 2) # - line7 (pt 2 to pt 5) # coastline to x=0, z=0 #line14 = pc.Line(points[5], points[10]) # x=0, z=0 to x=0, z=sea bottom #line15 = pc.Line(points[10], points[3]) # coastline to x=0, sea bottom # finer grid cell size around fresh-salt water interface curve_a = pc.CurveLoop(line1, line2, line3, line4) curve_b = pc.CurveLoop(line5, line6, line7, -line2) curve_c = pc.CurveLoop(line8, line9, line10, -line6) curve_d = pc.CurveLoop(line11, line12, line13, -line9) #curve_seawater = pc.CurveLoop(-line3, -line7, line14, line15) surface_a = pc.PlaneSurface(curve_a) surface_b = pc.PlaneSurface(curve_b) surface_c = pc.PlaneSurface(curve_c) surface_d = pc.PlaneSurface(curve_d) #surface_seawater = pc.PlaneSurface(curve_seawater) surface_a.setLocalScale(factor=Parameters.grid_refinement_factor_sea) surface_b.setLocalScale(factor=Parameters.grid_refinement_factor) surface_c.setLocalScale(factor=Parameters.grid_refinement_factor) #surface_seawater.setLocalScale(factor=Parameters.grid_refinement_factor_seawater) if fine_mesh is True: print 'assigning refined grid from landward side of model domain' surface_d.setLocalScale(factor=Parameters.grid_refinement_factor) d = gmsh.Design(dim=2, element_size=Parameters.cellsize) ps1 = pc.PropertySet("sea_surface1", line3) ps2 = pc.PropertySet("sea_surface2", line7) ps3 = pc.PropertySet("land_surface1", line10) ps4 = pc.PropertySet("land_surface2", line13) #ps5 = pc.PropertySet("sea_surface", line14) #d.addItems(pc.PropertySet('sea', surface_a), # pc.PropertySet('salt_wedge_sea_side', surface_b), # pc.PropertySet('salt_wedge_land_side', surface_c), # pc.PropertySet('land', surface_d), # pc.PropertySet('seawater', surface_seawater), # ps1, ps2, ps3, ps4, ps5) d.addItems(pc.PropertySet('sea', surface_a), pc.PropertySet('salt_wedge_sea_side', surface_b), pc.PropertySet('salt_wedge_land_side', surface_c), pc.PropertySet('land', surface_d), ps1, ps2, ps3, ps4) d.setMeshFileName(mesh_filename) mesh = fl.MakeDomain(d, optimizeLabeling=True) # calculate surface xy = mesh.getX() z_surface = xy[0] * Parameters.topo_gradient surface = es.whereZero(xy[1] - z_surface) # sea surface sea_surface = es.whereZero(xy[1]) * es.whereNegative(xy[0]) seawater = es.whereNegative(xy[0]) * es.whereNegative(z_surface - xy[1]) print bla return mesh, surface, sea_surface, seawater, z_surface
def setupMesh(mode, coord, elem_sizes): #--------------------------------------------------------------------------- # DESCRIPTION: # ----------- # This is a utility function which setups the COMMEMI-4 mesh. # # # ARGUMENTS: # ---------- # mode :: TE or TM mode. # coord :: dictionary with coordinate tuples. # elem_sizes :: mesh element sizes, large, normal, small. # # RETURNS: # -------- # <Nothing> A mesh file is written to the output folder. # # # AUTHOR: # ------- # Ralf Schaa, # University of Queensland # #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- # Imports. #--------------------------------------------------------------------------- import esys.pycad as pycad # @UnresolvedImport import esys.finley as finley # @UnresolvedImport import esys.escript as escript # @UnresolvedImport import esys.weipa as weipa # @UnresolvedImport # <Note>: "@UnresolvedImport" ignores any warnings in Eclipse/PyDev (PyDev has trouble with external libraries). model = "COMMEMI-4" print("Preparing the mesh " + model + " ...") print("") # Warn about magnetotelluric TM mode: if mode.lower() == 'tm': print("TM mode not yet supported") return # Path to write the mesh: outpath = "../out/commemi4" # -------------------------------------------------------------------------- # Initialisations. # -------------------------------------------------------------------------- # Get coordinates from dictionary as list of tuples a0 = coord["air"] l1 = coord["lyr1"] s1 = coord["slab"] b1 = coord["basin"] l2 = coord["lyr2"] l3 = coord["lyr3"] # Mesh length from top-boundary. x_extent = abs(a0[3][0]-a0[0][0]) # -------------------------------------------------------------------------- # Point definitions. # -------------------------------------------------------------------------- #<Note>: define all points spanning the mesh, anomalies and layers; # note also shared domain points must be defined only once. # Mesh top boundary. air = [] air.append( pycad.Point( *a0[0] ) ) # 0: left , top (@ boundary) air.append( pycad.Point( *a0[3] ) ) # 3: right , top (@ boundary) # First-layer. ly1 = [] ly1.append( pycad.Point( *l1[0] ) ) # 0: left , top (@ air/earth interface) ly1.append( pycad.Point( *l1[1] ) ) # 1: left , bottom (@ boundary) ly1.append( pycad.Point( *l1[2] ) ) # 2: right , bottom (@ slab/basin) ly1.append( pycad.Point( *l1[3] ) ) # 3: right , bottom (@ boundary) ly1.append( pycad.Point( *l1[4] ) ) # 4: right , top (@ air/earth interface) # Slab. sl1 = [] sl1.append( ly1[1] ) # 0: left , top (@ boundary) sl1.append( pycad.Point( *s1[1] ) ) # 1: left , bottom (@ boundary) sl1.append( pycad.Point( *s1[2] ) ) # 2: right , bottom (@ slab/basin) sl1.append( ly1[2] ) # 3: right , top (@ slab/basin) # Basin. bs1 = [] bs1.append( ly1[2] ) # 0: left , top (@ slab/basin) bs1.append( sl1[2] ) # 1: left , centre (@ slab/basin) bs1.append( pycad.Point( *b1[2] ) ) # 2: left , bottom (@ lyr1/basin) bs1.append( pycad.Point( *b1[3] ) ) # 3: centre, bottom (@ lyr1/basin) bs1.append( pycad.Point( *b1[4] ) ) # 4: edge , bottom (@ lyr1/basin) bs1.append( pycad.Point( *b1[5] ) ) # 5: right , bottom (@ boundary) bs1.append( ly1[3] ) # 6: right , top # Second-Layer. ly2 = [] ly2.append( sl1[1] ) # 0: left , top (@ lyr2/slab) ly2.append( pycad.Point( *l2[1] ) ) # 1: left , bottom (@ boundary) ly2.append( pycad.Point( *l2[2] ) ) # 2: right , bottom (@ boundary) ly2.append( bs1[5] ) # 3: right , top (@ basin/boundary) ly2.append( bs1[4] ) # 4: edge , top (@ lyr2/basin) ly2.append( bs1[3] ) # 5: centre, top (@ lyr2/basin) ly2.append( bs1[2] ) # 6: left , top (@ lyr2/basin) ly2.append( sl1[2] ) # 7: left , centre (@ slab/basin) # Basement layer. ly3 = [] ly3.append( ly2[1] ) # 0: left , top (@ boundary) ly3.append( pycad.Point( *l3[1] ) ) # 1: left , bottom (@ boundary) ly3.append( pycad.Point( *l3[2] ) ) # 2: right , bottom (@ boundary) ly3.append( ly2[2] ) # 3: right , top (@ boundary) #___________________________________________________________________________ # -------------------------------------------------------------------------- # Line definitions. # -------------------------------------------------------------------------- #<Note>: connects the points to define lines counterclockwise; # shared lines are re-used to ensure that all domains # are recognised as parts of the same mesh. # Air. ln0 = [] ln0.append( pycad.Line(air[0], ly1[0]) ) # 0 left-top to left-bottom. ln0.append( pycad.Line(ly1[0], ly1[4]) ) # 1 left-bottom to right-bottom (air-earth interface). ln0.append( pycad.Line(ly1[4], air[1]) ) # 2 right-bottom to right-top. ln0.append( pycad.Line(air[1], air[0]) ) # 3 right-top to left-top. # Top Layer. ln1 = [] ln1.append( pycad.Line(ly1[0], ly1[1]) ) # 0 left-top to left-bottom. ln1.append( pycad.Line(ly1[1], ly1[2]) ) # 1 left-bottom to start-slab/basin. ln1.append( pycad.Line(ly1[2], ly1[3]) ) # 2 start-slab/basin to basin-boundary ln1.append( pycad.Line(ly1[3], ly1[4]) ) # 3 basin-boundary to right-top. ln1.append( -ln0[1] ) # 4 right-top to left-top. # Slab. ln2 = [] ln2.append( pycad.Line(sl1[0], sl1[1]) ) # 0 left-top to left-bottom. ln2.append( pycad.Line(sl1[1], sl1[2]) ) # 1 left-bottom to right-bottom. ln2.append( pycad.Line(sl1[2], sl1[3]) ) # 2 right-bottom to right-top. ln2.append( -ln1[1] ) # 3 right-top to left-top # Basin. ln3 = [] ln3.append( -ln2[2] ) # 0 left-top to left-centre. ln3.append( pycad.Line(bs1[1], bs1[2]) ) # 1 left-centre to left-bottom. ln3.append( pycad.Line(bs1[2], bs1[3]) ) # 2 left-bottom to mid-bottom. ln3.append( pycad.Line(bs1[3], bs1[4]) ) # 3 mid-bottom to right-mid-top. ln3.append( pycad.Line(bs1[4], bs1[5]) ) # 4 right-mid-top to right-bottom. ln3.append( pycad.Line(bs1[5], bs1[6]) ) # 5 right-bottom to right-top. ln3.append( -ln1[2] ) # 6 right-top to right-slab/basin. # Layer below. ln4 = [] ln4.append( pycad.Line(ly2[0], ly2[1]) ) # 0 left-top to left-bottom. ln4.append( pycad.Line(ly2[1], ly2[2]) ) # 1 left-bottom to right-bottom. ln4.append( pycad.Line(ly2[2], ly2[3]) ) # 2 right-bottom to right-top. ln4.append( -ln3[4] ) # 3 right-top to right-mid-top. ln4.append( -ln3[3] ) # 4 right-mid-top to mid-bottom. ln4.append( -ln3[2] ) # 5 mid-bottom to left-bottom. ln4.append( -ln3[1] ) # 6 left-bottom to left-centre. ln4.append( -ln2[1] ) # 7 left-centre to left-top. # Basement layer. ln5 = [] ln5.append( pycad.Line(ly3[0], ly3[1]) ) # 0 left-top to left-bottom. ln5.append( pycad.Line(ly3[1], ly3[2]) ) # 1 left-bottom to right-bottom. ln5.append( pycad.Line(ly3[2], ly3[3]) ) # 2 right-bottom to right-top. ln5.append( -ln4[1] ) # 3 right-top to left-top. #___________________________________________________________________________ # -------------------------------------------------------------------------- # Domain definitions. # -------------------------------------------------------------------------- # First define all borders. borders = [] borders.append( pycad.CurveLoop(*ln0) ) borders.append( pycad.CurveLoop(*ln1) ) borders.append( pycad.CurveLoop(*ln2) ) borders.append( pycad.CurveLoop(*ln3) ) borders.append( pycad.CurveLoop(*ln4) ) borders.append( pycad.CurveLoop(*ln5) ) # And next the domains. domains = [] for i in range( len(borders) ): domains.append( pycad.PlaneSurface(borders[i]) ) #___________________________________________________________________________ # -------------------------------------------------------------------------- # Set element sizes in domains. # -------------------------------------------------------------------------- # Horizontal extents of segments along slab and basin: x_extents = [] x_extents.append( l1[2][0] - l1[0][0] ) # 0 x_extents.append( l1[3][0] - l1[2][0] ) # 1 # Number of elements in the air-domain, first-layer as well as slab- and basin-domain. domains[0].setElementDistribution( x_extent / elem_sizes["large"] ) domains[1].setElementDistribution( x_extent / (elem_sizes["small"]) ) domains[2].setElementDistribution( 0.4*x_extent / (elem_sizes["small"]) ) domains[3].setElementDistribution( 0.5*x_extent / (elem_sizes["small"]) ) #<Note> slab and basin multiplied by approximate ratio of their x_extent. #___________________________________________________________________________ #--------------------------------------------------------------------------- # Now define the gmsh 'design' object. #--------------------------------------------------------------------------- design2D = pycad.gmsh.Design(dim=2, element_size=elem_sizes['large'], keep_files=False) # Also specify the domains for tagging with property values later on: design2D.addItems( pycad.PropertySet( "air" , domains[0]) , pycad.PropertySet( "lyr1" , domains[1]) , pycad.PropertySet( "slab" , domains[2]) , pycad.PropertySet( "basin" , domains[3]) , pycad.PropertySet( "lyr2" , domains[4]) , pycad.PropertySet( "lyr3" , domains[5]) ) # Now define the unstructured finley-mesh.. model2D = finley.MakeDomain(design2D) #___________________________________________________________________________ return model2D
def setup_coastal_mesh_glover1959(Parameters, mesh_filename): """ Create a mesh consisting of 3 blocks, with a smaller cell size in the middle block The middle block is centered around the fresh-salt water interface, which is calculated using an anlytical solution by Glover (1959) Journal of Geophys. Res. """ # if Parameters.topo_gradient == 0: # extent_salt_water = 0 # else: # extent_salt_water = (Parameters.thickness / # (41.0 * Parameters.topo_gradient)) if Parameters.ghyben_herzberg is True: R = Parameters.recharge_flux B = Parameters.thickness K = Parameters.k * Parameters.rho_f_0 * 9.81 / Parameters.viscosity L = Parameters.L # calculate hydraulic head using analytical solution for confined aq # with uniform recharge + Dupuit assumptions xa = np.linspace(0, L, 1001) h = R / (K * B) * (L * xa - 0.5 * xa ** 2) # calculate depth salt water interface from grompy_lib import depth_sw_interface_Glover1959 rho_f = Parameters.rho_f_0 * Parameters.freshwater_concentration * Parameters.gamma + Parameters.rho_f_0 rho_s = Parameters.rho_f_0 * Parameters.seawater_concentration * Parameters.gamma + Parameters.rho_f_0 Qmax = Parameters.recharge_flux * L y_sw, int_sw_top, int_sw_bottom = depth_sw_interface_Glover1959(xa, Parameters.k, Parameters.viscosity, Parameters.topo_gradient, Parameters.thickness, rho_f, rho_s, Parameters.gamma, Qmax=Qmax) if Parameters.recharge_flux == 0.0: # assume with no rehcarge that the hydraulic head follows the land surface h = Parameters.topo_gradient * xa #y_sw, int_sw_top, int_sw_bottom if int_sw_bottom > L: print 'warning, calculated extent salt water toe exceeds model domain' print 'calculated toe of fresh_salt water bnd = %0.2f m' % int_sw_bottom extent_salt_water = Parameters.L - Parameters.buffer_distance_land - 1.0 print 'choosing maximum possible extent of %0.2f m for ' \ 'designing model grid' % extent_salt_water fine_mesh = False else: fine_mesh = False extent_salt_water = int_sw_bottom print 'calculated extent salt water toe = %0.2f m' % int_sw_bottom else: print 'assuming a vertical fresh-salt water interface' extent_salt_water = 0.0 fine_mesh = False L_land = Parameters.L ############################### # use gmsh to construct domain ############################## xs = np.array([-Parameters.L_sea, extent_salt_water - Parameters.buffer_distance_sea, -Parameters.buffer_distance_sea, -Parameters.L_sea, extent_salt_water, 0, extent_salt_water + Parameters.buffer_distance_land, Parameters.buffer_distance_land, L_land, L_land]) zs = xs * Parameters.topo_gradient zs[0:2] = zs[0:2] - Parameters.thickness zs[4] = zs[4] - Parameters.thickness zs[6] = zs[6] - Parameters.thickness zs[8] = zs[8] - Parameters.thickness # points = create_points(xs,zs) points = [pc.Point(x, z) for x, z in zip(xs, zs)] line1 = pc.Line(points[0], points[1]) line2 = pc.Line(points[1], points[2]) line3 = pc.Line(points[2], points[3]) line4 = pc.Line(points[3], points[0]) line5 = pc.Line(points[1], points[4]) line6 = pc.Line(points[4], points[5]) line7 = pc.Line(points[5], points[2]) line8 = pc.Line(points[4], points[6]) line9 = pc.Line(points[6], points[7]) line10 = pc.Line(points[7], points[5]) line11 = pc.Line(points[6], points[8]) line12 = pc.Line(points[8], points[9]) line13 = pc.Line(points[9], points[7]) # finer grid cell size around fresh-salt water interface curve_a = pc.CurveLoop(line1, line2, line3, line4) curve_b = pc.CurveLoop(line5, line6, line7, -line2) curve_c = pc.CurveLoop(line8, line9, line10, -line6) curve_d = pc.CurveLoop(line11, line12, line13, -line9) surface_a = pc.PlaneSurface(curve_a) surface_b = pc.PlaneSurface(curve_b) surface_c = pc.PlaneSurface(curve_c) surface_d = pc.PlaneSurface(curve_d) surface_a.setLocalScale(factor=Parameters.grid_refinement_factor_sea) surface_b.setLocalScale(factor=Parameters.grid_refinement_factor) surface_c.setLocalScale(factor=Parameters.grid_refinement_factor) if fine_mesh is True: print 'assigning refined grid to entire landward side of model domain' surface_d.setLocalScale(factor=Parameters.grid_refinement_factor) d = gmsh.Design(dim=2, element_size=Parameters.cellsize) ps1 = pc.PropertySet("sea_surface1", line3) ps2 = pc.PropertySet("sea_surface2", line7) ps3 = pc.PropertySet("land_surface1", line10) ps4 = pc.PropertySet("land_surface2", line13) d.addItems(pc.PropertySet('sea', surface_a), pc.PropertySet('salt_wedge_sea_side', surface_b), pc.PropertySet('salt_wedge_land_side', surface_c), pc.PropertySet('land', surface_d), ps1, ps2, ps3, ps4) d.setMeshFileName(mesh_filename) print '=' * 30 mesh = fl.MakeDomain(d, optimizeLabeling=True) # calculate surface xy = mesh.getX() z_surface = xy[0] * Parameters.topo_gradient surface = es.whereZero(xy[1] - z_surface) # sea surface # sea_surface = surface * es.whereNegative(xy[0]) sea_surface = None seawater = None return mesh, surface, sea_surface, seawater, z_surface