예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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