Ejemplo n.º 1
0
    def check_dist(self, dist=1.0):
        """
    remove points in contour that are not a linear distance of at least
    <dist> from previous point.
    """
        lin_dist = lambda p1, p2: sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)

        xycoords = self.longest_cont

        mask = ones(len(xycoords), dtype=bool)

        i = 0
        while (i < len(xycoords) - 1):
            p1 = xycoords[i]
            j = i + 1
            while(j < len(xycoords) and \
                  lin_dist(p1, xycoords[j]) < dist):
                mask[j] = 0
                j += 1
            i = j

        # fix end of array
        i = -1
        while(len(xycoords) + i >= 0 and (not mask[i] or \
              lin_dist(xycoords[0],xycoords[i]) < dist)):
            mask[i] = 0
            i -= 1

        # print results
        s    = "::: removed %s points closer than %s m to one another :::"% \
                (str(len(mask) - sum(mask)), dist)
        print_text(s, self.color)

        self.longest_cont = xycoords[mask]
Ejemplo n.º 2
0
    def extend_boundary(self, r):
        """
    Extends a 2d contour out from points in self.xycoords by a distance
    <r> (radius) in all directions.
    """
        s = "::: extending boundary by %i meters :::" % r
        print_text(s, self.color)

        xycoords = self.xycoords

        polygons = []
        for i, v in enumerate(xycoords):
            polygons.append(shapelyPoint(v[0], v[1]).buffer(r))

        # union of our original polygon and convex hull
        p1 = cascaded_union(polygons)
        p2 = Polygon(zip(xycoords[:, 0], xycoords[:, 1]))
        p3 = cascaded_union([p1, p2])

        xycoords_buf = array(zip(p3.exterior.xy[:][0], p3.exterior.xy[:][1]))
        self.plot_coords["xycoords_buf"] = xycoords_buf
        self.xycoords = xycoords_buf
        s = "::: extended contour created of length %i :::" % len(
            self.xycoords)
        print_text(s, self.color)
Ejemplo n.º 3
0
    def intersection(self, new_contour):
        """
    Take the geometric intersection of current coordinates with <new_contour>.
    Used primarily to replace the edge with something from a different
    (better) data set.
    """
        contour = self.longest_cont

        p1 = Polygon(zip(contour[:, 0], contour[:, 1]))
        p2 = Polygon(zip(new_contour[:, 0], new_contour[:, 1]))

        intersection = p1.intersection(p2)

        # check if multi-polygon is created. If so, take polygon
        # with greatest area
        import collections
        if isinstance(intersection, collections.Iterable):
            p3 = max(intersection, key=lambda x: x.area)
        else:
            p3 = intersection

        contour_intersect = zip(p3.exterior.xy[:][0], p3.exterior.xy[:][1])
        self.longest_cont = array(contour_intersect)[1:]
        s = "::: intersection contour created, length %s nodes :::"
        print_text(s % shape(self.longest_cont)[0], self.color)
Ejemplo n.º 4
0
    def extend_edge(self, r):
        """
    Extends a 2d contour out from points labeled in self.edge by a distance
    <r> (radius) in all directions.
    NOTE: this only works for greenland.
    """
        s = "::: extending edge by %i meters :::" % r
        print_text(s, self.color)

        xycoords = self.xycoords
        edge = self.edge

        polygons = []
        for i, v in enumerate(xycoords):
            if edge[i]:
                polygons.append(shapelyPoint(v[0], v[1]).buffer(r))

        # union of our original polygon and convex hull
        p1 = cascaded_union(polygons)
        p2 = Polygon(zip(xycoords[:, 0], xycoords[:, 1]))
        p3 = cascaded_union([p1, p2])

        xycoords_buf = array(zip(p3.exterior.xy[:][0], p3.exterior.xy[:][1]))
        self.plot_coords["xycoords_buf"] = xycoords_buf
        self.xycoords = xycoords_buf
