Skip to content
Snippets Groups Projects
Commit c699cf26 authored by Rostislav Chudoba's avatar Rostislav Chudoba
Browse files

fixed traitsui

parent b39572cc
No related branches found
No related tags found
No related merge requests found
......@@ -16,8 +16,8 @@ RUN conda env update -f /tmp/environment.yml && \
#
#RUN jupyter labextension install k3d@2.9.3
#
#RUN jupyter labextension install ipyregulartable@0.2.0
RUN jupyter labextension install ipyregulartable
#
#RUN jupyter labextension install @jupyter-widgets/jupyterlab-manager
#
#RUN jupyter labextension install k3d
RUN jupyter labextension install k3d
......@@ -19,5 +19,5 @@ dependencies:
- pip:
- bmcs-utils==0.0.31a0
- bmcs-ibvpy==0.0.19a0
- bmcs-cross-section==0.0.53a0
- bmcs-cross-section==0.0.54a0
- bmcs-beam==0.0.17a0
\ No newline at end of file
%% Cell type:markdown id: tags:
<a id="top"></a>
# **4.1: Loading, unloading and reloading**
%% Cell type:markdown id: tags:
[![title](../fig/bmcs_video.png)](https://moodle.rwth-aachen.de/mod/page/view.php?id=551829) part 1
%% Cell type:markdown id: tags:
<div style="background-color:lightgray;text-align:left"> <img src="../icons/start_flag.png" alt="Previous trip" width="40" height="40">
&nbsp; &nbsp; <b>Starting point</b> </div>
%% Cell type:markdown id: tags:
Once we have seen that there is a relation between the shape of the constitutive law and the stress redistribution process within a bond zone which has an immediate consequence on the shape of the pullout curve, we extend our horizon to the case of **non-monotonic loading**.
%% Cell type:markdown id: tags:
<div style="background-color:lightgray;text-align:left"> <img src="../icons/destination.png" alt="Previous trip" width="40" height="40">
&nbsp; &nbsp; <b>Where are we heading</b> </div>
%% Cell type:markdown id: tags:
To motivate a more general development of the model for the bond-slip behavior let us consider the case of non-monotonic loading. What happens in the material structure of the bond if the load is reduced and then it grows again?
%% Cell type:markdown id: tags:
# **Motivating examples**
%% Cell type:markdown id: tags:
Consider again the test double-sided pullout test introduced in [notebook 3.2](../tour3_nonlinear_bond/3_2_anchorage_length.ipynb#trc_pullout_study). Within this test series studying the nonlinear bond behavior of carbon fabrics, a loading scenario with introducing several **unloading and reloading steps** has been included for the specimen with the total length of 300 and 400 mm. The obtained measured response looked as follows
![image](../fig/test_unloading.png)
%% Cell type:markdown id: tags:
**Question:** Can the pullout models from tours 2 and 3 be used to describe such kind of behavior? What constitutive law can reproduce this kind of behavior?
**Answer:** The bond-slip laws presented so far only considered monotonically increasing load and cannot reproduce the real material behavior upon unloading.
The constant-bond slip model in Tour 2 and the multilinear bond-slip model exemplified in Tour 3 did not consider any change of behavior upon unloading.
To document this statement and to show how to introduce unloading and reloading into the interactive numerical models that we used in Tour 3, an example has been prepared showing how to introduce a more complex type of loading into the model.
%% Cell type:markdown id: tags:
<a id="trc_study_monotonic"></a>
### **Example 1:** TRC specimen with unloading
Let us reuse the geometrical, material and algorithmic parameters already specified in the
[case study on carbon fabric bond](../tour3_nonlinear_bond/3_2_anchorage_length.ipynb#case_study_1)
%% Cell type:code id: tags:
``` python
%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
from bmcs_cross_section.pullout import PullOutModel1D
po_trc = PullOutModel1D(n_e_x=100, w_max=3) # mm
po_trc.geometry.L_x=150 # [mm]
po_trc.time_line.step = 0.02
po_trc.cross_section.trait_set(A_m=1543, A_f=16.7, P_b=10)
po_trc.material_model='multilinear'
po_trc.material_model_.trait_set(
E_m=28000, E_f=170000,
s_data = '0, 0.1, 0.5, 1, 2, 3, 4.5, 6',
tau_data = '0, 5.4, 4.9, 5, 6, 7, 8.3, 9'
);
```
%% Cell type:markdown id: tags:
In addition, let us now change the `loading_scenario` to `cyclic` load.
Note that this polymorphic attribute changes the 'shadowed' object
which generates the time function for the scaling of the load. The
shadowed object representing the cyclic loading scenario can then
be accessed as an attribute `loading_scenario_`. It can be rendered
using the `interact` method, like any other model component in the
model tree
%% Cell type:code id: tags:
``` python
po_trc.loading_scenario = 'cyclic'
po_trc.loading_scenario_.interact()
po_trc.loading_scenario.profile = 'cyclic-nonsym-incr'
po_trc.loading_scenario.interact()
```
%% Output
xxxxx
%% Cell type:markdown id: tags:
The parameters of the loading scenario are now visible in the rendered window. They can be
assigned through the `trait_set` method.
%% Cell type:code id: tags:
``` python
po_trc.loading_scenario_.trait_set(number_of_cycles=2,
po_trc.loading_scenario.profile_.trait_set(number_of_cycles=1,
unloading_ratio=0.0,
numbe_of_increments=200,
amplitude_type='constant',
loading_range='non-symmetric');
numbe_of_increments=200);
```
%% Cell type:markdown id: tags:
The model can now be executed and rendered.
%% Cell type:code id: tags:
``` python
po_trc.reset()
po_trc.run()
po_trc.interact()
```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-30f7b3be9a30> in <module>
1 po_trc.run()
----> 2 po_trc.interact()
Warning: Update progress bar from model - not implemented yet
/opt/conda/lib/python3.8/site-packages/bmcs_utils/model.py in interact(self, **kw)
43
44 def interact(self,**kw):
---> 45 return AppWindow(self,**kw).interact()
46
47 def app(self,**kw):
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in interact(self)
133 layout=ipw.Layout(align_items="stretch",
134 width="100%"))
--> 135 self.model_tree.selected = True
136 display(app_print)
137
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in __set__(self, obj, value)
602 raise TraitError('The "%s" trait is read-only.' % self.name)
603 else:
--> 604 self.set(obj, value)
605
606 def _validate(self, obj, value):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in set(self, obj, value)
591 # we explicitly compare silent to True just in case the equality
592 # comparison above returns something other than True/False
--> 593 obj._notify_trait(self.name, old_value, new_value)
594
595 def __set__(self, obj, value):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in _notify_trait(self, name, old_value, new_value)
1215
1216 def _notify_trait(self, name, old_value, new_value):
-> 1217 self.notify_change(Bunch(
1218 name=name,
1219 old=old_value,
/opt/conda/lib/python3.8/site-packages/ipywidgets/widgets/widget.py in notify_change(self, change)
604 # Send new state to front-end
605 self.send_state(key=name)
--> 606 super(Widget, self).notify_change(change)
607
608 def __repr__(self):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in notify_change(self, change)
1225 def notify_change(self, change):
1226 """Notify observers of a change event"""
-> 1227 return self._notify_observers(change)
1228
1229 def _notify_observers(self, event):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in _notify_observers(self, event)
1262 c = getattr(self, c.name)
1263
-> 1264 c(event)
1265
1266 def _add_notifiers(self, handler, name, type):
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in select_node(self, event)
227 self.set_plot_backend(backend)
228 self.setup_plot(controller.model)
--> 229 self.update_plot(controller.model)
230
231 current_plot_backend = tr.Str
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in update_plot(self, model)
250 def update_plot(self, model):
251 pb = self.plot_backend_table[self.current_plot_backend]
--> 252 pb.update_plot(model)
253 pb.show_fig()
254
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in update_plot(self, model)
44 self.plot_fig.clf()
45 self.axes = model.subplots(self.plot_fig)
---> 46 model.update_plot(self.axes)
47
48 class K3DBackend(PlotBackend):
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in update_plot(self, axes)
934 self.history.plot_geo(ax_geo)
935 self.history.plot_Pw(ax_Pw)
--> 936 self.history.plot_G_t(ax_energy)
937 self.history.plot_dG_t(ax_dG_t)
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in plot_G_t(self, ax, label_U, label_W, color_U, color_W)
259 ax.plot(t, W_t, color=color_W, label=label_W)
260 ax.plot(t, U_bar_t, color=color_U, label=label_U)
--> 261 ax.plot(t, U_bar_t+self.G_omega_t, color='black', linestyle='dashed', label='G_t')
262 ax.fill_between(t, W_t, U_bar_t, facecolor='gray', alpha=0.3,
263 label='G(t)')
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in _get_G_omega_t(self)
178 A = xmodel.A
179 eps_tEms = self.get_eps_tEms(slice(0, None))
--> 180 _, D0_rs = mats.get_corr_pred(np.array([[0,0,0]]), 0,
181 kappa_n=np.array([0]), omega_n=np.array([0]))
182 w_ip = fets.ip_weights
TypeError: get_corr_pred() got an unexpected keyword argument 'kappa_n'
%% Cell type:markdown id: tags:
Apparently, there is no significant difference directly visible. However, if you browse through the history, it will be obvious that unloading is running along the same path as loading, which contradicts to the behavior observed in experiments.
%% Cell type:markdown id: tags:
### **Example 2:** CFRP with unloading
Even more evident demonstration of the non-physicality of the applied model can be provided by reusing the calibrated CFRP model. Let us apply the same loading scenario again
%% Cell type:code id: tags:
``` python
A_f = 16.67 # [mm^2]
A_m = 1540.0 # [mm^2]
p_b = 100.0 #
E_f = 170000 # [MPa]
E_m = 28000 # [MPa]
pm = PullOutModel1D()
pm.material_model = 'multilinear'
pm.material_model_.s_data = "0, 0.1, 0.4, 4"
pm.material_model_.tau_data = "0, 8, 0, 0"
pm.sim.tline.step = 0.01 # 100 time increments
pm.cross_section.trait_set(A_f=A_f, P_b=p_b, A_m=A_m)
pm.geometry.L_x = 300 # length of the specimen [mm]
pm.w_max = 1.8 # maximum control displacement [mm]
pm.n_e_x = 100 # number of finite elements
pm.loading_scenario = 'cyclic'
pm.loading_scenario_.trait_set(number_of_cycles=2,
unloading_ratio=0.0,
numbe_of_increments=200,
amplitude_type='constant',
loading_range='non-symmetric')
pm.run()
pm.interact()
```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-8fbd37e44f78> in <module>
20 loading_range='non-symmetric')
21 pm.run()
---> 22 pm.interact()
/opt/conda/lib/python3.8/site-packages/bmcs_utils/model.py in interact(self, **kw)
43
44 def interact(self,**kw):
---> 45 return AppWindow(self,**kw).interact()
46
47 def app(self,**kw):
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in interact(self)
133 layout=ipw.Layout(align_items="stretch",
134 width="100%"))
--> 135 self.model_tree.selected = True
136 display(app_print)
137
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in __set__(self, obj, value)
602 raise TraitError('The "%s" trait is read-only.' % self.name)
603 else:
--> 604 self.set(obj, value)
605
606 def _validate(self, obj, value):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in set(self, obj, value)
591 # we explicitly compare silent to True just in case the equality
592 # comparison above returns something other than True/False
--> 593 obj._notify_trait(self.name, old_value, new_value)
594
595 def __set__(self, obj, value):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in _notify_trait(self, name, old_value, new_value)
1215
1216 def _notify_trait(self, name, old_value, new_value):
-> 1217 self.notify_change(Bunch(
1218 name=name,
1219 old=old_value,
/opt/conda/lib/python3.8/site-packages/ipywidgets/widgets/widget.py in notify_change(self, change)
604 # Send new state to front-end
605 self.send_state(key=name)
--> 606 super(Widget, self).notify_change(change)
607
608 def __repr__(self):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in notify_change(self, change)
1225 def notify_change(self, change):
1226 """Notify observers of a change event"""
-> 1227 return self._notify_observers(change)
1228
1229 def _notify_observers(self, event):
/opt/conda/lib/python3.8/site-packages/traitlets/traitlets.py in _notify_observers(self, event)
1262 c = getattr(self, c.name)
1263
-> 1264 c(event)
1265
1266 def _add_notifiers(self, handler, name, type):
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in select_node(self, event)
227 self.set_plot_backend(backend)
228 self.setup_plot(controller.model)
--> 229 self.update_plot(controller.model)
230
231 current_plot_backend = tr.Str
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in update_plot(self, model)
250 def update_plot(self, model):
251 pb = self.plot_backend_table[self.current_plot_backend]
--> 252 pb.update_plot(model)
253 pb.show_fig()
254
/opt/conda/lib/python3.8/site-packages/bmcs_utils/app_window.py in update_plot(self, model)
44 self.plot_fig.clf()
45 self.axes = model.subplots(self.plot_fig)
---> 46 model.update_plot(self.axes)
47
48 class K3DBackend(PlotBackend):
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in update_plot(self, axes)
934 self.history.plot_geo(ax_geo)
935 self.history.plot_Pw(ax_Pw)
--> 936 self.history.plot_G_t(ax_energy)
937 self.history.plot_dG_t(ax_dG_t)
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in plot_G_t(self, ax, label_U, label_W, color_U, color_W)
259 ax.plot(t, W_t, color=color_W, label=label_W)
260 ax.plot(t, U_bar_t, color=color_U, label=label_U)
--> 261 ax.plot(t, U_bar_t+self.G_omega_t, color='black', linestyle='dashed', label='G_t')
262 ax.fill_between(t, W_t, U_bar_t, facecolor='gray', alpha=0.3,
263 label='G(t)')
/opt/conda/lib/python3.8/site-packages/bmcs_cross_section/pullout/pullout_sim.py in _get_G_omega_t(self)
178 A = xmodel.A
179 eps_tEms = self.get_eps_tEms(slice(0, None))
--> 180 _, D0_rs = mats.get_corr_pred(np.array([[0,0,0]]), 0,
181 kappa_n=np.array([0]), omega_n=np.array([0]))
182 w_ip = fets.ip_weights
TypeError: get_corr_pred() got an unexpected keyword argument 'kappa_n'
%% Cell type:markdown id: tags:
Browsing through the history will reveal that the debonded zone gets recovered upon unloading as the process zone travels back through the bond zone and the pullout tests gets completely healed once $w = 0$. This motivates the question: **How to introduce irreversible changes in the material structure** so that we reflect the physics behind the scenes in a correct way.
%% Cell type:markdown id: tags:
<a id="plasticity_and_damage"></a>
# **Physical explanation of the bond behavior**
%% Cell type:markdown id: tags:
[![title](../fig/bmcs_video.png)](https://moodle.rwth-aachen.de/mod/page/view.php?id=551829) part 2
%% Cell type:markdown id: tags:
Regarding a small segment of the bond interface with a nearly constant shear stress $\tau$ and constant
slip $s$ let us try to describe the correspondence between the micro- and meso-scopic mechanisms that actually govern
bond-slip relation $\tau(s)$. To classify the elementary mechanisms behind the observed bond behavior, let us can idealize
the material structure of the bond using two types of bindings:
- as a **series of elastic springs** that can break once they achieve their strength, and
- as a **series of asperities** representing an unevenness or roughness of the surface area.
Sliding of these surfaces is accompanied with a stress required to cross over the asperities. During this process the asperities can deform elastically or get abraded.
With this simple image of the material interface we can try to associate the structure of the bond layer with the basic types of inelastic material behavior, namely, damage and plasticity. In most cases both types of material behavior occur. The question is, how to distinguish and quantify them.
%% Cell type:markdown id: tags:
**Damage:** Consider an infinitesimal material point of the interface exhibiting softening response upon monotonic loading. Upon unloading, this material point would unload to origin. This behavior can be reproduced by an idealization of the material point as a series of elastic springs. Assuming further a scatter of spring strength, the failure of one spring upon increasing slip displacement $s$ leads to the reduction of the bond stiffness and overall stress level $\tau$. Since all the remaining springs are elastic, they would all unload to the origin.
%% Cell type:markdown id: tags:
![damage](../fig/damage.png)
%% Cell type:markdown id: tags:
**Plasticity:**
On the other hand, if a bond stress is transferred by asperities, we can distinguish two phases of response. Before the stress necessary to skip over an asperity has been reached, the slip is zero. At the onset of sliding over the asperities, the slip can increase at constant level of stress. Once the stress level is reduced, the slip does not change. Or putting it differently, the stress needed to induce sliding over the surface remains constant. Once the sliding direction is changed, also the sign of the shear stress must change. The described type of behavior is referred to as ideally plastic. This kind of material response is shown as the curve (2)
![plasticity](../fig/plasticity.png)
If asperities can deform before reaching the onset of sliding, an elastic deformation can be observed as indicated
by the curve (3).
%% Cell type:markdown id: tags:
**Interactions:** Usually, both damage and plasticity encounter simultaneously in the material behavior. Both introduce energy dissipation. While damage is connected with the reduction of the material stiffness, plasticity leads to permanent deformation after unloading of the structure. To understand the effect of damage and plasticity at the level of a material point, we will construct simple models that can be used within the BMCS interactive sheets to understand the two types of material behavior in detail.
%% Cell type:markdown id: tags:
Corresponding to this classification, we will address the two categories of behavior in a more
detailed way:
1. starting with interactive studies for non-monotonic loading scenarios,
2. providing a mathematical framework for the description of plasticity and damage exemplified for the bond-behavior at a material point level
3. studying the effect of plasticity and damage at the structural level using pullout tests.
%% Cell type:markdown id: tags:
<div style="background-color:lightgray;text-align:left;width:45%;display:inline-table;"> <img src="../icons/previous.png" alt="Previous trip" width="50" height="50">
&nbsp; <a href="../tour3_nonlinear_bond/3_2_anchorage_length.ipynb#top">3.2 Anchorage length</a>
</div><div style="background-color:lightgray;text-align:center;width:10%;display:inline-table;"> <a href="#top"><img src="../icons/compass.png" alt="Compass" width="50" height="50"></a></div><div style="background-color:lightgray;text-align:right;width:45%;display:inline-table;">
<a href="4_2_BS_EP_SH_I_A.ipynb#top">4.2 Basic concept of plasticity</a>&nbsp; <img src="../icons/next.png" alt="Previous trip" width="50" height="50"> </div>
%% Cell type:code id: tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment