def test_Smooth(self): K = 12.3 G = 45.6 gamma = 0.02 epsm = 0.12 Eps = np.array([[epsm, gamma], [gamma, epsm]]) Sig = np.array([[K * epsm, 0.0], [0.0, K * epsm]]) self.assertTrue(np.isclose(float(GMat.Epsd(Eps)), gamma)) mat = GMat.Smooth(K, G, [0.01, 0.03, 0.10]) mat.setStrain(Eps) self.assertTrue(np.allclose(mat.Stress(), Sig)) self.assertTrue(mat.currentIndex() == 1) self.assertTrue(np.isclose(mat.epsp(), 0.02)) self.assertTrue(np.isclose(mat.currentYieldLeft(), 0.01)) self.assertTrue(np.isclose(mat.currentYieldRight(), 0.03)) self.assertTrue( np.isclose(mat.currentYieldLeft(), mat.refQPotChunked().yleft())) self.assertTrue( np.isclose(mat.currentYieldRight(), mat.refQPotChunked().yright()))
def test_Elastic(self): shape = [2, 3] K = np.random.random(shape) G = np.random.random(shape) mat = GMat.Elastic2d(K, G) gamma = np.random.random(shape) epsm = np.random.random(shape) mat.Eps[..., 0, 0] = epsm mat.Eps[..., 1, 1] = epsm mat.Eps[..., 0, 1] = gamma mat.Eps[..., 1, 0] = gamma mat.refresh() Sig = np.empty(shape + [2, 2]) Sig[..., 0, 0] = K * epsm Sig[..., 1, 1] = K * epsm Sig[..., 0, 1] = G * gamma Sig[..., 1, 0] = G * gamma self.assertTrue(np.allclose(GMat.Epsd(mat.Eps), gamma)) self.assertTrue(np.allclose(GMat.Sigd(mat.Sig), 2 * G * gamma)) self.assertTrue(np.allclose(mat.Sig, Sig)) self.assertTrue(np.allclose(tensor.A4_ddot_B2(mat.C, mat.Eps), Sig)) self.assertTrue(np.allclose(mat.energy, K * epsm**2 + G * gamma**2)) self.assertTrue(np.allclose(mat.K, K)) self.assertTrue(np.allclose(mat.G, G))
def test_Epsd_Sigd(self): A = np.zeros((2, 3, 2, 2)) A[..., 0, 1] = 1 A[..., 1, 0] = 1 self.assertTrue(np.allclose(GMat.Epsd(A), np.ones(A.shape[:-2]))) self.assertTrue(np.allclose(GMat.Sigd(A), 2 * np.ones(A.shape[:-2])))
def test_addSimpleShearToFixedStress(self): mesh = GooseFEM.Mesh.Quad4.Regular(3, 3) coor = mesh.coor() dofs = mesh.dofs() dofs[mesh.nodesLeftOpenEdge(), ...] = dofs[mesh.nodesRightOpenEdge(), ...] elastic = np.array([0, 1, 2, 6, 7, 8], dtype=np.uint64) plastic = np.array([3, 4, 5], dtype=np.uint64) epsy = 1e-3 * np.cumsum(np.ones((plastic.size, 5)), axis=1) system = FrictionQPotFEM.UniformSingleLayer2d.System( coor=coor, conn=mesh.conn(), dofs=dofs, iip=dofs[np.concatenate((mesh.nodesBottomEdge(), mesh.nodesTopEdge())), :].ravel(), elastic_elem=elastic, elastic_K=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=0.01, rho=1, alpha=0.1, eta=0, ) system.initEventDrivenSimpleShear() dV = system.quad.AsTensor(2, system.quad.dV) for step in range(4): u_n = np.copy(system.u) sig_n = GMat.Sigd(np.average(system.Sig(), weights=dV, axis=(0, 1))) system.eventDrivenStep(1e-4, step % 2 == 0, direction=1) system.minimise() sig = GMat.Sigd(np.average(system.Sig(), weights=dV, axis=(0, 1))) target = sig_n + 0.5 * (sig - sig_n) system.u = u_n system.addSimpleShearToFixedStress(target) self.assertTrue( np.isclose(target, GMat.Sigd(np.average(system.Sig(), weights=dV, axis=(0, 1)))) )
def test_main(self): with h5py.File("Cartesian2d_random.hdf5", "r") as data: shape = data["/shape"][...] mat = GMat.Matrix(shape[0], shape[1]) I = data["/cusp/I"][...] idx = data["/cusp/idx"][...] K = data["/cusp/K"][...] G = data["/cusp/G"][...] epsy = data["/cusp/epsy"][...] mat.setCusp(I, idx, K, G, epsy) I = data["/smooth/I"][...] idx = data["/smooth/idx"][...] K = data["/smooth/K"][...] G = data["/smooth/G"][...] epsy = data["/smooth/epsy"][...] mat.setSmooth(I, idx, K, G, epsy) I = data["/elastic/I"][...] idx = data["/elastic/idx"][...] K = data["/elastic/K"][...] G = data["/elastic/G"][...] mat.setElastic(I, idx, K, G) for i in range(20): GradU = data[f"/random/{i:d}/GradU"][...] Eps = np.einsum("...ijkl,...lk->...ij", mat.I4s(), GradU) idx = mat.Find(Eps) self.assertTrue( np.allclose(mat.Stress(Eps), data[f"/random/{i:d}/Stress"][...])) self.assertTrue( np.allclose( mat.Tangent(Eps)[1], data[f"/random/{i:d}/Tangent"][...], )) self.assertTrue( np.allclose( mat.Epsy(idx), data[f"/random/{i:d}/CurrentYieldLeft"][...], )) self.assertTrue( np.allclose( mat.Epsy(idx + 1), data[f"/random/{i:d}/CurrentYieldRight"][...], )) self.assertTrue( np.all( mat.Find(Eps) == data[f"/random/{i:d}/CurrentIndex"][ ...]))
def test_Smooth_2d(self): shape = [2, 3] K = np.random.random(shape) G = np.random.random(shape) epsy = np.zeros(shape + [5]) epsy += np.array([-0.01, 0.01, 0.5, 1, 2]).reshape([1, 1, -1]) Eps = tensor.A4_ddot_B2( tensor.Array2d(shape).I4s, np.random.random(shape + [3, 3])) Eps[..., :, 2] = 0 Eps[..., 2, :] = 0 Eps[..., 0, 0] = -Eps[..., 1, 1] mat2d = GMat2d.Smooth2d(3 * K, 2 * G, epsy) mat3d = GMat.Smooth2d(K, G, epsy) mat2d.Eps = Eps[..., :2, :2] mat3d.Eps = Eps self.assertTrue(np.allclose(mat2d.Sig, mat3d.Sig[..., :2, :2])) self.assertTrue(np.allclose(mat2d.energy, mat3d.energy)) self.assertTrue(np.allclose(mat2d.epsp, mat3d.epsp)) self.assertTrue(np.allclose(mat2d.epsy_left, mat3d.epsy_left)) self.assertTrue(np.allclose(mat2d.epsy_right, mat3d.epsy_right))
def ComputePerturbation(sigma_star_test, trigger, mat, quad, vector, K, Solver): fext = vector.AllocateNodevec(0.0) disp = vector.AllocateNodevec(0.0) # pre-stress Sigstar = quad.AllocateQtensor(2, 0.0) for q in range(nip): Sigstar[trigger, q, :, :] = sigma_star_test Sigstar[trigger, q, :, :] = sigma_star_test # strain, stress, tangent Eps = quad.AllocateQtensor(2, 0.0) Sig = -Sigstar # residual force fe = quad.Int_gradN_dot_tensor2_dV(Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # solve disp = Solver.Solve(K, fres, disp) # post-process # ------------ ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) mat.setStrain(Eps) Sig = mat.Stress() return GMat.Deviatoric(Eps[trigger, 0]), disp, Eps, Sig
def test_Elastic(self): K = 12.3 G = 45.6 gamma = 0.02 epsm = 0.12 Eps = np.array([[epsm, gamma], [gamma, epsm]]) Sig = np.array([[K * epsm, G * gamma], [G * gamma, K * epsm]]) self.assertTrue(np.isclose(float(GMat.Epsd(Eps)), gamma)) mat = GMat.Elastic(K, G) mat.setStrain(Eps) self.assertTrue(np.allclose(mat.Stress(), Sig))
def test_tangent(self): shape = [2, 3] Eps = np.random.random(shape + [2, 2]) Eps = tensor.A4_ddot_B2(tensor.Array2d(shape).I4s, Eps) mat = GMat.Elastic2d(np.random.random(shape), np.random.random(shape)) mat.Eps = Eps self.assertTrue(np.allclose(tensor.A4_ddot_B2(mat.C, mat.Eps), mat.Sig))
def test_Array2d_refModel(self): K = 12.3 G = 45.6 gamma = 0.02 epsm = 0.12 Eps = np.array([[epsm, gamma], [gamma, epsm]]) Sig_elas = np.array([[K * epsm, G * gamma], [G * gamma, K * epsm]]) Sig_plas = np.array([[K * epsm, 0.0], [0.0, K * epsm]]) nelem = 3 nip = 2 mat = GMat.Array2d([nelem, nip]) I = np.zeros([nelem, nip], dtype="int") I[0, :] = 1 mat.setElastic(I, K, G) I = np.zeros([nelem, nip], dtype="int") I[1, :] = 1 mat.setCusp(I, K, G, 0.01 + 0.02 * np.arange(100)) I = np.zeros([nelem, nip], dtype="int") I[2, :] = 1 mat.setSmooth(I, K, G, 0.01 + 0.02 * np.arange(100)) for e in range(nelem): for q in range(nip): fac = float((e + 1) * nip + (q + 1)) if e == 0: model = mat.refElastic([e, q]) model.setStrain(fac * Eps) self.assertTrue(np.allclose(model.Stress(), fac * Sig_elas)) elif e == 1: model = mat.refCusp([e, q]) model.setStrain(fac * Eps) self.assertTrue(np.allclose(model.Stress(), fac * Sig_plas)) self.assertTrue(np.allclose(model.epsp(), fac * gamma)) elif e == 2: model = mat.refSmooth([e, q]) model.setStrain(fac * Eps) self.assertTrue(np.allclose(model.Stress(), fac * Sig_plas)) self.assertTrue(np.allclose(model.epsp(), fac * gamma))
def test_Array2d(self): K = 12.3 G = 45.6 gamma = 0.02 epsm = 0.12 Eps = np.array([[epsm, gamma], [gamma, epsm]]) Sig_elas = np.array([[K * epsm, G * gamma], [G * gamma, K * epsm]]) Sig_plas = np.array([[K * epsm, 0.0], [0.0, K * epsm]]) nelem = 3 nip = 2 mat = GMat.Array2d([nelem, nip]) ndim = 2 I = np.zeros([nelem, nip], dtype="int") I[0, :] = 1 mat.setElastic(I, K, G) I = np.zeros([nelem, nip], dtype="int") I[1, :] = 1 mat.setCusp(I, K, G, 0.01 + 0.02 * np.arange(100)) I = np.zeros([nelem, nip], dtype="int") I[2, :] = 1 mat.setSmooth(I, K, G, 0.01 + 0.02 * np.arange(100)) eps = np.zeros((nelem, nip, ndim, ndim)) sig = np.zeros((nelem, nip, ndim, ndim)) epsp = np.zeros((nelem, nip)) for e in range(nelem): for q in range(nip): fac = float((e + 1) * nip + (q + 1)) eps[e, q, :, :] = fac * Eps if e == 0: sig[e, q, :, :] = fac * Sig_elas epsp[e, q] = 0.0 else: sig[e, q, :, :] = fac * Sig_plas epsp[e, q] = fac * gamma mat.setStrain(eps) self.assertTrue(np.allclose(mat.Stress(), sig)) self.assertTrue(np.allclose(mat.Epsp(), epsp))
def test_eventDrivenSimpleShear(self): mesh = GooseFEM.Mesh.Quad4.Regular(3, 3) coor = mesh.coor() dofs = mesh.dofs() dofs[mesh.nodesLeftOpenEdge(), ...] = dofs[mesh.nodesRightOpenEdge(), ...] elastic = np.array([0, 1, 2, 6, 7, 8], dtype=np.uint64) plastic = np.array([3, 4, 5], dtype=np.uint64) epsy = 1e-3 * np.cumsum(np.ones((plastic.size, 5)), axis=1) system = FrictionQPotFEM.UniformSingleLayer2d.System( coor=coor, conn=mesh.conn(), dofs=dofs, iip=dofs[np.concatenate((mesh.nodesBottomEdge(), mesh.nodesTopEdge())), :].ravel(), elastic_elem=elastic, elastic_K=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, ) for loop in range(2): if loop == 0: system.initEventDrivenSimpleShear() delta_u = system.eventDriven_deltaU else: system.eventDriven_setDeltaU(delta_u) system.u = np.zeros_like(coor) directions = [1, 1, 1, 1, 1, 1, -1, -1, -1] kicks = [False, False, True, False, True, False, False, True, False] indices = [0, 0, 0, 1, 1, 2, 1, 1, 0] multi = [-1, -1, +1, -1, +1, -1, +1, -1, +1] for direction, kick, index, m in zip(directions, kicks, indices, multi): eps_expect = epsy[0, index] + m * 0.5 * 1e-4 system.eventDrivenStep(1e-4, kick, direction) self.assertTrue(np.allclose(GMat.Epsd(system.plastic.Eps), eps_expect)) self.assertTrue(system.residual() < 1e-5)
def test_Elastic_2d(self): shape = [2, 3] K = np.random.random(shape) G = np.random.random(shape) Eps = tensor.A4_ddot_B2( tensor.Array2d(shape).I4s, np.random.random(shape + [3, 3])) Eps[..., :, 2] = 0 Eps[..., 2, :] = 0 Eps[..., 0, 0] = -Eps[..., 1, 1] mat2d = GMat2d.Elastic2d(3 * K, 2 * G) mat3d = GMatElastic.Elastic2d(K, G) mat2d.Eps = Eps[..., :2, :2] mat3d.Eps = Eps self.assertTrue(np.allclose(mat2d.Sig, mat3d.Sig[..., :2, :2])) self.assertTrue(np.allclose(mat2d.energy, mat3d.energy))
def test_historic(self): """ A simple historic run. Thanks to prrng this test can be run on any platform, but also from any API (Python or C++). """ # Define a geometry N = 3**2 h = np.pi L = h * float(N) mesh = GooseFEM.Mesh.Quad4.Regular(N, 11, h) coor = mesh.coor() conn = mesh.conn() dofs = mesh.dofs() elem = mesh.elementgrid() height = [1.5 * h, 3.5 * h, 5.5 * h, 7.5 * h, 9.5 * h] active = [[False, False], [False, False], [True, False], [False, False], [True, False]] layers = [ elem[:3, :].ravel(), elem[3, :].ravel(), elem[4:7, :].ravel(), elem[7, :].ravel(), elem[8:, :].ravel(), ] layers = [np.sort(i) for i in layers] is_plastic = [False, True, False, True, False] left = mesh.nodesLeftOpenEdge() right = mesh.nodesRightOpenEdge() dofs[left] = dofs[right] mesh.nodesTopEdge() mesh.nodesBottomEdge() nelas = sum(i.size for i, p in zip(layers, is_plastic) if not p) nplas = sum(i.size for i, p in zip(layers, is_plastic) if p) c = 1.0 G = 1.0 K = 10.0 * G rho = G / c**2.0 qL = 2.0 * np.pi / L qh = 2.0 * np.pi / h alpha = np.sqrt(2.0) * qL * c * rho dt = 1.0 / (c * qh) / 10.0 generators = prrng.pcg32_array(np.arange(nplas), np.zeros(nplas)) epsy = np.hstack((generators.random([1]), generators.weibull([1000], k=2.0))) epsy *= 1.0e-3 epsy += 1.0e-5 epsy = np.cumsum(epsy, 1) system = FrictionQPotFEM.UniformMultiLayerLeverDrive2d.System( coor=coor, conn=conn, dofs=dofs, iip=dofs[mesh.nodesBottomEdge(), :].ravel(), elem=layers, node=[np.unique(conn[i, :]) for i in layers], layer_is_plastic=is_plastic, elastic_K=FrictionQPotFEM.moduli_toquad(K * np.ones(nelas)), elastic_G=FrictionQPotFEM.moduli_toquad(G * np.ones(nelas)), plastic_K=FrictionQPotFEM.moduli_toquad(K * np.ones(nplas)), plastic_G=FrictionQPotFEM.moduli_toquad(G * np.ones(nplas)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=dt, rho=rho, alpha=alpha, eta=0, drive_is_active=active, k_drive=1e-3, H=12 * h, hi=height, ) # Drive system.initEventDriven(0.1, active) nstep = 20 collect_Eps = np.zeros(nstep) collect_Sig = np.zeros(nstep) collect_Sig_plastic = np.zeros(nstep) dV = system.quad.AsTensor(2, system.dV) for step in range(nstep): if step % 2 == 0: system.eventDrivenStep(deps=1e-5, kick=True, iterative=True, yield_element=False) ret = system.minimise() self.assertTrue(ret == 0) else: system.eventDrivenStep(deps=1e-5, kick=False, iterative=True, yield_element=False) Epsbar = np.average(system.Eps(), weights=dV, axis=(0, 1)) Sigbar = np.average(system.Sig(), weights=dV, axis=(0, 1)) collect_Eps[step] = GMat.Epsd(Epsbar) collect_Sig[step] = GMat.Sigd(Sigbar) collect_Sig_plastic[step] = GMat.Sigd(np.mean(system.plastic.Sig, axis=(0, 1))) with h5py.File(os.path.splitext(__file__)[0] + ".h5") as file: self.assertTrue(np.allclose(collect_Eps, file["Eps"][...])) self.assertTrue(np.allclose(collect_Sig, file["Sig"][...])) self.assertTrue(np.allclose(collect_Sig_plastic, file["Sig_plastic"][...])) self.assertTrue(np.allclose(system.u, file["u_last"][...]))
def test_eventDrivenSimpleShear(self): """ Simple test of event driven simple shear in a homogeneous system: Load forward and backward (for the latter: test current implementation limitation). """ mesh = GooseFEM.Mesh.Quad4.Regular(3, 3) coor = mesh.coor() dofs = mesh.dofs() dofs[mesh.nodesLeftOpenEdge(), ...] = dofs[mesh.nodesRightOpenEdge(), ...] elastic = np.array([0, 1, 2, 6, 7, 8], dtype=np.uint64) plastic = np.array([3, 4, 5], dtype=np.uint64) epsy = np.cumsum(np.ones((plastic.size, 5)), axis=1) self.assertTrue( np.allclose(initelastic_allquad(epsy), FrictionQPotFEM.epsy_initelastic_toquad(epsy)) ) system = FrictionQPotFEM.Generic2d.System( coor=coor, conn=mesh.conn(), dofs=dofs, iip=dofs[np.concatenate((mesh.nodesBottomEdge(), mesh.nodesTopEdge())), :].ravel(), elastic_elem=elastic, elastic_K=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, ) self.assertEqual(system.rho, 1) self.assertEqual(system.alpha, 1) self.assertEqual(system.dt, 1) delta_u = np.zeros_like(coor) for i in range(delta_u.shape[0]): delta_u[i, 0] = 0.1 * (coor[i, 1] - coor[0, 1]) for loop in range(2): if loop == 0: system.eventDriven_setDeltaU(delta_u) delta_u = system.eventDriven_deltaU else: system.eventDriven_setDeltaU(delta_u) system.u = np.zeros_like(coor) settings = [ [+1, 0, 0, -1, 0], # : .| | | | [+1, 0, 0, -1, 0], # : .| | | | [+1, 1, 0, +1, 0], # : |. | | | [+1, 0, 1, -1, 0], # : | .| | | [+1, 1, 1, +1, 0], # : | |. | | [+1, 0, 2, -1, 0], # : | | .| | [+1, 1, 2, +1, 0], # : | | |. | [-1, 0, 2, +1, 0], # : | | |. | [-1, 1, 2, -1, 0], # : | | .| | [-1, 0, 1, +1, 0], # : | |. | | [-1, 1, 1, -1, 0], # : | .| | | [-1, 0, 0, +1, 0], # : |. | | | [-1, 1, 0, -1, 0], # : .| | | | [-1, 0, 0, -1, 1], # : .| | | | (symmetry, throw) [-1, 1, 0, +1, 1], # : |. | | | (symmetry, not tested) [-1, 0, 1, -1, 1], # : | .| | | (symmetry, not tested) ] for direction, kick, index, f, throw in settings: eps_expect = epsy[0, index] + f * 0.5 * 0.1 if throw: with self.assertRaises(IndexError): system.eventDrivenStep(0.1, kick, direction) break system.eventDrivenStep(0.1, kick, direction) self.assertTrue(np.allclose(GMat.Epsd(system.plastic.Eps), eps_expect)) self.assertTrue(system.residual() < 1e-5) self.assertTrue(np.all(system.plastic.i < system.plastic.epsy.shape[-1])) if index == 3: self.assertFalse(np.all(system.plastic.i < system.plastic.epsy.shape[-1]) - 3)
def test_eventDrivenSimpleShear_element(self): """ Like :py:func:`test_eventDrivenSimpleShear` but with slightly different yield strains per element. """ mesh = GooseFEM.Mesh.Quad4.Regular(3, 3) coor = mesh.coor() dofs = mesh.dofs() dofs[mesh.nodesLeftOpenEdge(), ...] = dofs[mesh.nodesRightOpenEdge(), ...] elastic = np.array([0, 1, 2, 6, 7, 8], dtype=np.uint64) plastic = np.array([3, 4, 5], dtype=np.uint64) epsy = np.cumsum(np.ones((plastic.size, 5)), axis=1) system = FrictionQPotFEM.Generic2d.System( coor=coor, conn=mesh.conn(), dofs=dofs, iip=dofs[np.concatenate((mesh.nodesBottomEdge(), mesh.nodesTopEdge())), :].ravel(), elastic_elem=elastic, elastic_K=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, ) delta_u = np.zeros_like(coor) for i in range(delta_u.shape[0]): delta_u[i, 0] = 0.1 * (coor[i, 1] - coor[0, 1]) for loop in range(2): if loop == 0: system.eventDriven_setDeltaU(delta_u) delta_u = system.eventDriven_deltaU else: system.eventDriven_setDeltaU(delta_u) system.u = np.zeros_like(coor) settings = [ [+1, 0, 0, -1, 0], # : .| | | | [+1, 0, 0, -1, 0], # : .| | | | [+1, 1, 0, +1, 0], # : |. | | | [+1, 0, 1, -1, 0], # : | .| | | [+1, 1, 1, +1, 0], # : | |. | | [+1, 0, 2, -1, 0], # : | | .| | [+1, 1, 2, +1, 0], # : | | |. | ] for direction, kick, index, f, throw in settings: if not kick: eps_expect = epsy[0, index] + f * 0.5 * 0.05 else: eps_expect = epsy[0, index] + f * 0.5 * 0.05 if throw: with self.assertRaises(IndexError): system.eventDrivenStep(0.05, kick, direction, yield_element=True) break system.eventDrivenStep(0.05, kick, direction, yield_element=True) self.assertTrue(np.allclose(GMat.Epsd(system.plastic.Eps), eps_expect)) self.assertTrue(system.residual() < 1e-5)
def test_basic(self): # ------------------------ # initialise configuration # ------------------------ # mesh # ---- # define mesh mesh = GooseFEM.Mesh.Quad4.FineLayer(21, 21) # mesh dimensions nelem = mesh.nelem mesh.nne mesh.ndim # mesh definitions coor = mesh.coor() conn = mesh.conn() dofs = mesh.dofs() # node sets nodesLft = mesh.nodesLeftOpenEdge() nodesRgt = mesh.nodesRightOpenEdge() nodesTop = mesh.nodesTopEdge() nodesBot = mesh.nodesBottomEdge() # element sets plastic = mesh.elementsMiddleLayer() elastic = np.setdiff1d(np.arange(nelem), plastic) # periodicity and fixed displacements DOFs # ---------------------------------------- dofs[nodesRgt, :] = dofs[nodesLft, :] dofs = GooseFEM.Mesh.renumber(dofs) iip = np.concatenate( (dofs[nodesBot, 0], dofs[nodesBot, 1], dofs[nodesTop, 0], dofs[nodesTop, 1])) # simulation variables # -------------------- # vector definition vector = GooseFEM.VectorPartitioned(conn, dofs, iip) # allocate system matrix K = GooseFEM.MatrixPartitioned(conn, dofs, iip) Solver = GooseFEM.MatrixPartitionedSolver() # nodal quantities disp = np.zeros(coor.shape) fint = np.zeros(coor.shape) fext = np.zeros(coor.shape) fres = np.zeros(coor.shape) # element/material definition # --------------------------- # element definition quad = GooseFEM.Element.Quad4.Quadrature(vector.AsElement(coor)) # material definition mat = GMat.Elastic2d(10 * np.ones([nelem, quad.nip]), np.ones([nelem, quad.nip])) # solve # ----- # strain, stress, tangent ue = vector.AsElement(disp) mat.Eps = quad.SymGradN_vector(ue) # stiffness matrix Ke = quad.Int_gradN_dot_tensor4_dot_gradNT_dV(mat.C) K.assemble(Ke) # residual force fe = quad.Int_gradN_dot_tensor2_dV(mat.Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # set fixed displacements disp[nodesTop, 0] = +5.0 disp[nodesTop, 1] = np.sin(np.linspace(0, 2.0 * np.pi, len(nodesTop)) - np.pi) disp[nodesBot, 1] = np.cos(np.linspace(0, 2.0 * np.pi, len(nodesBot)) - np.pi) # solve disp = Solver.Solve(K, fres, disp) # compute new state ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) mat.Eps = Eps Sig = np.copy(mat.Sig) # ---------------------- # Effect of perturbation # ---------------------- epsy = np.cumsum(np.ones(50 * plastic.size).reshape(plastic.size, -1), axis=0) sys = model.System( coor=coor, conn=conn, dofs=dofs, iip=iip, elastic_elem=elastic, elastic_K=10 * FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=10 * FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, ) modelTrigger = model.LocalTriggerFineLayerFull(sys) modelTrigger.setState(Eps, Sig, 0.5 * np.ones((len(plastic), 4)), 100) Barrier = [] for itrigger, trigger in enumerate(plastic): Sigstar_s = np.array([[0.0, +1.0], [+1.0, 0.0]]) Sigstar_p = np.array([[+1.0, 0.0], [0.0, -1.0]]) Epsstar_s, u_s, Eps_s, Sig_s = ComputePerturbation( Sigstar_s, trigger, mat, quad, vector, K, Solver) Epsstar_p, u_p, Eps_p, Sig_p = ComputePerturbation( Sigstar_p, trigger, mat, quad, vector, K, Solver) self.assertTrue(np.allclose(u_s, modelTrigger.u_s(itrigger))) self.assertTrue(np.allclose(u_p, modelTrigger.u_p(itrigger))) self.assertTrue(np.allclose(Eps_s, modelTrigger.Eps_s(itrigger))) self.assertTrue(np.allclose(Eps_p, modelTrigger.Eps_p(itrigger))) self.assertTrue(np.allclose(Sig_s, modelTrigger.Sig_s(itrigger))) self.assertTrue(np.allclose(Sig_p, modelTrigger.Sig_p(itrigger))) # Current state for triggered element Epsd = gtens.Deviatoric(Eps[trigger, 0]) gamma = Epsd[0, 1] E = Epsd[0, 0] # Find which (s, p) lie on the yield surface, # and to which energy change those perturbations lead Py, Sy = GetYieldSurface(E, gamma, Epsstar_p[0, 0], Epsstar_s[0, 1]) Ey = ComputeEnergy(Py, Sy, Eps, Sig, quad.dV, Eps_s, Sig_s, Eps_p, Sig_p, plastic[itrigger]) # Plot perturbed configuration smin = Sy.ravel()[np.argmin(Ey)] pmin = Py.ravel()[np.argmin(Ey)] Barrier += [np.min(Ey)] delta_u = pmin * u_p + smin * u_s self.assertTrue( np.allclose(delta_u, modelTrigger.delta_u(itrigger, 0))) Barrier = np.array(Barrier) self.assertTrue(np.allclose(Barrier, modelTrigger.barriers()[:, 0]))
# nodal quantities disp = np.zeros(coor.shape) fint = np.zeros(coor.shape) fext = np.zeros(coor.shape) fres = np.zeros(coor.shape) # element/material definition # --------------------------- # element definition quad = GooseFEM.Element.Quad4.Quadrature(vector.AsElement(coor)) nip = quad.nip() # material definition mat = GMat.Array2d([nelem, nip]) iden = np.zeros(mat.shape(), dtype="int") iden[elastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) iden = np.zeros(mat.shape(), dtype="int") iden[plastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) # solve # ----- # strain, stress, tangent ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue)
with h5py.File("Cartesian2d_random.hdf5", "w") as data: nelem = 1000 nip = 4 iden = 3.0 * np.random.random([nelem, nip]) iden = np.where(iden < 1.0, 0.0, iden) iden = np.where((iden >= 1.0) * (iden < 2.0), 1.0, iden) iden = np.where(iden >= 2.0, 2.0, iden) iden = iden.astype(np.int) shape = np.array([nelem, nip], np.int) data["/shape"] = shape mat = GMat.Array2d(shape) I = np.where(iden == 0, 1, 0).astype(np.int) n = np.sum(I) idx = np.zeros(I.size, np.int) idx[np.argwhere(I.ravel() == 1).ravel()] = np.arange(n) idx = idx.reshape(I.shape) epsy = np.cumsum(np.random.random([n, 500]), 1) K = np.ones(n) G = np.ones(n) data["/cusp/I"] = I data["/cusp/idx"] = idx data["/cusp/K"] = K data["/cusp/G"] = G data["/cusp/epsy"] = epsy
def test_main(self): with h5py.File("Cartesian2d_random.hdf5", "r") as data: shape = data["/shape"][...] i = np.eye(2) I = np.einsum("xy,ij", np.ones(shape), i) I4 = np.einsum("xy,ijkl->xyijkl", np.ones(shape), np.einsum("il,jk", i, i)) I4rt = np.einsum("xy,ijkl->xyijkl", np.ones(shape), np.einsum("ik,jl", i, i)) I4s = (I4 + I4rt) / 2.0 mat = GMat.Matrix(shape[0], shape[1]) I = data["/cusp/I"][...] idx = data["/cusp/idx"][...] K = data["/cusp/K"][...] G = data["/cusp/G"][...] epsy = data["/cusp/epsy"][...] mat.setCusp(I, idx, K, G, epsy) I = data["/smooth/I"][...] idx = data["/smooth/idx"][...] K = data["/smooth/K"][...] G = data["/smooth/G"][...] epsy = data["/smooth/epsy"][...] mat.setSmooth(I, idx, K, G, epsy) I = data["/elastic/I"][...] idx = data["/elastic/idx"][...] K = data["/elastic/K"][...] G = data["/elastic/G"][...] mat.setElastic(I, idx, K, G) for i in range(20): GradU = data[f"/random/{i:d}/GradU"][...] Eps = np.einsum("...ijkl,...lk->...ij", I4s, GradU) idx = mat.Find(Eps) self.assertTrue( np.allclose(mat.Stress(Eps), data[f"/random/{i:d}/Stress"][...])) self.assertTrue( np.allclose( mat.Epsy(idx), data[f"/random/{i:d}/CurrentYieldLeft"][...], )) self.assertTrue( np.allclose( mat.Epsy(idx + 1), data[f"/random/{i:d}/CurrentYieldRight"][...], )) self.assertTrue( np.all( mat.Find(Eps) == data[f"/random/{i:d}/CurrentIndex"][ ...]))
def test_eventDrivenSimpleShear(self): mesh = GooseFEM.Mesh.Quad4.Regular(nx=3, ny=2 * 3 + 1) coor = mesh.coor() conn = mesh.conn() elem = mesh.elementgrid() dofs = mesh.dofs() dofs[mesh.nodesLeftEdge()[1:], ...] = dofs[mesh.nodesRightEdge()[1:], ...] layers = [elem[:3, :].ravel(), elem[3, :].ravel(), elem[4:, :].ravel()] layers = [np.sort(i) for i in layers] is_plastic = [False, True, False] nelas = sum(i.size for i, p in zip(layers, is_plastic) if not p) nplas = sum(i.size for i, p in zip(layers, is_plastic) if p) epsy = 1e-3 * np.cumsum(np.ones((nplas, 5)), axis=1) system = FrictionQPotFEM.UniformMultiLayerIndividualDrive2d.System( coor=coor, conn=conn, dofs=dofs, iip=dofs[mesh.nodesBottomEdge(), :].ravel(), elem=layers, node=[np.unique(conn[i, :]) for i in layers], layer_is_plastic=is_plastic, elastic_K=FrictionQPotFEM.moduli_toquad(np.ones(nelas)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(nelas)), plastic_K=FrictionQPotFEM.moduli_toquad(np.ones(nplas)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(nplas)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, drive_is_active=np.ones((len(layers), 2)), k_drive=1e-3, ) drive_active = np.zeros((3, 2), dtype=bool) drive_u = np.zeros((3, 2), dtype=float) drive_active[-1, 0] = True drive_u[-1, 0] = 5.0 for loop in range(2): if loop == 0: system.initEventDriven(drive_u, drive_active) delta_active = system.eventDriven_targetActive delta_u = system.eventDriven_deltaU delta_ubar = system.eventDriven_deltaUbar else: system.initEventDriven(delta_ubar, delta_active, delta_u) system.u = np.zeros_like(coor) directions = [1, 1, 1, 1, 1, 1, -1, -1, -1] kicks = [ False, False, True, False, True, False, False, True, False ] indices = [0, 0, 0, 1, 1, 2, 1, 1, 0] multi = [-1, -1, +1, -1, +1, -1, +1, -1, +1] for direction, kick, index, m in zip(directions, kicks, indices, multi): eps_expect = epsy[0, index] + m * 0.5 * 1e-4 system.eventDrivenStep(1e-4, kick, direction) self.assertTrue( np.allclose(GMat.Epsd(system.plastic.Eps), eps_expect)) self.assertTrue(system.residual() < 1e-5)
def test_Cusp_Smooth(self): shape = [2, 3] K = np.random.random(shape) G = np.random.random(shape) epsy = np.zeros(shape + [4]) epsy += np.array([-0.01, 0.01, 0.03, 0.10]).reshape([1, 1, -1]) mat = GMat.Cusp2d(K, G, epsy) smooth = GMat.Smooth2d(K, G, epsy) gamma = 0.02 epsm = np.random.random(shape) mat.Eps[..., 0, 0] = epsm mat.Eps[..., 1, 1] = epsm mat.Eps[..., 0, 1] = gamma mat.Eps[..., 1, 0] = gamma mat.refresh() smooth.Eps = mat.Eps Sig = np.empty(shape + [2, 2]) Sig[..., 0, 0] = K * epsm Sig[..., 1, 1] = K * epsm Sig[..., 0, 1] = 0 Sig[..., 1, 0] = 0 self.assertTrue(np.allclose(GMat.Epsd(mat.Eps), gamma)) self.assertTrue(np.allclose(GMat.Sigd(mat.Sig), 0)) self.assertTrue(np.allclose(mat.Sig, Sig)) self.assertTrue(np.allclose(smooth.Sig, Sig)) self.assertTrue(np.all(mat.i == 1)) self.assertTrue(np.allclose(mat.epsp, 0.02)) self.assertTrue(np.allclose(mat.epsy_left, 0.01)) self.assertTrue(np.allclose(mat.epsy_right, 0.03)) self.assertTrue(np.allclose(mat.energy, K * epsm**2 - G * 0.01**2)) mat.epsy = np.zeros(shape + [3]) mat.epsy += np.array([0.01, 0.03, 0.10]).reshape([1, 1, -1]) self.assertTrue(np.allclose(GMat.Epsd(mat.Eps), gamma)) self.assertTrue(np.allclose(GMat.Sigd(mat.Sig), 0)) self.assertTrue(np.allclose(mat.Sig, Sig)) self.assertTrue(np.all(mat.i == 0)) self.assertTrue(np.allclose(mat.epsp, 0.02)) self.assertTrue(np.allclose(mat.epsy_left, 0.01)) self.assertTrue(np.allclose(mat.epsy_right, 0.03)) self.assertTrue(np.allclose(mat.energy, K * epsm**2 - G * 0.01**2)) mat.epsy = np.zeros(shape + [5]) mat.epsy += np.array([-0.01, 0.01, 0.03, 0.05, 0.10]).reshape([1, 1, -1]) gamma = 0.04 + 0.009 * np.random.random(shape) mat.Eps[..., 0, 1] = gamma mat.Eps[..., 1, 0] = gamma mat.refresh() Sig[..., 0, 1] = G * (gamma - 0.04) Sig[..., 1, 0] = G * (gamma - 0.04) self.assertTrue(np.allclose(GMat.Epsd(mat.Eps), gamma)) self.assertTrue( np.allclose(GMat.Sigd(mat.Sig), 2 * G * np.abs(gamma - 0.04))) self.assertTrue(np.allclose(mat.Sig, Sig)) self.assertTrue(np.all(mat.i == 2)) self.assertTrue(np.allclose(mat.epsp, 0.04)) self.assertTrue(np.allclose(mat.epsy_left, 0.03)) self.assertTrue(np.allclose(mat.epsy_right, 0.05)) self.assertTrue( np.allclose(mat.energy, K * epsm**2 + G * ((gamma - 0.04)**2 - 0.01**2))) mat.Eps *= 0 smooth.Eps *= 0 self.assertTrue(np.allclose(mat.Sig, 0 * Sig)) self.assertTrue(np.allclose(smooth.Sig, 0 * Sig)) self.assertTrue(np.allclose(mat.energy, -G * 0.01**2)) self.assertTrue( np.allclose(smooth.energy, -2 * G * (0.01 / np.pi)**2 * 2))
def ComputePerturbation(sigma_star_test): # mesh # ---- # define mesh mesh = GooseFEM.Mesh.Quad4.FineLayer(13, 13) # mesh dimensions nelem = mesh.nelem() # mesh definitions coor = mesh.coor() conn = mesh.conn() dofs = mesh.dofs() # node sets nodesLft = mesh.nodesLeftOpenEdge() nodesRgt = mesh.nodesRightOpenEdge() nodesTop = mesh.nodesTopEdge() nodesBot = mesh.nodesBottomEdge() # element sets plastic = mesh.elementsMiddleLayer() elastic = np.setdiff1d(np.arange(nelem), plastic) # periodicity and fixed displacements DOFs # ---------------------------------------- dofs[nodesRgt, :] = dofs[nodesLft, :] dofs = GooseFEM.Mesh.renumber(dofs) iip = np.concatenate( (dofs[nodesBot, 0], dofs[nodesBot, 1], dofs[nodesTop, 0], dofs[nodesTop, 1])) # simulation variables # -------------------- # vector definition vector = GooseFEM.VectorPartitioned(conn, dofs, iip) # allocate system matrix K = GooseFEM.MatrixPartitioned(conn, dofs, iip) Solver = GooseFEM.MatrixPartitionedSolver() # nodal quantities disp = np.zeros(coor.shape) fint = np.zeros(coor.shape) fext = np.zeros(coor.shape) fres = np.zeros(coor.shape) # element/material definition # --------------------------- # element definition quad = GooseFEM.Element.Quad4.Quadrature(vector.AsElement(coor)) nip = quad.nip() # material definition mat = GMat.Array2d([nelem, nip]) iden = np.zeros(mat.shape(), dtype="int") iden[elastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) iden = np.zeros(mat.shape(), dtype="int") iden[plastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) # solve # ----- # strain ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) # pre-stress trigger = plastic[int(len(plastic) / 2.0)] Sigstar = quad.AllocateQtensor(2, 0.0) for q in range(nip): Sigstar[trigger, q, :, :] = sigma_star_test Sigstar[trigger, q, :, :] = sigma_star_test # stress & tangent mat.setStrain(Eps) Sig = mat.Stress() - Sigstar C = mat.Tangent() # stiffness matrix Ke = quad.Int_gradN_dot_tensor4_dot_gradNT_dV(C) K.assemble(Ke) # residual force fe = quad.Int_gradN_dot_tensor2_dV(Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # solve disp = Solver.Solve(K, fres, disp) # post-process # ------------ ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) return ( GMat.Deviatoric(Eps[trigger, 0]), trigger, disp, coor, conn, vector, quad, mat, )
mat = {} # cusp I = np.where(iden == 0, 1, 0).astype(int) n = np.sum(I) idx = np.zeros(I.size, int) idx[np.argwhere(I.ravel() == 1).ravel()] = np.arange(n) idx = idx.reshape(I.shape) K = np.random.random(n) G = np.random.random(n) epsy = np.cumsum(np.random.random([n, 500]), 1) epsy[:, 0] = -epsy[:, 1] mat["Cusp1d"] = {"mat": GMat.Cusp1d(K, G, epsy), "is": iden == 0} data["/cusp/I"] = I data["/cusp/idx"] = idx data["/cusp/K"] = K data["/cusp/G"] = G data["/cusp/epsy"] = epsy data["/iden"] = iden # smooth I = np.where(iden == 1, 1, 0).astype(int) n = np.sum(I) idx = np.zeros(I.size, int) idx[np.argwhere(I.ravel() == 1).ravel()] = np.arange(n) idx = idx.reshape(I.shape)
def test_historic(self): """ A simple historic run. Thanks to prrng this test can be run on any platform, but also from any API (Python or C++). """ # Define a geometry N = 3**2 h = np.pi L = h * float(N) mesh = GooseFEM.Mesh.Quad4.FineLayer(N, N, h) coor = mesh.coor() conn = mesh.conn() dofs = mesh.dofs() plastic = mesh.elementsMiddleLayer() elastic = np.setdiff1d(np.arange(mesh.nelem), plastic) left = mesh.nodesLeftOpenEdge() right = mesh.nodesRightOpenEdge() dofs[left] = dofs[right] top = mesh.nodesTopEdge() bottom = mesh.nodesBottomEdge() iip = np.concatenate((dofs[bottom].ravel(), dofs[top].ravel())) c = 1.0 G = 1.0 K = 10.0 * G rho = G / c**2.0 qL = 2.0 * np.pi / L qh = 2.0 * np.pi / h alpha = np.sqrt(2.0) * qL * c * rho dt = 1.0 / (c * qh) / 10.0 generators = prrng.pcg32_array(np.arange(N), np.zeros(N)) epsy = np.hstack( (generators.random([1]), generators.weibull([1000], k=2.0))) epsy *= 1.0e-3 epsy += 1.0e-5 epsy = np.cumsum(epsy, 1) # Initialise system system = FrictionQPotFEM.Generic2d.System( coor=coor, conn=conn, dofs=dofs, iip=iip, elastic_elem=elastic, elastic_K=FrictionQPotFEM.moduli_toquad(K * np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(G * np.ones(elastic.size)), plastic_elem=plastic, plastic_K=FrictionQPotFEM.moduli_toquad(K * np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(G * np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=dt, rho=rho, alpha=alpha, eta=0, ) # Run dF = np.zeros((1001, 2, 2)) dF[1:, 0, 1] = 0.004 / 1000.0 collect_Eps = np.zeros(dF.shape[0]) collect_Sig = np.zeros(dF.shape[0]) collect_Sig_plastic = np.zeros(dF.shape[0]) dV = system.quad.AsTensor(2, system.dV) for step in range(dF.shape[0]): u = system.u for i in range(mesh.nnode): for j in range(mesh.ndim): for k in range(mesh.ndim): u[i, j] += dF[step, j, k] * (coor[i, k] - coor[0, k]) system.u = u ret = system.minimise(nmargin=5) self.assertTrue(ret == 0) Epsbar = np.average(system.Eps(), weights=dV, axis=(0, 1)) Sigbar = np.average(system.Sig(), weights=dV, axis=(0, 1)) collect_Eps[step] = GMat.Epsd(Epsbar) collect_Sig[step] = GMat.Sigd(Sigbar) collect_Sig_plastic[step] = GMat.Sigd( np.mean(system.plastic.Sig, axis=(0, 1))) with h5py.File(os.path.splitext(__file__)[0] + ".h5") as file: self.assertTrue(np.allclose(collect_Eps, file["Eps"][...])) self.assertTrue(np.allclose(collect_Sig, file["Sig"][...])) self.assertTrue( np.allclose(collect_Sig_plastic, file["Sig_plastic"][...])) self.assertTrue(np.allclose(system.u, file["u_last"][...]))
Eps_s = quad.SymGradN_vector(ue) mat.setStrain(Eps_s) Sig_s = mat.Stress() ue = vector.AsElement(u_p) Eps_p = quad.SymGradN_vector(ue) mat.setStrain(Eps_p) Sig_p = mat.Stress() # Current state ue = vector.AsElement(0 * u_p) Eps = quad.SymGradN_vector(ue) mat.setStrain(Eps) Sig = mat.Stress() Epsd = GMat.Deviatoric(Eps[trigger, 0]) gamma = Epsd[0, 1] E = Epsd[0, 0] # Find which (s, p) lie on the yield surface, and to which energy change those perturbations lead Py, Sy = GetYieldSurface(E, gamma, Epsstar_p[0, 0], Epsstar_s[0, 1]) Ey = ComputeEnergy(Py, Sy, Eps, Sig, quad.dV(), Eps_s, Sig_s, Eps_p, Sig_p) # Phase diagram for strain, stress, and energy # -------------------------------------------- dV = quad.dV() sig = np.zeros((201, 201)) eps = np.zeros(sig.shape) energy = np.zeros(sig.shape) P = np.linspace(-3, 3, sig.shape[0])