Ejemplo n.º 5
0
    def finish(self, field):
        """
    figure out background field and close the .geo file.
    """
        f = self.f
        fd = str(field)
        flist = self.fieldList

        # get a string of the fields list :
        l = ""
        for i, j in enumerate(flist):
            l += str(j)
            if i != len(flist) - 1:
                l += ', '

        # make the background mesh size the minimum of the fields :
        if len(flist) > 0:
            f.write("Field[" + fd + "]            = Min;\n")
            f.write("Field[" + fd + "].FieldsList = {" + l + "};\n")
            f.write("Background Field    = " + fd + ";\n\n")
        else:
            f.write("Background Field = " + fd + ";\n\n")

        s = 'finished, closing \"' + self.direc + self.fn + '.geo\".'
        print_text(s, self.color)
        f.close()
Ejemplo n.º 6
0
    def intersection(self, other):
        """
    Take the geometric intersection of current coordinates with <other>.
    Used primarily to replace the edge with something from a different
    (better) data set.

    NOTE: it's probably better to extend the boundary before taking the
    intersection.
    """
        s = "::: taking intersection with new contour of length %i :::"
        print_text(s % len(other), self.color)

        xycoords = self.xycoords

        p1 = Polygon(zip(xycoords[:, 0], xycoords[:, 1]))
        p2 = Polygon(zip(other[:, 0], other[:, 1]))

        intersection = p1.intersection(p2)

        # check if multi-polygon is created. If so, take polygon with greatest
        # area
        import collections
        if isinstance(intersection, collections.Iterable):
            p3 = max(intersection, key=lambda x: x.area)
        else:
            p3 = intersection

        xycoords_intersect = array(zip(p3.exterior.xy[:][0], \
                                       p3.exterior.xy[:][1]))

        self.plot_coords["xycoords_intersect"] = xycoords_intersect
        self.xycoords = xycoords_intersect

        s = "::: intersection created with length %i :::"
        print_text(s % len(self.xycoords), self.color)
Ejemplo n.º 7
0
 def close_file(self):
     """
 close the .geo file down for further editing.
 """
     s = '::: finished, closing \"' + self.direc + self.fn + '.geo\" :::'
     print_text(s, self.color)
     self.f.close()
Ejemplo n.º 8
0
    def __init__(self, di, basin=None):
        """
    """
        self.color = 'grey_46'
        self.di = di

        s = "::: INITIALIZING BASIN GENERATOR :::"
        print_text(s, self.color)

        self.plot_coords = {}

        # Get path of this file, which should be in the src directory
        filename = inspect.getframeinfo(inspect.currentframe()).filename
        home = os.path.dirname(os.path.abspath(filename)) + "/.."

        if di.cont == "greenland":
            path = home + "/data/greenland/basins/"
            self.datafile = path + "GrnDrainageSystems_Ekholm.txt"
            self.imagefile = path + "Grn_Drainage_Systems.png"
        elif di.cont == "antarctica":
            path = home + "/data/antarctica/basins/"
            self.datafile = path + "Ant_Full_DrainageSystem_Polygons.txt"
            self.imagefile = path + "Ant_ICESatDSMaps_Fig_1.jpg"
        else:
            s = "Can not find data corresponding to location %s" % di.cont
            print_text(s, 'red', 1)

        if basin == None:
            self.show_and_get_basin()
        else:
            self.basin = basin
        self.retrive_basin_latlong()
        self.convert_to_projection()
Ejemplo n.º 9
0
 def show_and_get_basin(self):
     """
 """
     print_text(self.imagefile, self.color)
     image = Image.open(self.imagefile)
     image.show()
     self.basin = raw_input("Input the numerical code of the basin.\n")
Ejemplo n.º 10
0
 def restart(self):
     """
 clear all contents from the .geo file.
 """
     self.f.close
     self.f = open(self.direc + self.fn + '.geo', 'w')
     s = 'Reopened \"' + self.direc + self.fn + '.geo\".'
     print_text(s, self.color)
Ejemplo n.º 11
0
 def remove_skip_points(self, skip_pts):
     """
 remove every other <skip_pts> node from the contour.
 """
     # remove skip points and last point to avoid overlap :
     longest_cont = self.longest_cont
     self.longest_cont = longest_cont[::skip_pts, :][:-1, :]
     s = "::: contour points skipped, new length %s nodes :::"
     print_text(s % shape(self.longest_cont)[0], self.color)
