示例#1
0
 def build_system(self, q, q0, R_load=None):
     """Build the matrix system of equations for the next Newton step."""
     DT = self._sess.run(self._vars['Dt'])
     R0_vol_arr = self._sess.run([self.rhs],
                                 feed_dict={self.i_q: q0.reshape(-1, 2)})
     # The mass component at t
     vol_R0, = cf.Assemble(husk_identity.kernel_idty_R,
                           self.H_vol, {
                               'iR': (R0_vol_arr, self.dm_q),
                           }, {
                               'R': (self.dm_q, ),
                           },
                           ndof=self.X.shape[0] * 2)
     # Assemble the mass component at t+Dt:
     K_vol_arr, R_vol_arr = self._sess.run(
         [self.K_lhs, self.lhs], feed_dict={self.i_q: q.reshape(-1, 2)})
     vol_R, vol_K = cf.Assemble(husk_identity.kernel_idty_RK,
                                self.H_vol, {
                                    'iR': (R_vol_arr, self.dm_q),
                                    'iK': (K_vol_arr, self.dm_4)
                                }, {
                                    'R': (self.dm_q, ),
                                    'K': (self.dm_q, )
                                },
                                ndof=self.X.shape[0] * 2)
     # Assemble the fluxes:
     q_face = np.array([q[self.dm_q.Get_List(e[0:2])] for e in self.H_face])
     X_face = np.array(
         [self.X.ravel()[self.dm_q.Get_List(e[0:2])] for e in self.H_face])
     qA = q_face[:, 0:2]
     qB = q_face[:, 2:4]
     XA = X_face[:, 0:2]
     XB = X_face[:, 2:4]
     oF, oKF = self._sess.run([self.o_F, self.o_KF],
                              feed_dict={
                                  self.i_q: qA,
                                  self.i_q2: qB,
                                  self.i_XA: XA,
                                  self.i_XB: XB
                              })
     flux_R, flux_K = cf.Assemble(husk_identity.kernel_idty_2_RK,
                                  self.H_face, {
                                      'iR': (oF.flatten(), self.dm_face),
                                      'iK': (oKF.flatten(), self.dm_face16)
                                  }, {
                                      'R': (self.dm_q, ),
                                      'K': (self.dm_q, )
                                  },
                                  ndof=self.X.shape[0] * 2)
     # Make the runge kutta system
     RR = vol_R0 - vol_R + DT * flux_R
     if not R_load is None:
         RR += R_load
     KK = vol_K - DT * flux_K
     return RR, KK
示例#2
0
    def solve(self,
              method,
              weight,
              P=1.0,
              smoothing="",
              stab=2.0,
              fictmet="trivial"):
        """
        Solves the deformation of the block matrix given the method name and
        influence function. The influence support is decided at initialization
        of the PeriBlock object.

        The method and weight strings key directly into the peridynamics kernels
        in the husk. There is an additional smoothing argument, which, if not
        false-valued, will call the smoothing kernel after assembling and
        solving the system.

        If there are cut bonds present, self.HCut, the P argument will be used
        to apply the fluid-filled pressure force on the bonds.
        """
        # Assemble the matrix and load for the given peridynamics law
        K, R = self._assemble_KR(method, weight, stab)
        # Assemble the fluid pressure on bonds if present
        try:
            Rp, = cf.Assemble(
                hb.kernel_bond_pressure, self.HCut,
                [self.data, {
                    'p': (np.array([P]), self.dm_GlobalSca)
                }], {
                    'R': (self.dm_PtVec, ),
                }, gdim * self.NPart)
            R += Rp
        except AttributeError:
            pass
        # Add the ficticious domain component
        if self.ficticious:
            K, R = self._assemble_KR_fict(K, R, fictmet, method, weight, stab)
        else:
            R -= self.data['load'][0].ravel(
            ) * self.data['p_Vol'][0]**0.5 / self.data['p_Vol'][0]

        # Apply boundary conditions and then solve the matrix system
        cf.Apply_BC(self.diridofs, self.ubc, K, R)

        u = splin.spsolve(K, R)
        # If we specified a smoothing function, post process the solution
        if smoothing:
            us, = cf.Assemble(hp.__dict__['kernel_smooth_{0}'.format(weight)],
                              self.HAdj,
                              [self.data, {
                                  'y': (u, self.dm_PtVec)
                              }], {'ys': (self.dm_PtVec, )}, gdim * self.NPart)
            u = us
        # The PeriBlock object is stateless w.r.t. solution, so
        return u
示例#3
0
 def _assemble_KR(self, method, weight, stab=0.0):
     K, R = cf.Assemble(
         hp.__dict__['kernel_{0}_{1}'.format(method, weight)], self.HAdj,
         [self.data, {
             'p_stab': (np.array([stab]), self.dm_GlobalSca)
         }], {
             'R': (self.dm_PtVec, ),
             'K': (self.dm_PtVec, )
         }, gdim * self.NPart)
     return K, R
