def make_line_mesh(self, Ny, L): """Makes a new mesh of elements in a line.""" # The centers of the volumes self.X = np.c_[np.zeros((Ny, )), np.linspace(0, L, Ny)] # A graph of the connections self.H_face = cf.Hypergraph() for i in range(Ny - 1): self.H_face.Push_Edge([i, i + 1, i + Ny]) self._make_vol_graph() self._make_dofmaps()
def Make_Bond_Adjacency(H): edges = H.view()[0] newgraph = defaultdict(lambda: []) for l in edges: newgraph[l[0]].append((l[1], l[2])) newgraph[l[1]].append((l[0], l[2])) HA = cf.Hypergraph() for center, bonds in newgraph.iteritems(): egg = np.empty(2 * len(bonds) + 1, dtype=np.intc) egg[0] = center for i, b in enumerate(bonds): egg[1 + i] = b[0] egg[1 + len(bonds) + i] = b[1] HA.Push_Edge(egg) return HA
import cornflakes as cf import numpy as np from PeriBlock import PeriBlock L = 1.0 N = 10 delta = 1.5 * 2.0 * L / float(N) PB = PeriBlock(L, N, delta, ficticious=True) PB.setbcs([(PB.right, 0), (PB.left, 0), (PB.bottom, 1)], [(PB.top, 1)]) eps = 1.0e-12 inside = lambda x: x[0] < L + eps and x[0] > -L - eps or x[1] > -L - eps or x[ 1] < L + eps HStencil4 = cf.Hypergraph() HStencil3 = cf.Hypergraph() for e in PB.HFict: x0 = PB.x[e[0], :] bodyvertices = [] print print x0 for i in e[1:(len(e) / 2 + 1)]: print PB.x[i, :] if x0[0] > L: if PB.x[i, 0] < L + eps: bodyvertices.append(i) elif x0[0] < -L: if PB.x[i, 0] > -L - eps: bodyvertices.append(i) elif x0[1] > L:
def _make_vol_graph(self): """Cornflakes needs a graph of singletons to represent the volumes""" self.H_vol = cf.Hypergraph() for i in range(self.X.shape[0]): self.H_vol.Push_Edge([i])
def __init__(self, L, Nside, delta, E=1.0, nu=0.0, ficticious=False, ficticious_size=1.0): """ Initialize a square domain of half-side-length L with Nside particles along its side. delta is the support of the influence function. A Peridynamics scheme has 3 hyperparameters: 1. method: The force law 2. weight: The form of the influence function 3. delta: The scaling of the support radius The delta is the only hyperparamter that needs to be set at first; the same data and graph can be applied to many schemes in solve(). The delta radius is used to build the neighbor list. """ if ficticious: # The band shouldn't mess up the gridding h = 2.0 * L / float(Nside - 1) # ceil would give us one more, but it wouldn't be inside # any particles' support. Then it's BC wouldn't be obvious Ndel = int(np.floor(delta / h) * ficticious_size) band = Ndel * h Ltot = L + band Nside = Nside + Ndel * 2 else: Ltot = L self.ficticious = ficticious # Make a grid and the graphs self.x = cf.PP.init_grid(Nside, Nside, [-Ltot, -Ltot], [2 * Ltot, 0.0], [0.0, 2 * Ltot]) particle_Vol = (2.0 * L)**2 / float(Nside**2) self.NPart = self.x.shape[0] self.HPair = cf.Graphers.Build_Pair_Graph(self.x, delta * 1.1) self.NBond = len(self.HPair) self.HBond = cf.Graphers.Build_Pair_Graph(self.x, delta * 1.1) self.HBond.Add_Edge_Vertex(self.NPart) self.HAdj = util.Make_Bond_Adjacency(self.HBond) # The ficticious nodes are set aside in a different graph, because # they will apply a different operator than the PD stencil if ficticious: self.FictNodes = set() self.HFict = cf.Hypergraph() Hnew = cf.Hypergraph() for e in self.HAdj: xi = self.x[e[0], :] if xi[0] < L + eps and xi[0] > -L - eps and xi[ 1] > -L - eps and xi[1] < L + eps: Hnew.Push_Edge(e) else: self.HFict.Push_Edge(e) self.FictNodes.add(e[0]) self.HAdj = Hnew # Make the FDM stencils self.HFictStencil4 = cf.Hypergraph() self.HFictStencil3 = cf.Hypergraph() for e in self.HFict: x0 = self.x[e[0], :] bodyvertices = [] for i in e[1:(len(e) / 2 + 1)]: if x0[1] > L: if self.x[i, 1] < L + eps: bodyvertices.append(i) elif x0[1] < -L: if self.x[i, 1] > -L - eps: bodyvertices.append(i) elif x0[0] > L: if self.x[i, 0] < L + eps: bodyvertices.append(i) elif x0[0] < -L: if self.x[i, 0] > -L - eps: bodyvertices.append(i) bodyvertices.sort( key=lambda i: np.linalg.norm(self.x[i, :] - x0)) if len(bodyvertices) == 2: self.HFictStencil3.Push_Edge([e[0]] + bodyvertices) elif len(bodyvertices) == 3: self.HFictStencil4.Push_Edge([e[0]] + bodyvertices) # Make the data arrays, vertex-to-data mappings, and the data dictionary y = self.x.copy() alpha = np.ones(self.NBond, dtype=np.double) delta = np.ones(self.NPart, dtype=np.double) self.dm_PtVec = cf.Dofmap_Strided(gdim) self.dm_PtSca = cf.Dofmap_Strided(1) self.dm_BondSca = cf.Dofmap_Strided(1, -self.NPart) self.dm_GlobalSca = cf.Dofmap_Strided(1, stride=0) self.data = { 'x': (self.x, self.dm_PtVec), 'y': (y, self.dm_PtVec), 'alpha': (alpha, self.dm_BondSca), 'delta': (delta, self.dm_PtSca), 'p_E': (np.array([E]), self.dm_GlobalSca), 'p_nu': (np.array([nu]), self.dm_GlobalSca), 'p_Vol': (np.array([particle_Vol]), self.dm_GlobalSca), 'p_stab': (np.array([1.0]), self.dm_GlobalSca), 'load': (np.zeros(self.x.shape), self.dm_PtVec) } # Mark boundaries if self.ficticious: self.fleft = cf.select_nodes(self.x, lambda a: a[0] < -L - h + eps) self.fright = cf.select_nodes(self.x, lambda a: a[0] > L + h - eps) self.fbottom = cf.select_nodes(self.x, lambda a: a[1] < -L - h + eps) self.ftop = cf.select_nodes(self.x, lambda a: a[1] > L + h - eps) self.left = cf.select_nodes(self.x, lambda a: a[0] < -L + eps) self.right = cf.select_nodes(self.x, lambda a: a[0] > L - eps) self.bottom = cf.select_nodes(self.x, lambda a: a[1] < -L + eps) self.top = cf.select_nodes(self.x, lambda a: a[1] > L - eps)
def write_cloud(fname, X, nodefields): import cornflakes as cf Hcloud = cf.Hypergraph() for l in xrange(X.shape[0]): Hcloud.Push_Edge([l]) cf.GraphIO.write_graph(fname, Hcloud, X,nodefields)