Ejemplo n.º 12
0
 def create_2D_mesh(self, outfile):
     """
 create the 2D mesh to file <outfile>.msh.
 """
     #FIXME: this fails every time, the call in the terminal does work however.
     cmd = 'gmsh ' + '-2 ' + self.direc + self.fn + '.geo'  # -2 -o ' \
     #+ self.direc + outfile + '.msh'
     s = "\nExecuting :\n\n\t", cmd, "\n\n"
     print_text(s, self.color)
     subprocess.call(cmd.split())
Ejemplo n.º 13
0
 def plot_contour(self):
     """
 Plot the contour created with the "create_contour" method.
 """
     s = "::: plotting contour :::"
     print_text(s, self.color)
     ax = self.ax
     lc = self.longest_cont
     ax.plot(lc[:, 0], lc[:, 1], 'r-', lw=3.0)
     ax.set_title("contour")
     show()
Ejemplo n.º 14
0
    def convert_msh_to_xml(self, mshfile, xmlfile):
        """
    convert <mshfile> .msh file to .xml file <xmlfile> via dolfin-convert.
    """
        msh = self.direc + mshfile + '.msh'
        xml = self.direc + xmlfile + '.xml'

        cmd = 'dolfin-convert ' + msh + ' ' + xml
        s = "\nExecuting :\n\n\t %s\n\n" % cmd
        print_text(s, self.color)
        subprocess.call(cmd.split())
Ejemplo n.º 15
0
 def set_contour(self, cont_array):
     """ This is an alternative to the create_contour method that allows you to
 manually specify contour points.
 Inputs:
 cont_array : A numpy array of contour points (i.e. array([[1,2],[3,4],...]))
 """
     s = "::: manually setting contour with %s nodes:::"
     print_text(s % shape(cont_array)[0], self.color)
     fig = figure()
     self.ax = fig.add_subplot(111)
     self.ax.set_aspect('equal')
     self.longest_cont = cont_array
Ejemplo n.º 16
0
    def write_gmsh_contour(self, lc=100000, boundary_extend=True):
        """
    write the contour created with create_contour to the .geo file with mesh
    spacing <lc>.  If <boundary_extend> is true, the spacing in the interior
    of the domain will be the same as the distance between nodes on the contour.
    """
        #FIXME: sporadic results when used with ipython, does not stops writing the
        #       file after a certain point.  calling restart() then write again
        #       results in correct .geo file written.  However, running the script
        #       outside of ipython works.
        s = "::: writing gmsh contour to \"%s%s.geo\" :::"
        print_text(s % (self.direc, self.fn), self.color)
        c = self.longest_cont
        f = self.f

        pts = size(c[:, 0])

        # write the file to .geo file :
        f.write("// Mesh spacing\n")
        f.write("lc = " + str(lc) + ";\n\n")

        f.write("// Points\n")
        for i in range(pts):
            f.write("Point(" + str(i) + ") = {" + str(c[i,0]) + "," \
                    + str(c[i,1]) + ",0,lc};\n")

        f.write("\n// Lines\n")
        for i in range(pts - 1):
            f.write("Line(" + str(i) + ") = {" + str(i) + "," + str(i + 1) +
                    "};\n")
        f.write("Line(" + str(pts-1) + ") = {" + str(pts-1) + "," \
                + str(0) + "};\n\n")

        f.write("// Line loop\n")
        loop = ""
        loop += "{"
        for i in range(pts - 1):
            loop += str(i) + ","
        loop += str(pts - 1) + "}"
        f.write("Line Loop(" + str(pts + 1) + ") = " + loop + ";\n\n")

        f.write("// Surface\n")
        surf_num = pts + 2
        f.write("Plane Surface(" + str(surf_num) + ") = {" + str(pts + 1) +
                "};\n\n")

        if not boundary_extend:
            f.write("Mesh.CharacteristicLengthExtendFromBoundary = 0;\n\n")

        self.surf_num = surf_num
        self.pts = pts
        self.loop = loop
Ejemplo n.º 17
0
    def extrude(self, h, n_layers):
        """
    Extrude the mesh <h> units with <n_layers> number of layers.
    """
        s = "::: extruding gmsh contour %i layers :::" % n_layers
        print_text(s, self.color)
        f = self.f
        s = str(self.surf_num)
        h = str(h)
        layers = str(n_layers)

        f.write("Extrude {0,0," + h + "}" \
                + "{Surface{" + s + "};" \
                + "Layers{" + layers + "};}\n\n")