示例#4
0
 def _assemble_KR_fict(self, K, R, fictmet, method, weight, stab=0.0):
     if fictmet == "trivial":
         Kf, Rf = cf.Assemble(
             hp.__dict__['kernel_{0}_{1}'.format(method,
                                                 weight)], self.HFict,
             [self.data, {
                 'p_stab': (np.array([stab]), self.dm_GlobalSca)
             }], {
                 'R': (self.dm_PtVec, ),
                 'K': (self.dm_PtVec, )
             }, gdim * self.NPart)
         Rf -= self.data['load'][0].ravel(
         ) * self.data['p_Vol'][0]**0.5 / self.data['p_Vol'][0]
         return K + Kf, R + Rf
     elif fictmet == "bobaru":
         K3, R3 = cf.Assemble(hf.kernel_bobaru_n3, self.HFictStencil3,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         K4, R4 = cf.Assemble(hf.kernel_bobaru_n, self.HFictStencil4,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         Kb = K3 + K4
         Rb = R3 + R4
         Kt = K.copy()
         Rt = R.copy()
         for e in self.FictNodes:
             Kt[self.dm_PtVec.Get_List([e]), :] = Kb[
                 self.dm_PtVec.Get_List([e]), :]
             Rt[self.dm_PtVec.Get_List([e
                                        ])] = Rb[self.dm_PtVec.Get_List([e
                                                                         ])]
         return Kt, Rt
     elif fictmet == "bobaru_F":
         K3, R3 = cf.Assemble(hf.kernel_bobaru_F3, self.HFictStencil3,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         K4, R4 = cf.Assemble(hf.kernel_bobaru_F, self.HFictStencil4,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         Kb = K3 + K4
         Rb = R3 + R4
         Kt = K.copy()
         Rt = R.copy()
         for e in self.FictNodes:
             Kt[self.dm_PtVec.Get_List([e]), :] = Kb[
                 self.dm_PtVec.Get_List([e]), :]
             Rt[self.dm_PtVec.Get_List([e
                                        ])] = Rb[self.dm_PtVec.Get_List([e
                                                                         ])]
         return Kt, Rt
     elif fictmet == "both":
         Kp, Rp = cf.Assemble(
             hp.__dict__['kernel_{0}_{1}'.format(method,
                                                 weight)], self.HFict,
             [self.data, {
                 'p_stab': (np.array([stab]), self.dm_GlobalSca)
             }], {
                 'R': (self.dm_PtVec, ),
                 'K': (self.dm_PtVec, )
             }, gdim * self.NPart)
         K3, R3 = cf.Assemble(hf.kernel_bobaru_n3, self.HFictStencil3,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         K4, R4 = cf.Assemble(hf.kernel_bobaru_n, self.HFictStencil4,
                              self.data, {
                                  'R': (self.dm_PtVec, ),
                                  'K': (self.dm_PtVec, )
                              }, gdim * self.NPart)
         Kb = K3 + K4
         Rb = R3 + R4
         Kt = K + Kp
         Rt = R + Rp
         for e in self.FictNodes:
             Kt[self.dm_PtVec.Get_List([e]), :] = Kb[
                 self.dm_PtVec.Get_List([e]), :]
             Rt[self.dm_PtVec.Get_List([e
                                        ])] = Rb[self.dm_PtVec.Get_List([e
                                                                         ])]
         return Kt, Rt
     return K, R
示例#5
0
    'p_vol': (np.array([particle_Vol]), dm_GlobalSca),
}

# Mark boundaries
eps = 1.0e-10
right = cf.select_nodes(x, lambda a: a[0] < -L + eps)
left = cf.select_nodes(x, lambda a: a[0] > L - eps)
bottom = cf.select_nodes(x, lambda a: a[1] < -L + eps)
top = cf.select_nodes(x, lambda a: a[1] > L - eps)

loaddofs = dm_PtVec.Get_List(top)[1::2]
dirrdofs = np.array([
    dm_PtVec.Get_List(right)[0::2],
    dm_PtVec.Get_List(left)[0::2],
    dm_PtVec.Get_List(bottom)[1::2]
]).flatten()
Nbc = len(dirrdofs)
ubc = np.zeros(Nbc)

# Make the linear system
K, R = cf.Assemble(hp.kernel_Silling_cubic, HAdj, data, {
    'R': (cf.Dofmap_Strided(gdim), ),
    'K': (cf.Dofmap_Strided(gdim), )
}, gdim * NPart)
cf.Apply_BC(dirrdofs, ubc, K, R)
R[loaddofs] -= 1.0
u = splin.spsolve(K, R)

cf.GraphIO.write_graph("./out.vtk", HPair, x, [('x', x),
                                               ('u', u.reshape((-1, 2)))])