.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/mechanical/EPJCK.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_mechanical_EPJCK.py: Johnson-Cook plasticity: strain-rate sensitivity ================================================== .. GENERATED FROM PYTHON SOURCE LINES 5-170 .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/mechanical/images/sphx_glr_EPJCK_001.png :alt: Strain rate sensitivity (Johnson-Cook, AISI 4340), Dissipated work :srcset: /examples/mechanical/images/sphx_glr_EPJCK_001.png :class: sphx-glr-multi-img * .. image-sg:: /examples/mechanical/images/sphx_glr_EPJCK_002.png :alt: EPJCK :srcset: /examples/mechanical/images/sphx_glr_EPJCK_002.png :class: sphx-glr-multi-img .. code-block:: Python import os import numpy as np import matplotlib.pyplot as plt import simcoon as sim plt.rcParams["figure.figsize"] = (18, 10) plt.rc("text", usetex=True) plt.rc("font", family="serif") # ################################################################################### # The Johnson-Cook constitutive law (EPJCK) is a von Mises elastic-viscoplastic material whose # yield stress depends on the accumulated plastic strain, on the plastic strain rate and on the # temperature (Johnson and Cook, 1983): # # .. math:: # # \sigma_Y & = \left(A + B\,p^{n}\right)\left(1 + C\,\ln\frac{\dot{p}}{\dot{\varepsilon}_0}\right) # \left(1 - T^{*m}\right), \quad T^{*} = \frac{T - T_{\textrm{ref}}}{T_{\textrm{melt}} - T_{\textrm{ref}}} \\\\ # \Phi & = \overline{\sigma} - \sigma_Y \leq 0, \quad # \dot{\varepsilon}^{\textrm{p}}_{ij} = \dot{p}\,\Lambda_{ij}, \quad \dot{p} \geq 0, ~~~ \dot{p}\,\Phi = 0 # # Eleven parameters are required: # # 1. The Young modulus :math:`E` # 2. The Poisson ratio :math:`\nu` # 3. The coefficient of thermal expansion :math:`\alpha` # 4. The initial yield stress :math:`A` # 5. The hardening coefficient :math:`B` # 6. The hardening exponent :math:`n` # 7. The strain-rate sensitivity :math:`C` # 8. The reference strain rate :math:`\dot{\varepsilon}_0` # 9. The thermal softening exponent :math:`m` # 10. The reference temperature :math:`T_{\textrm{ref}}` # 11. The melting temperature :math:`T_{\textrm{melt}}` # # The plastic strain rate is treated fully implicitly over the increment, # :math:`\dot{p} = \Delta p / \Delta t`, inside the convex cutting plane return mapping, and the # rate factor is clamped at 1 below :math:`\dot{\varepsilon}_0`. The 9 state variables are the # initial temperature, :math:`p`, the plastic strain tensor and the plastic strain rate of the # last increment. # # Parameters of AISI 4340 steel (Johnson and Cook, 1983): umat_name = "EPJCK" # This is the 5 character code for the Johnson-Cook subroutine nstatev = 9 E = 200000.0 # Young's modulus (MPa) nu = 0.33 # Poisson's ratio alpha = 1.0e-5 # CTE A_jc = 792.0 # initial yield stress (MPa) B_jc = 510.0 # hardening coefficient (MPa) n_jc = 0.26 # hardening exponent C_jc = 0.014 # strain-rate sensitivity edot0 = 1.0 # reference strain rate (1/s) m_jc = 1.03 # thermal softening exponent T_ref = 293.0 # reference temperature (K) T_melt = 1793.0 # melting temperature (K) psi_rve = 0.0 theta_rve = 0.0 phi_rve = 0.0 solver_type = 0 corate_type = 3 props = np.array([E, nu, alpha, A_jc, B_jc, n_jc, C_jc, edot0, m_jc, T_ref, T_melt]) path_data = "../data" # ################################################################################### # Strain-rate sensitivity # -------------------------------------- # The same 10 % tension is applied over 10 s, 1 s and 1 ms, i.e. at strain rates of # :math:`10^{-2}`, :math:`10^{-1}` and :math:`10^{2}` s\ :math:`^{-1}`. The first two sit below # the reference rate :math:`\dot{\varepsilon}_0 = 1` s\ :math:`^{-1}`, where the rate factor is # clamped at 1, so they coincide; the fast one hardens by the logarithmic factor. Every path is # read in Python and the case runs in memory. rate_configs = { "slow": {"pathfile": "EPJCK_path_slow.json", "label": r"$\dot{\varepsilon} = 10^{-2}$ s$^{-1}$"}, "medium": {"pathfile": "EPJCK_path.json", "label": r"$\dot{\varepsilon} = 10^{-1}$ s$^{-1}$"}, "fast": {"pathfile": "EPJCK_path_fast.json", "label": r"$\dot{\varepsilon} = 10^{2}$ s$^{-1}$"}, } colors = {"slow": "blue", "medium": "black", "fast": "red"} results = {} for key, cfg in rate_configs.items(): blocks, T_init, _ = sim.solver.load_path_json(os.path.join(path_data, cfg["pathfile"])) results[key] = sim.solver.solve( blocks, umat_name, props, nstatev, T_init=T_init, solver_type=solver_type, corate=corate_type, orientation=(psi_rve, theta_rve, phi_rve), ) fig = plt.figure() ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) for key, cfg in rate_configs.items(): res = results[key] e11 = res["Strain"][0] s11 = res["Stress"][0] time = res["Time"] Wm_d = res["Wm"][3] # the medium path carries a reverse / reload cycle: plot only its first step n = len(e11) if key != "medium" else np.argmax(e11) + 1 ax1.plot(e11[:n], s11[:n], c=colors[key], label=cfg["label"]) ax2.plot(time[:n] / time[n - 1], Wm_d[:n], c=colors[key], label=cfg["label"]) ax1.set_xlabel(r"Strain $\varepsilon_{11}$", size=15) ax1.set_ylabel(r"Stress $\sigma_{11}$ (MPa)", size=15) ax1.set_title("Strain rate sensitivity (Johnson-Cook, AISI 4340)", size=15) ax1.grid(True) ax1.legend(loc="best", fontsize=12) ax1.tick_params(axis="both", which="major", labelsize=15) ax2.set_xlabel("normalized time $t / t_{\\textrm{end}}$", size=15) ax2.set_ylabel(r"Dissipated work $W_m^d$ (mJ/mm$^3$)", size=15) ax2.set_title("Dissipated work", size=15) ax2.grid(True) ax2.legend(loc="best", fontsize=12) ax2.tick_params(axis="both", which="major", labelsize=15) plt.tight_layout() plt.show() # ################################################################################### # Reverse loading at the reference rate # -------------------------------------- # The medium-rate path continues with a compression to -10 % and a reload to +10 %. The # hardening is isotropic, so the flow stress keeps growing with :math:`p` on each reversal. res = results["medium"] e11 = res["Strain"][0] s11 = res["Stress"][0] time = res["Time"] Wm, Wm_r, Wm_ir, Wm_d = res["Wm"] p = res["Statev"][1] fig = plt.figure() ax = fig.add_subplot(1, 2, 1) plt.grid(True) plt.tick_params(axis="both", which="major", labelsize=15) plt.xlabel(r"Strain $\varepsilon_{11}$", size=15) plt.ylabel(r"Stress $\sigma_{11}$ (MPa)", size=15) plt.plot(e11, s11, c="black", label="direction 1") plt.legend(loc=2) ax = fig.add_subplot(1, 2, 2) plt.grid(True) plt.tick_params(axis="both", which="major", labelsize=15) plt.xlabel("time (s)", size=15) plt.ylabel(r"$W_m$ (mJ/mm$^3$)", size=15) plt.plot(time, Wm, c="black", label=r"$W_m$") plt.plot(time, Wm_r, c="green", label=r"$W_m^r$") plt.plot(time, Wm_ir, c="blue", label=r"$W_m^{ir}$") plt.plot(time, Wm_d, c="red", label=r"$W_m^d$") plt.legend(loc=2) plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 4.929 seconds) .. _sphx_glr_download_examples_mechanical_EPJCK.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: EPJCK.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: EPJCK.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: EPJCK.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_