Ejemplo n.º 18
0
 def transform_contour(self, di):
     """
 Transforms the coordinates of the contour to DataInput object <di>'s
 projection coordinates.
 """
     if type(di) == type(self.dd):
         proj = di.proj
         name = di.name
     elif type(di) == dict:
         name = di['dataset']
         proj = di['pyproj_Proj']
     s = "::: transforming contour coordinates from %s to %s :::"
     print_text(s % (name, self.dd.name), self.color)
     x, y = self.longest_cont.T
     xn, yn = transform(self.dd.proj, proj, x, y)
     self.longest_cont = array([xn, yn]).T
Ejemplo n.º 19
0
 def __init__(self, dd, fn, direc):
     """
 Generate a mesh with DataInput object <dd>, output filename <fn>, and
 output directory <direc>.
 """
     self.color = 'grey_46'
     s = "::: INITIALIZING MESHGENERATOR :::"
     print_text(s, self.color)
     self.dd = dd
     self.fn = fn
     self.direc = direc
     self.x, self.y = meshgrid(dd.x, dd.y)
     if not os.path.exists(direc):
         os.makedirs(direc)
     self.f = open(direc + fn + '.geo', 'w')
     self.fieldList = []  # list of field indexes created.
Ejemplo n.º 20
0
    def finish(self, gui=True, dim=3, out_file_name='mesh'):
        """
    Finish and create the .msh file.  If <gui> is True, run the gui program,
    Otherwise, create the .msh file with dimension <dim> and filename
    <out_file_name>.msh.
    """
        self.out_file_name = out_file_name

        #launch the GUI
        if gui:
            print_text("::: opening GUI :::", self.color)
            FlGui.instance().run()

        # instead of starting the GUI, we could generate the mesh and save it
        else:
            s = "::: writing %s.msh :::" % out_file_name
            print_text(s, self.color)
            self.m.mesh(dim)
            self.m.save(out_file_name + ".msh")
Ejemplo n.º 21
0
    def check_dist(self, r):
        """
    remove points in xycoords that are not a linear distance of at least
    <dist> from previous point.
    """
        lin_dist = lambda p1, p2: sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)

        edge = self.edge
        xycoords = self.xycoords
        n = len(xycoords)

        mask = ones(n, dtype=bool)

        i = 0
        while (i < n - 1):
            p1 = xycoords[i]
            j = i + 1
            while (j < n and lin_dist(p1, xycoords[j]) < r):
                mask[j] = 0
                j += 1
            i = j

        # fix end of array
        i = -1
        while(n + i >= 0 and (not mask[i] or \
              lin_dist(xycoords[0],xycoords[i]) < r)):
            mask[i] = 0
            i -= 1

        #for i in range(0,n-2):
        #  p1 = xycoords[i]
        #  p2 = xycoords[i+1]
        #  if lin_dist(p1, p2) < r:
        #    mask[i] = 0

        # print results
        s    = "::: removed %s points closer than %s m to one another :::"% \
                (str(len(mask) - sum(mask)), r)
        print_text(s, self.color)

        self.xycoords = xycoords[mask]
Ejemplo n.º 22
0
    def convert_to_projection(self):
        """
    """
        self.xycoords = []
        self.edge = []
        p = self.llcoords[0, :]  # previous point
        self.xycoords.append(self.di.get_xy(p[0], p[1]))
        self.edge.append(True)
        p_p = self.xycoords[-1]
        distance = 0

        lin_dist = lambda p1, p2: sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)

        for p in self.llcoords:
            p_n = self.di.get_xy(p[0], p[1])  # Current point xy
            delta_X = lin_dist(p_n, p_p)
            distance += delta_X

            if delta_X > 500.:  # edge points are further apart
                self.edge.append(True)
            else:
                self.edge.append(False)
            self.xycoords.append(p_n)
            distance = 0.
            p_p = p_n
        """
    # remove points at end of array that may overlap
    while(len(self.xycoords) > 0):
      self.xycoords.pop()
      self.edge.pop()
    """

        self.xycoords = array(self.xycoords)
        self.plot_coords["xycoords"] = self.xycoords

        #self.clean_edge() #clean (very rare) incorrectly identified edge points
        self.edge = array(self.edge)

        s = "::: basin contour created with length %i :::"
        print_text(s % len(self.xycoords), self.color)
