Esempio n. 1
0
    def createMesh(self, ctrs, fd, frame, plot=False):
        self.frame = frame
        pfix = None

        # Extract bounding box
        xmin, ymin, xmax, ymax = self.bbox
        if pfix is not None:
            pfix = np.array(pfix, dtype='d')

        #1. Set up initial points
        x, y = np.mgrid[xmin:(xmax + self.h0):self.h0,
                        ymin:(ymax + self.h0 * np.sqrt(3) / 2):self.h0 *
                        np.sqrt(3) / 2]
        x[:, 1::2] += self.h0 / 2  # Shift even rows
        p = np.vstack((x.flat, y.flat)).T  # List of node coordinates

        # 2. Remove points outside the region, apply the rejection method
        a = fd(p)
        p = p[np.where(a < self.geps)]  # Keep only d<0 points
        r0 = 1 / self.fh(p)**2  # Probability to keep point
        p = p[np.random.random(p.shape[0]) < r0 / r0.max()]  # Rejection method
        if pfix is not None:
            p = ml.setdiff_rows(p, pfix)  # Remove duplicated nodes
            pfix = ml.unique_rows(pfix)
            nfix = pfix.shape[0]
            p = np.vstack((pfix, p))  # Prepend fix points
        else:
            nfix = 0
        N = p.shape[0]  # Number of points N
        self.N = N

        count = 0
        pold = float('inf')  # For first iteration

        ################################################################################
        #Mesh creation
        ################################################################################

        while count < self.maxiter:
            print 'DistMesh create count: %d/%d' % (count, self.maxiter)
            count += 1
            # 3. Retriangulation by the Delaunay algorithm
            dist = lambda p1, p2: np.sqrt(((p1 - p2)**2).sum(1))
            if (dist(p, pold) /
                    self.h0).max() > self.ttol:  # Any large movement?
                pold = p.copy()  # Save current positions
                self.delaunay = spspatial.Delaunay(p)
                t = self.delaunay.vertices  # List of triangles
                pmid = p[t].sum(1) / 3  # Compute centroids
                t = t[fd(pmid) < -self.geps]  # Keep interior triangles
                # 4. Describe each bar by a unique pair of nodes
                bars = np.vstack((t[:, [0, 1]], t[:, [1, 2]],
                                  t[:, [2, 0]]))  # Interior bars duplicated
                bars.sort(axis=1)
                bars = ml.unique_rows(bars)  # Bars as node pairs
                #Plot
                fc = frame.copy()
                if frame is not None:
                    drawGrid(fc, p, bars)
                    if plot:
                        cv2.imshow('Initial mesh', fc)
                        k = cv2.waitKey(30) & 0xff
                        if k == 27:
                            break

            # 6. Move mesh points based on bar lengths L and forces F
            barvec = p[bars[:, 0]] - p[bars[:, 1]]  # List of bar vectors
            L = np.sqrt((barvec**2).sum(1))  # L = Bar lengths
            hbars = self.fh(p[bars].sum(1) / 2)
            L0 = 1.5 * self.h0 * np.ones_like(L)
            #(hbars*Fscale
            #*np.sqrt((L**2).sum()/(hbars**2).sum()))  # L0 = Desired lengths

            F = self.k * (L0 - L)
            F[F <
              0] = 0  #F[F<0]*.5#0                         # Bar forces (scalars)
            Fvec = F[:, None] / L[:, None].dot(
                [[1, 1]]) * barvec  # Bar forces (x,y components)
            Ftot = ml.dense(bars[:, [0, 0, 1, 1]],
                            np.repeat([[0, 1, 0, 1]], len(F), axis=0),
                            np.hstack((Fvec, -Fvec)),
                            shape=(N, 2))
            Ftot[:nfix] = 0  # Force = 0 at fixed points
            p += self.deltat * Ftot  # Update node positions

            # 7. Bring outside points back to the boundary
            d = fd(p)
            ix = d > 0  # Find points outside (d>0)
            ddeps = 1e-1
            for idx in range(10):
                if ix.any():
                    dgradx = (fd(p[ix] + [ddeps, 0]) -
                              d[ix]) / ddeps  # Numerical
                    dgrady = (fd(p[ix] + [0, ddeps]) -
                              d[ix]) / ddeps  # gradient
                    dgrad2 = dgradx**2 + dgrady**2
                    p[ix] -= (d[ix] * np.vstack(
                        (dgradx, dgrady)) / dgrad2).T  # Project

            # 8. Termination criterion: All interior nodes move less than dptol (scaled)
            if (np.sqrt((self.deltat * Ftot[d < -self.geps]**2).sum(1)) /
                    self.h0).max() < self.dptol:
                break

        self.p = p
        self.t = t
        self.bars = bars
        self.L = L
