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_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_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"][...]))
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"][...]))
# 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) # Plot perturbed configuration smin = Sy.ravel()[np.argmin(Ey)] pmin = Py.ravel()[np.argmin(Ey)] Barrier += [np.min(Ey)] u = disp + pmin * u_p + smin * u_s ue = vector.AsElement(u) mat.setStrain(quad.SymGradN_vector(ue)) sigeq = GMat.Sigd( np.average(mat.Stress(), weights=quad.AsTensor(2, quad.dV()), axis=1)) fig, ax = plt.subplots() gplt.patch(coor=coor + u, conn=conn, cindex=sigeq, cmap="Reds", axis=ax, clim=(0, 1.0)) ax.axis("equal") plt.axis("off") fig.savefig(f"example_layer_config-perturbed_{itrigger:d}.pdf") plt.close(fig)
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]) S = np.linspace(-3, 3, sig.shape[1]) E0 = np.average(0.5 * gtens.A2_ddot_B2(Sig, Eps), weights=dV) * np.sum(dV) for i, p in enumerate(P): for j, s in enumerate(S): Eps_n = Eps + s * Eps_s + p * Eps_p Sig_n = Sig + s * Sig_s + p * Sig_p sig[i, j] = GMat.Sigd(Sig_n[trigger, 0]) eps[i, j] = GMat.Epsd(Eps_n[trigger, 0]) energy[i, j] = ( np.average(0.5 * gtens.A2_ddot_B2(Sig_n, Eps_n), weights=dV) * np.sum(dV) - E0) # Plot phase diagram - stress fig, ax = plt.subplots() h = ax.imshow(sig, cmap="jet", extent=[np.min(P), np.max(P), np.min(S), np.max(S)]) ax.plot([0, 0], [P[0], P[-1]], c="w", lw=1)
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))
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]) S = np.linspace(-3, 3, sig.shape[1]) E0 = np.average(0.5 * gtens.A2_ddot_B2(Sig, Eps), weights=dV) * np.sum(dV) for i, p in enumerate(P): for j, s in enumerate(S): Eps_n = Eps + s * Eps_s + p * Eps_p Sig_n = Sig + s * Sig_s + p * Sig_p sig[i, j] = GMat.Sigd(Sig_n[trigger, 0]) eps[i, j] = GMat.Epsd(Eps_n[trigger, 0]) energy[i, j] = ( np.average(0.5 * gtens.A2_ddot_B2(Sig_n, Eps_n), weights=dV) * np.sum(dV) - E0) dEps = s * Eps_s + p * Eps_p dSig = s * Sig_s + p * Sig_p disp = s * u_s + p * u_p ue = vector.AsElement(disp) mat.setStrain(Eps_n) assert np.allclose(Eps_n, quad.SymGradN_vector(ue)) assert np.allclose(Sig_n, mat.Stress()) assert np.isclose(energy[i, j] + E0,