Ejemplo n.º 23
0
    def __init__(self, di, fn, gmsh_file_name):
        """
    Creates a 2D or 3D mesh based on contour .geo file <gmsh_file_name>.
    Refinements are done on DataInput object <di> with data field index <fn>.
    """
        self.color = '43'
        s = "::: initializing MeshRefiner on \"%s.geo\" :::" % gmsh_file_name
        print_text(s, self.color)

        self.field = di.data[fn].T
        print_min_max(self.field, 'refinement field [m]')

        self.spline = RectBivariateSpline(di.x, di.y, self.field, kx=1, ky=1)

        #load the mesh into a GModel
        self.m = GModel.current()
        self.m.load(gmsh_file_name + '.geo')

        # set some parameters :
        GmshSetOption("Mesh", "CharacteristicLengthFromPoints", 0.0)
        GmshSetOption("Mesh", "CharacteristicLengthExtendFromBoundary", 0.0)
        GmshSetOption("Mesh", "Smoothing", 100.0)
Ejemplo n.º 24
0
    def create_contour(self, var, zero_cntr, skip_pts):
        """
    Create a contour of the data field with index <var> of <dd> provided at
    initialization.  <zero_cntr> is the value of <var> to contour, <skip_pts>
    is the number of points to skip in the contour, needed to prevent overlap.
    """
        s    = "::: creating contour from %s's \"%s\" field with skipping %i " + \
               "point(s) :::"
        print_text(s % (self.dd.name, var, skip_pts), self.color)

        skip_pts = skip_pts + 1

        # create contour :
        field = self.dd.data[var]
        fig = figure()
        self.ax = fig.add_subplot(111)
        self.ax.set_aspect('equal')
        self.c = self.ax.contour(self.x, self.y, field, [zero_cntr])

        # Get longest contour:
        cl = self.c.allsegs[0]
        ind = 0
        amax = 0
        amax_ind = 0

        for a in cl:
            if size(a) > amax:
                amax = size(a)
                amax_ind = ind
            ind += 1

        # remove skip points and last point to avoid overlap :
        self.longest_cont = cl[amax_ind]
        s = "::: contour created, length %s nodes :::"
        print_text(s % shape(self.longest_cont)[0], self.color)
        self.remove_skip_points(skip_pts)
Ejemplo n.º 25
0
    def eliminate_intersections(self, dist=10):
        """
    Eliminate intersecting boundary elements. <dist> is an integer specifiying
    how far forward to look to eliminate intersections.  If any intersections
    are found, this method is called recursively until none are found.
    """
        s = "::: eliminating intersections :::"
        print_text(s, self.color)

        class Point:
            def __init__(self, x, y):
                self.x = x
                self.y = y

        def ccw(A, B, C):
            return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)

        def intersect(A, B, C, D):
            return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(
                A, B, D)

        lc = self.longest_cont

        flag = ones(len(lc))
        intr = False
        for ii in range(len(lc) - 1):

            A = Point(*lc[ii])
            B = Point(*lc[ii + 1])

            for jj in range(ii, min(ii + dist, len(lc) - 1)):

                C = Point(*lc[jj])
                D = Point(*lc[jj + 1])

                if intersect(A, B, C, D) and ii != jj + 1 and ii + 1 != jj:
                    s = "  - intersection found between node %i and %i"
                    print_text(s % (ii + 1, jj), 'red')
                    flag[ii + 1] = 0
                    flag[jj] = 0
                    intr = True

        counter = 0
        new_cont = zeros((sum(flag), 2))
        for ii, fl in enumerate(flag):
            if fl:
                new_cont[counter, :] = lc[ii, :]
                counter += 1

        self.longest_cont = new_cont
        s = "::: eliminated %i nodes :::"
        print_text(s % sum(flag == 0), self.color)
        # call again if required :
        if intr:
            self.eliminate_intersections(dist)