FrictionQPotFEM 0.23.3
Loading...
Searching...
No Matches
UniformMultiLayerLeverDrive2d.h
Go to the documentation of this file.
1
7#ifndef FRICTIONQPOTFEM_UNIFORMMULTILAYERLEVERDRIVE2D_H
8#define FRICTIONQPOTFEM_UNIFORMMULTILAYERLEVERDRIVE2D_H
9
11#include "config.h"
12
13namespace FrictionQPotFEM {
14
22namespace UniformMultiLayerLeverDrive2d {
23
27inline std::vector<std::string> version_dependencies()
28{
30}
31
35inline std::vector<std::string> version_compiler()
36{
38}
39
49
50private:
52
53public:
54 System() = default;
55
56 virtual ~System(){};
57
87 const std::vector<array_type::tensor<size_t, 1>>& elem,
88 const std::vector<array_type::tensor<size_t, 1>>& node,
89 const array_type::tensor<bool, 1>& layer_is_plastic,
90 const array_type::tensor<double, 2>& elastic_K,
91 const array_type::tensor<double, 2>& elastic_G,
92 const array_type::tensor<double, 2>& plastic_K,
93 const array_type::tensor<double, 2>& plastic_G,
94 const array_type::tensor<double, 3>& plastic_epsy,
95 double dt,
96 double rho,
97 double alpha,
98 double eta,
99 const array_type::tensor<bool, 2>& drive_is_active,
100 double k_drive,
101 double H,
103 {
104 this->init(
105 coor,
106 conn,
107 dofs,
108 iip,
109 elem,
110 node,
111 layer_is_plastic,
112 elastic_K,
113 elastic_G,
114 plastic_K,
115 plastic_G,
116 plastic_epsy,
117 dt,
118 rho,
119 alpha,
120 eta,
121 drive_is_active,
122 k_drive);
123
124 using size_type = typename decltype(m_lever_hi)::size_type;
125 std::array<size_type, 1> shape = {static_cast<size_type>(m_n_layer)};
126
127 m_lever_hi.resize(shape);
128 m_lever_hi.fill(0.0);
129
130 m_lever_hi_H.resize(shape);
131 m_lever_hi_H.fill(0.0);
132
133 m_lever_hi_H_2.resize(shape);
134 m_lever_hi_H_2.fill(0.0);
135
136 m_lever_H = 0.0;
137 m_lever_target = 0.0;
138 m_lever_u = 0.0;
139
140 this->setLeverProperties(H, hi);
141 }
142
143public:
144 std::string type() const override
145 {
146 return "FrictionQPotFEM.UniformMultiLayerLeverDrive2d.System";
147 }
148
156 template <class T>
157 void setLeverProperties(double H, const T& hi)
158 {
159 FRICTIONQPOTFEM_ASSERT(xt::has_shape(hi, m_lever_hi.shape()));
160 m_lever_hi = hi;
161 m_lever_H = H;
162
163 m_lever_hi_H = m_lever_hi / H;
164 m_lever_hi_H_2 = xt::pow(m_lever_hi / H, 2.0);
165
166 this->updated_u(); // updates forces
167 }
168
174 void setLeverTarget(double xdrive)
175 {
176 m_lever_target = xdrive;
177 this->updated_u(); // updates target average displacement per layer, and forces
178 }
179
185 double leverTarget() const
186 {
187 return m_lever_target;
188 }
189
195 double leverPosition() const
196 {
197 return m_lever_u;
198 }
199
214 template <class T>
215 void initEventDriven(double xlever, const T& active)
216 {
218 FRICTIONQPOTFEM_ASSERT(xt::has_shape(active, m_layerdrive_active.shape()));
219
220 // backup system
221
222 auto u0 = m_u;
223 auto v0 = m_v;
224 auto a0 = m_a;
225 auto active0 = m_layerdrive_active;
226 auto ubar0 = m_layerdrive_targetubar;
227 auto xdrive0 = m_lever_target;
228 auto inc0 = m_inc;
229
231 array_type::tensor<double, 3> rigid = xt::empty<double>({m_nelem_plas, m_nip, size_t(2)});
232
233 double infty = std::numeric_limits<double>::max();
234
235 for (size_t e = 0; e < m_nelem_plas; ++e) {
236 for (size_t q = 0; q < m_nip; ++q) {
237 rigid(e, q, 0) = -infty;
238 rigid(e, q, 1) = infty;
239 }
240 }
241
242 m_plas.set_epsy(rigid);
243
244 // perturbation
245
246 m_u.fill(0.0);
247 m_v.fill(0.0);
248 m_a.fill(0.0);
249 this->updated_u();
250 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(m_plas.i(), 0)));
251 this->layerSetTargetActive(active);
252 this->setLeverTarget(xlever);
253 this->minimise(0);
254 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(m_plas.i(), 0)));
255 auto up = m_u;
256 m_u.fill(0.0);
257
258 // restore yield strains
259
260 m_plas.set_epsy(epsy0);
261
262 // store result
263
264 auto c = this->eventDriven_setDeltaU(up);
267 m_pert_lever_target = c * xlever;
268
269 // restore system
270
271 this->setU(u0);
272 this->setV(v0);
273 this->setA(a0);
274 this->layerSetTargetActive(active0);
275 this->layerSetTargetUbar(ubar0);
276 this->setLeverTarget(xdrive0);
277 this->setInc(inc0);
278 }
279
288 template <class T, class U, class W>
289 double initEventDriven(double xlever, const T& active, const U& delta_u, const W& delta_ubar)
290 {
291 FRICTIONQPOTFEM_ASSERT(xt::has_shape(delta_ubar, m_layerdrive_targetubar.shape()));
292 FRICTIONQPOTFEM_ASSERT(xt::has_shape(active, m_layerdrive_active.shape()));
293 FRICTIONQPOTFEM_ASSERT(xt::has_shape(delta_u, m_u.shape()));
294 double c = this->eventDriven_setDeltaU(delta_u);
296 m_pert_layerdrive_targetubar = c * delta_ubar;
297 m_pert_lever_target = c * xlever;
298 return c;
299 }
300
302 double deps,
303 bool kick,
304 int direction = +1,
305 bool yield_element = false,
306 bool fallback = false) override
307 {
308 double c =
309 Generic2d::System::eventDrivenStep(deps, kick, direction, yield_element, fallback);
311 this->setLeverTarget(m_lever_target + c * m_pert_lever_target);
312 return c;
313 }
314
321 {
322 return m_pert_lever_target;
323 }
324
325protected:
331 void updated_u() override
332 {
334
335 // Position of the lever based on equilibrium
336
337 m_lever_u = m_lever_target;
338 double n = 1.0;
339
340 for (size_t i = 0; i < m_n_layer; ++i) {
341 if (m_layerdrive_active(i, 0)) {
342 m_lever_u += m_layer_ubar(i, 0) * m_lever_hi_H(i);
343 n += m_lever_hi_H_2(i);
344 }
345 }
346
347 m_lever_u /= n;
348
349 // Update position of driving springs
350
351 for (size_t i = 0; i < m_n_layer; ++i) {
352 if (m_layerdrive_active(i, 0)) {
353 m_layerdrive_targetubar(i, 0) = m_lever_hi_H(i) * m_lever_u;
354 }
355 }
356
357 // Update forces
359 this->computeForceMaterial();
360 }
361
362private:
363 double m_lever_H;
365 array_type::tensor<double, 1> m_lever_hi_H;
366 array_type::tensor<double, 1> m_lever_hi_H_2;
367 double m_lever_target;
368 double m_lever_u;
369 double m_pert_lever_target;
370};
371
372} // namespace UniformMultiLayerLeverDrive2d
373} // namespace FrictionQPotFEM
374
375#endif
long minimise(size_t nmargin=0, double tol=1e-5, size_t niter_tol=20, size_t max_iter=1e7, bool time_activity=false, bool max_iter_is_error=true)
Minimise energy: run System::timeStep until a mechanical equilibrium has been reached.
Definition: Generic2d.h:1868
double eta() const
Get the damping at the interface.
Definition: Generic2d.h:478
double rho() const
Mass density.
Definition: Generic2d.h:406
void setV(const T &v)
Overwrite nodal velocities.
Definition: Generic2d.h:601
GMatElastoPlasticQPot::Cartesian2d::Cusp< 2 > m_plas
Material for plastic el.
Definition: Generic2d.h:2096
array_type::tensor< double, 2 > m_a
Nodal accelerations.
Definition: Generic2d.h:2114
double eventDriven_setDeltaU(const T &delta_u, bool autoscale=true)
Set purely elastic and linear response to specific boundary conditions.
Definition: Generic2d.h:1234
size_t m_inc
Current increment (current time = m_dt * m_inc).
Definition: Generic2d.h:2138
void setU(const T &u)
Overwrite nodal displacements.
Definition: Generic2d.h:586
array_type::tensor< double, 2 > m_v
Nodal velocities.
Definition: Generic2d.h:2112
const auto & coor() const
Nodal coordinates.
Definition: Generic2d.h:708
void computeForceMaterial()
Update m_fmaterial based on the current displacement field m_u.
Definition: Generic2d.h:1179
virtual void setInc(size_t arg)
Set increment.
Definition: Generic2d.h:918
const auto & conn() const
Connectivity.
Definition: Generic2d.h:698
double dt() const
Get time step.
Definition: Generic2d.h:566
array_type::tensor< double, 2 > m_u
Nodal displacements.
Definition: Generic2d.h:2104
const auto & dofs() const
DOFs per node.
Definition: Generic2d.h:718
bool isHomogeneousElastic() const
Check if elasticity is homogeneous.
Definition: Generic2d.h:554
virtual double eventDrivenStep(double deps, bool kick, int direction=1, bool yield_element=false, bool iterative=false)
Add event driven step for the boundary conditions that correspond to the displacement perturbation se...
Definition: Generic2d.h:1300
double alpha() const
Background damping density.
Definition: Generic2d.h:507
void setA(const T &a)
Overwrite nodal accelerations.
Definition: Generic2d.h:615
size_t m_nip
Number of integration points.
Definition: Generic2d.h:2084
size_t m_nelem_plas
Number of plastic elements.
Definition: Generic2d.h:2080
System that comprises several layers (elastic or plastic).
array_type::tensor< bool, 2 > m_pert_layerdrive_active
Event driven: applied lever setting.
void layerSetTargetUbar(const T &ubar)
Overwrite the target average displacement per layer.
void computeLayerUbarActive()
Compute the average displacement of all layers with an active driving spring.
void layerSetTargetActive(const T &active)
Turn on (or off) springs connecting the average displacement of a layer ("ubar") to its set target va...
void computeForceFromTargetUbar()
Compute force deriving from the activate springs between the average displacement of the layer and it...
array_type::tensor< bool, 2 > m_layerdrive_active
See prescribe in layerSetTargetUbar()
array_type::tensor< double, 2 > m_layer_ubar
See computeLayerUbarActive().
array_type::tensor< double, 2 > m_pert_layerdrive_targetubar
Event driven: applied lever setting.
array_type::tensor< double, 2 > m_layerdrive_targetubar
Per layer, the prescribed average position.
double initEventDriven(const S &ubar, const T &active)
Initialise the event driven protocol by applying a perturbation to the loading springs and computing ...
Similar to UniformMultiLayerIndividualDrive2d::System(), but with the difference that the target aver...
double leverPosition() const
Get the current lever 'position'.
double eventDrivenStep(double deps, bool kick, int direction=+1, bool yield_element=false, bool fallback=false) override
Add event driven step for the boundary conditions that correspond to the displacement perturbation se...
double leverTarget() const
Get the current target lever 'position'.
void setLeverTarget(double xdrive)
Overwrite the target 'position' of the spring pulling the lever.
double eventDriven_deltaLeverPosition() const
Get target 'position' of the spring pulling the lever perturbation used for event driven code.
double initEventDriven(double xlever, const T &active, const U &delta_u, const W &delta_ubar)
Restore perturbation used from event driven protocol.
System(const array_type::tensor< double, 2 > &coor, const array_type::tensor< size_t, 2 > &conn, const array_type::tensor< size_t, 2 > &dofs, const array_type::tensor< size_t, 1 > &iip, const std::vector< array_type::tensor< size_t, 1 > > &elem, const std::vector< array_type::tensor< size_t, 1 > > &node, const array_type::tensor< bool, 1 > &layer_is_plastic, const array_type::tensor< double, 2 > &elastic_K, const array_type::tensor< double, 2 > &elastic_G, const array_type::tensor< double, 2 > &plastic_K, const array_type::tensor< double, 2 > &plastic_G, const array_type::tensor< double, 3 > &plastic_epsy, double dt, double rho, double alpha, double eta, const array_type::tensor< bool, 2 > &drive_is_active, double k_drive, double H, const array_type::tensor< double, 1 > &hi)
Define basic geometry.
void updated_u() override
Evaluate relevant forces when m_u is updated.
void setLeverProperties(double H, const T &hi)
Overwrite the lever properties.
std::string type() const override
Return the type of system.
void initEventDriven(double xlever, const T &active)
Initialise the event driven protocol by applying a perturbation to loading spring and computing and s...
const array_type::tensor< size_t, N > & i() const
Index of the current yield strain per item.
Definition: Cartesian2d.h:436
void set_epsy(const T &epsy)
Overwrite yield strains per item.
Definition: Cartesian2d.h:411
const array_type::tensor< double, N+1 > & epsy() const
Yield strains per item.
Definition: Cartesian2d.h:401
std::vector< std::string > version_dependencies()
Return versions of this library and of all of its dependencies.
Definition: Generic2d.h:161
std::vector< std::string > version_compiler()
Version information of the compilers.
Definition: Generic2d.h:170
std::vector< std::string > version_dependencies()
Return versions of this library and of all of its dependencies.
std::vector< std::string > version_compiler()
Version information of the compilers.
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Definition: config.h:160
Friction simulations based on a disorder potential energy landscape and the finite element method.
Definition: config.h:139
#define FRICTIONQPOTFEM_ASSERT(expr)
All assertions are implementation as::
Definition: config.h:62