Esempio n. 2
0
	def createMesh(self, ctrs, fd, frame, plot = False):
		self.frame = frame 
		pfix = None 
	
		# Extract bounding box
		xmin, ymin, xmax, ymax = self.bbox
		if pfix is not None:
			pfix = np.array(pfix, dtype='d')
		
		#1. Set up initial points 
		x, y = np.mgrid[xmin:(xmax+self.h0):self.h0,
										ymin:(ymax+self.h0*np.sqrt(3)/2):self.h0*np.sqrt(3)/2]
		x[:, 1::2] += self.h0/2                               # Shift even rows
		p = np.vstack((x.flat, y.flat)).T                # List of node coordinates
		
		# 2. Remove points outside the region, apply the rejection method
		a = fd(p)
		p = p[np.where(a<self.geps)]                          # Keep only d<0 points
		r0 = 1/self.fh(p)**2                                  # Probability to keep point
		p = p[np.random.random(p.shape[0])<r0/r0.max()]  # Rejection method
		if pfix is not None:
			p = ml.setdiff_rows(p, pfix)                 # Remove duplicated nodes
			pfix = ml.unique_rows(pfix); nfix = pfix.shape[0]
			p = np.vstack((pfix, p))                     # Prepend fix points
		else:
			nfix = 0
		N = p.shape[0]                                   # Number of points N
		self.N = N
		
		count = 0
		pold = float('inf')                              # For first iteration
		
		################################################################################
		#Mesh creation
		################################################################################
		
		while count < self.maxiter: 
			#print count 
			count += 1
			# 3. Retriangulation by the Delaunay algorithm
			dist = lambda p1, p2: np.sqrt(((p1-p2)**2).sum(1))
			if (dist(p, pold)/self.h0).max() > self.ttol:          # Any large movement?
				pold = p.copy()                          # Save current positions
				self.delaunay = spspatial.Delaunay(p)
				t = self.delaunay.vertices       # List of triangles
				pmid = p[t].sum(1)/3                     # Compute centroids
				t = t[fd(pmid) < -self.geps]                  # Keep interior triangles
				# 4. Describe each bar by a unique pair of nodes
				bars = np.vstack((t[:, [0,1]],
									t[:, [1,2]],
									t[:, [2,0]]))          # Interior bars duplicated
				bars.sort(axis=1)
				bars = ml.unique_rows(bars)              # Bars as node pairs
				#Plot
				fc = frame.copy()
				if frame is not None:
					drawGrid(fc, p, bars)
					if plot:
						cv2.imshow('Initial mesh',fc)
						k = cv2.waitKey(30) & 0xff
						if k == 27:
							break
		
			# 6. Move mesh points based on bar lengths L and forces F
			barvec = p[bars[:,0]] - p[bars[:,1]]         # List of bar vectors
			L = np.sqrt((barvec**2).sum(1))              # L = Bar lengths
			hbars = self.fh(p[bars].sum(1)/2)
			L0 = 1.5*self.h0*np.ones_like(L); #(hbars*Fscale
						#*np.sqrt((L**2).sum()/(hbars**2).sum()))  # L0 = Desired lengths
		
			F = self.k*(L0-L)
			F[F<0] = 0#F[F<0]*.5#0                         # Bar forces (scalars)
			Fvec = F[:,None]/L[:,None].dot([[1,1]])*barvec # Bar forces (x,y components)
			Ftot = ml.dense(bars[:,[0,0,1,1]],
											np.repeat([[0,1,0,1]], len(F), axis=0),
											np.hstack((Fvec, -Fvec)),
											shape=(N, 2))
			Ftot[:nfix] = 0                              # Force = 0 at fixed points
			p += self.deltat*Ftot                             # Update node positions
		
			# 7. Bring outside points back to the boundary
			d = fd(p); ix = d>0                          # Find points outside (d>0)
			ddeps = 1e-1
			for idx in range(10):
				if ix.any():
					dgradx = (fd(p[ix]+[ddeps,0])-d[ix])/ddeps # Numerical
					dgrady = (fd(p[ix]+[0,ddeps])-d[ix])/ddeps # gradient
					dgrad2 = dgradx**2 + dgrady**2
					p[ix] -= (d[ix]*np.vstack((dgradx, dgrady))/dgrad2).T # Project
		
			# 8. Termination criterion: All interior nodes move less than dptol (scaled)
			if (np.sqrt((self.deltat*Ftot[d<-self.geps]**2).sum(1))/self.h0).max() < self.dptol:
				break
		
		self.p = p 
		self.t = t 
		self.bars = bars
		self.L = L 
Esempio n. 3
0
 def plot(self):
     fc = self.frame.copy()
     if self.bars is not None:
         drawGrid(fc, self.p, self.bars)
         cv2.imshow('Current mesh', fc)
         k = cv2.waitKey(30) & 0xff
Esempio n. 4
0
	def plot(self):
		fc = self.frame.copy()
		if self.bars is not None:
			drawGrid(fc, self.p, self.bars)
			cv2.imshow('Current mesh',fc)
			k = cv2.waitKey(30) & 0xff