Пример #1
0
 def test_nonlinear_diagonalshift(self):
     nelems = 10
     domain, geom = mesh.rectilinear([nelems, 1])
     geom *= [2 * numpy.pi / nelems, 1]
     ubasis = domain.basis('spline', degree=2).vector(2)
     u = ubasis.dot(function.Argument('dofs', [len(ubasis)]))
     Geom = [.5 * geom[0], geom[1] + function.cos(geom[0])
             ] + u  # compress by 50% and buckle
     cons = solver.minimize('dofs',
                            domain.boundary['left,right'].integral(
                                (u**2).sum(0), degree=4),
                            droptol=1e-15).solve()
     strain = .5 * (function.outer(Geom.grad(geom), axis=1).sum(0) -
                    function.eye(2))
     energy = domain.integral(
         ((strain**2).sum([0, 1]) + 150 *
          (function.determinant(Geom.grad(geom)) - 1)**2) *
         function.J(geom),
         degree=6)
     nshift = 0
     for iiter, (lhs, info) in enumerate(
             solver.minimize('dofs', energy, constrain=cons)):
         self.assertLess(iiter, 38)
         if info.shift:
             nshift += 1
         if info.resnorm < self.tol:
             break
     self.assertEqual(nshift, 9)
Пример #2
0
def main(nelems:int, etype:str, btype:str, degree:int, poisson:float, angle:float, restol:float, trim:bool):
  '''
  Deformed hyperelastic plate.

  .. arguments::

     nelems [10]
       Number of elements along edge.
     etype [square]
       Type of elements (square/triangle/mixed).
     btype [std]
       Type of basis function (std/spline).
     degree [1]
       Polynomial degree.
     poisson [.25]
       Poisson's ratio, nonnegative and stricly smaller than 1/2.
     angle [20]
       Rotation angle for right clamp (degrees).
     restol [1e-10]
       Newton tolerance.
     trim [no]
       Create circular-shaped hole.
  '''

  domain, geom = mesh.unitsquare(nelems, etype)
  if trim:
    domain = domain.trim(function.norm2(geom-.5)-.2, maxrefine=2)
  bezier = domain.sample('bezier', 5)

  ns = function.Namespace(fallback_length=domain.ndims)
  ns.x = geom
  ns.angle = angle * numpy.pi / 180
  ns.lmbda = 2 * poisson
  ns.mu = 1 - 2 * poisson
  ns.ubasis = domain.basis(btype, degree=degree)
  ns.u_i = 'ubasis_k ?lhs_ki'
  ns.X_i = 'x_i + u_i'
  ns.strain_ij = '.5 (d(u_i, x_j) + d(u_j, x_i))'
  ns.energy = 'lmbda strain_ii strain_jj + 2 mu strain_ij strain_ij'

  sqr = domain.boundary['left'].integral('u_k u_k J(x)' @ ns, degree=degree*2)
  sqr += domain.boundary['right'].integral('((u_0 - x_1 sin(2 angle) - cos(angle) + 1)^2 + (u_1 - x_1 (cos(2 angle) - 1) + sin(angle))^2) J(x)' @ ns, degree=degree*2)
  cons = solver.optimize('lhs', sqr, droptol=1e-15)

  energy = domain.integral('energy J(x)' @ ns, degree=degree*2)
  lhs0 = solver.optimize('lhs', energy, constrain=cons)
  X, energy = bezier.eval(['X', 'energy'] @ ns, lhs=lhs0)
  export.triplot('linear.png', X, energy, tri=bezier.tri, hull=bezier.hull)

  ns.strain_ij = '.5 (d(u_i, x_j) + d(u_j, x_i) + d(u_k, x_i) d(u_k, x_j))'
  ns.energy = 'lmbda strain_ii strain_jj + 2 mu strain_ij strain_ij'

  energy = domain.integral('energy J(x)' @ ns, degree=degree*2)
  lhs1 = solver.minimize('lhs', energy, arguments=dict(lhs=lhs0), constrain=cons).solve(restol)
  X, energy = bezier.eval(['X', 'energy'] @ ns, lhs=lhs1)
  export.triplot('nonlinear.png', X, energy, tri=bezier.tri, hull=bezier.hull)

  return lhs0, lhs1
Пример #3
0
 def test_nonlinear_diagonalshift(self):
   nelems = 10
   domain, geom = mesh.rectilinear([nelems,1])
   geom *= [2*numpy.pi/nelems, 1]
   ubasis = domain.basis('spline', degree=2).vector(2)
   u = ubasis.dot(function.Argument('dofs', [len(ubasis)]))
   Geom = [.5 * geom[0], geom[1] + function.cos(geom[0])] + u # compress by 50% and buckle
   cons = solver.minimize('dofs', domain.boundary['left,right'].integral((u**2).sum(0), degree=4), droptol=1e-15).solve()
   strain = .5 * (function.outer(Geom.grad(geom), axis=1).sum(0) - function.eye(2))
   energy = domain.integral(((strain**2).sum([0,1]) + 150*(function.determinant(Geom.grad(geom))-1)**2)*function.J(geom), degree=6)
   nshift = 0
   for iiter, (lhs, info) in enumerate(solver.minimize('dofs', energy, constrain=cons)):
     self.assertLess(iiter, 90)
     if info.shift:
       nshift += 1
     if info.resnorm < self.tol:
       break
   self.assertEqual(nshift, 60)
Пример #4
0
 def setUp(self):
   super().setUp()
   domain, geom = mesh.rectilinear([numpy.linspace(0,1,9)] * 2)
   ubasis = domain.basis('std', degree=2).vector(2)
   u = ubasis.dot(function.Argument('dofs', [len(ubasis)]))
   Geom = geom * [1.1, 1] + u
   self.cons = solver.minimize('dofs', domain.boundary['left,right'].integral((u**2).sum(0), degree=4), droptol=1e-15).solve()
   self.boolcons = ~numpy.isnan(self.cons)
   strain = .5 * (function.outer(Geom.grad(geom), axis=1).sum(0) - function.eye(2))
   self.energy = domain.integral(((strain**2).sum([0,1]) + 20*(function.determinant(Geom.grad(geom))-1)**2)*function.J(geom), degree=6)
   self.residual = self.energy.derivative('dofs')
   self.tol = 1e-10
Пример #5
0
 def test_minimize_boolcons(self):
     self.assert_resnorm(
         solver.minimize('dofs',
                         energy=self.energy,
                         constrain=self.boolcons).solve(tol=self.tol,
                                                        maxiter=12))
Пример #6
0
 def setUp(self):
   super().setUp()
   self.ns = function.Namespace()
   self.domain, self.ns.geom = mesh.rectilinear([2,2])
   self.ns.ubasis = self.domain.basis('std', degree=1)
   self.ns.u = 'ubasis_n ?dofs_n'
   self.optimize = solver.optimize if not self.minimize else lambda *args, newtontol=0, **kwargs: solver.minimize(*args, **kwargs).solve(newtontol)
Пример #7
0
 def test_minimize_iter(self):
   _test_recursion_cache(self, lambda: ((types.frozenarray(lhs), info.resnorm) for lhs, info in solver.minimize('dofs', energy=self.energy, constrain=self.cons)))
Пример #8
0
 def test_minimize_boolcons(self):
   self.assert_resnorm(solver.minimize('dofs', energy=self.energy, constrain=self.boolcons).solve(tol=self.tol, maxiter=8))