FrictionQPotFEM 0.23.3
Loading...
Searching...
No Matches
UniformMultiLayerIndividualDrive2d.h
Go to the documentation of this file.
1
7#ifndef FRICTIONQPOTFEM_UNIFORMMULTILAYERINDIVIDUALDRIVE2D_H
8#define FRICTIONQPOTFEM_UNIFORMMULTILAYERINDIVIDUALDRIVE2D_H
9
10#include "Generic2d.h"
11#include "config.h"
12
13namespace FrictionQPotFEM {
14
21namespace UniformMultiLayerIndividualDrive2d {
22
26inline std::vector<std::string> version_dependencies()
27{
29}
30
34inline std::vector<std::string> version_compiler()
35{
37}
38
57class System : public Generic2d::System {
58
59public:
60 System() = default;
61
62 virtual ~System(){};
63
91 const std::vector<array_type::tensor<size_t, 1>>& elem,
92 const std::vector<array_type::tensor<size_t, 1>>& node,
93 const array_type::tensor<bool, 1>& layer_is_plastic,
94 const array_type::tensor<double, 2>& elastic_K,
95 const array_type::tensor<double, 2>& elastic_G,
96 const array_type::tensor<double, 2>& plastic_K,
97 const array_type::tensor<double, 2>& plastic_G,
98 const array_type::tensor<double, 3>& plastic_epsy,
99 double dt,
100 double rho,
101 double alpha,
102 double eta,
103 const array_type::tensor<bool, 2>& drive_is_active,
104 double k_drive)
105 {
106 this->init(
107 coor,
108 conn,
109 dofs,
110 iip,
111 elem,
112 node,
113 layer_is_plastic,
114 elastic_K,
115 elastic_G,
116 plastic_K,
117 plastic_G,
118 plastic_epsy,
119 dt,
120 rho,
121 alpha,
122 eta,
123 drive_is_active,
124 k_drive);
125 }
126
127protected:
131 void init(
136 const std::vector<array_type::tensor<size_t, 1>>& elem,
137 const std::vector<array_type::tensor<size_t, 1>>& node,
138 const array_type::tensor<bool, 1>& layer_is_plastic,
139 const array_type::tensor<double, 2>& elastic_K,
140 const array_type::tensor<double, 2>& elastic_G,
141 const array_type::tensor<double, 2>& plastic_K,
142 const array_type::tensor<double, 2>& plastic_G,
143 const array_type::tensor<double, 3>& plastic_epsy,
144 double dt,
145 double rho,
146 double alpha,
147 double eta,
148 const array_type::tensor<bool, 2>& drive_is_active,
149 double k_drive)
150 {
151 FRICTIONQPOTFEM_ASSERT(layer_is_plastic.size() == elem.size());
152 FRICTIONQPOTFEM_ASSERT(layer_is_plastic.size() == node.size());
153
154 using size_type = typename decltype(m_layerdrive_active)::size_type;
155
156 m_n_layer = node.size();
157 m_layer_node = node;
158 m_layer_elem = elem;
159 m_layer_is_plastic = layer_is_plastic;
160
161 std::array<size_type, 1> shape1 = {static_cast<size_type>(m_n_layer)};
162 std::array<size_type, 2> shape2 = {static_cast<size_type>(m_n_layer), 2};
163 m_layerdrive_active.resize(shape2);
164 m_layerdrive_targetubar.resize(shape2);
165 m_layer_ubar.resize(shape2);
166 m_layer_dV1.resize(shape2);
167 m_slice_index.resize(shape1);
168
169 m_layerdrive_targetubar.fill(0.0);
170 m_layerdrive_active.fill(false);
171
172 size_t n_elem_plas = 0;
173 size_t n_elem_elas = 0;
174 size_t n_layer_plas = 0;
175 size_t n_layer_elas = 0;
176
177 for (size_t i = 0; i < elem.size(); ++i) {
178 if (m_layer_is_plastic(i)) {
179 n_elem_plas += elem[i].size();
180 n_layer_plas++;
181 }
182 else {
183 n_elem_elas += elem[i].size();
184 n_layer_elas++;
185 }
186 }
187
188 array_type::tensor<size_t, 1> plas = xt::empty<size_t>({n_elem_plas});
189 array_type::tensor<size_t, 1> elas = xt::empty<size_t>({n_elem_elas});
190
191 std::array<size_type, 1> size_plas = {static_cast<size_type>(n_layer_plas) + 1};
192 std::array<size_type, 1> size_elas = {static_cast<size_type>(n_layer_elas) + 1};
193 m_slice_plas.resize(size_plas);
194 m_slice_elas.resize(size_elas);
195 m_slice_plas(0) = 0;
196 m_slice_elas(0) = 0;
197 m_N = 0;
198
199 n_elem_plas = 0;
200 n_elem_elas = 0;
201 n_layer_plas = 0;
202 n_layer_elas = 0;
203
204 for (size_t i = 0; i < m_n_layer; ++i) {
205 if (m_layer_is_plastic(i)) {
206 size_t l = m_slice_plas(n_layer_plas);
207 size_t u = n_elem_plas + elem[i].size();
208
209 m_slice_index(i) = n_layer_plas;
210 m_slice_plas(n_layer_plas + 1) = u;
211
212 xt::view(plas, xt::range(l, u)) = elem[i];
213
214 n_elem_plas += elem[i].size();
215 n_layer_plas++;
216
217 FRICTIONQPOTFEM_REQUIRE(m_N == elem[i].size() || m_N == 0);
218 m_N = elem[i].size();
219 }
220 else {
221 size_t l = m_slice_elas(n_layer_elas);
222 size_t u = n_elem_elas + elem[i].size();
223
224 m_slice_index(i) = n_layer_elas;
225 m_slice_elas(n_layer_elas + 1) = u;
226
227 xt::view(elas, xt::range(l, u)) = elem[i];
228
229 n_elem_elas += elem[i].size();
230 n_layer_elas++;
231 }
232 }
233
234 this->initSystem(
235 coor,
236 conn,
237 dofs,
238 iip,
239 elas,
240 elastic_K,
241 elastic_G,
242 plas,
243 plastic_K,
244 plastic_G,
245 plastic_epsy,
246 dt,
247 rho,
248 alpha,
249 eta);
250
253 m_uq = m_quad.allocate_qtensor<1>(0.0);
254 m_dV = m_quad.dV();
255
256 size_t nip = m_quad.nip();
257 m_layer_dV1.fill(0.0);
258
259 for (size_t i = 0; i < m_n_layer; ++i) {
260 for (auto& e : m_layer_elem[i]) {
261 for (size_t q = 0; q < nip; ++q) {
262 for (size_t d = 0; d < 2; ++d) {
263 m_layer_dV1(i, d) += m_dV(e, q);
264 }
265 }
266 }
267 }
268
269// sanity check nodes per layer
270#ifdef FRICTIONQPOTFEM_ENABLE_ASSERT
271 for (size_t i = 0; i < m_n_layer; ++i) {
272 auto e = this->layerElements(i);
273 auto n = xt::unique(xt::view(m_vector.conn(), xt::keep(e)));
274 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(xt::sort(n), xt::sort(node[i]))));
275 }
276#endif
277
278// sanity check elements per layer + slice of elas/plas element sets
279#ifdef FRICTIONQPOTFEM_ENABLE_ASSERT
280 for (size_t i = 0; i < m_n_layer; ++i) {
281 array_type::tensor<size_t, 1> e;
282 size_t j = m_slice_index(i);
283 if (m_layer_is_plastic(i)) {
284 e = xt::view(m_elem_plas, xt::range(m_slice_plas(j), m_slice_plas(j + 1)));
285 }
286 else {
287 e = xt::view(m_elem_elas, xt::range(m_slice_elas(j), m_slice_elas(j + 1)));
288 }
289 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(xt::sort(e), xt::sort(elem[i]))));
290 }
291#endif
292
293 this->layerSetDriveStiffness(k_drive);
294 this->layerSetTargetActive(drive_is_active);
295 }
300public:
301 size_t N() const override
302 {
303 return m_N;
304 }
305
306 std::string type() const override
307 {
308 return "FrictionQPotFEM.UniformMultiLayerIndividualDrive2d.System";
309 }
310
315 size_t nlayer() const
316 {
317 return m_n_layer;
318 }
319
326 {
328 return m_layer_elem[i];
329 }
330
337 {
339 return m_layer_node[i];
340 }
341
347 {
348 return m_layer_is_plastic;
349 }
350
361 void layerSetDriveStiffness(double k, bool symmetric = true)
362 {
363 m_drive_spring_symmetric = symmetric;
364 m_drive_k = k;
367 }
368
387 template <class S, class T>
388 double initEventDriven(const S& ubar, const T& active)
389 {
390 FRICTIONQPOTFEM_ASSERT(xt::has_shape(ubar, m_layerdrive_targetubar.shape()));
391 FRICTIONQPOTFEM_ASSERT(xt::has_shape(active, m_layerdrive_active.shape()));
392
393 // backup system
394
395 auto u0 = m_u;
396 auto v0 = m_v;
397 auto a0 = m_a;
398 auto active0 = m_layerdrive_active;
399 auto ubar0 = m_layerdrive_targetubar;
400 auto inc0 = m_inc;
401
403 array_type::tensor<double, 3> rigid = xt::empty<double>({m_nelem_plas, m_nip, size_t(2)});
404
405 double infty = std::numeric_limits<double>::max();
406
407 for (size_t e = 0; e < m_nelem_plas; ++e) {
408 for (size_t q = 0; q < m_nip; ++q) {
409 rigid(e, q, 0) = -infty;
410 rigid(e, q, 1) = infty;
411 }
412 }
413
414 m_plas.set_epsy(rigid);
415
416 // perturbation
417
418 m_u.fill(0.0);
419 m_v.fill(0.0);
420 m_a.fill(0.0);
421 this->updated_u();
422 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(m_plas.i(), 0)));
423 this->layerSetTargetActive(active);
424 this->layerSetTargetUbar(ubar);
425 this->minimise(0);
426 FRICTIONQPOTFEM_ASSERT(xt::all(xt::equal(m_plas.i(), 0)));
427 auto up = m_u;
428 m_u.fill(0.0);
429
430 // restore yield strains
431
432 m_plas.set_epsy(epsy0);
433
434 // store result
435
436 auto c = this->eventDriven_setDeltaU(up);
439
440 // restore system
441
442 this->setU(u0);
443 this->setV(v0);
444 this->setA(a0);
445 this->layerSetTargetActive(active0);
446 this->layerSetTargetUbar(ubar0);
447 this->setInc(inc0);
448
449 return c;
450 }
451
459 template <class S, class T, class U>
460 double initEventDriven(const S& ubar, const T& active, const U& delta_u)
461 {
462 FRICTIONQPOTFEM_ASSERT(xt::has_shape(ubar, m_layerdrive_targetubar.shape()));
463 FRICTIONQPOTFEM_ASSERT(xt::has_shape(active, m_layerdrive_active.shape()));
464 FRICTIONQPOTFEM_ASSERT(xt::has_shape(delta_u, m_u.shape()));
465 double c = this->eventDriven_setDeltaU(delta_u);
468 return c;
469 }
470
476 {
478 }
479
485 {
487 }
488
490 double deps,
491 bool kick,
492 int direction = +1,
493 bool yield_element = false,
494 bool fallback = false) override
495 {
496 double c =
497 Generic2d::System::eventDrivenStep(deps, kick, direction, yield_element, fallback);
499 return c;
500 }
501
511 template <class T>
512 void layerSetTargetActive(const T& active)
513 {
514 FRICTIONQPOTFEM_ASSERT(xt::has_shape(active, m_layerdrive_active.shape()));
515 m_layerdrive_active = active;
518 }
519
528 {
529 // Recompute needed because computeLayerUbarActive() only computes the average
530 // on layers with an active spring.
531 // This function, in contrast, returns the average on all layers.
532
533 m_layer_ubar.fill(0.0);
534 size_t nip = m_quad.nip();
535
538
539 for (size_t i = 0; i < m_n_layer; ++i) {
540 for (auto& e : m_layer_elem[i]) {
541 for (size_t d = 0; d < 2; ++d) {
542 for (size_t q = 0; q < nip; ++q) {
543 m_layer_ubar(i, d) += m_uq(e, q, d) * m_dV(e, q);
544 }
545 }
546 }
547 }
548
550
551 return m_layer_ubar;
552 }
553
559 {
561 }
562
568 {
569 return m_layerdrive_active;
570 }
571
581 template <class T>
582 void layerSetTargetUbar(const T& ubar)
583 {
584 FRICTIONQPOTFEM_ASSERT(xt::has_shape(ubar, m_layerdrive_targetubar.shape()));
586 this->computeForceFromTargetUbar(); // average displacement and other forces do not change
587 }
588
603 template <class S, class T>
604 void layerSetUbar(const S& ubar, const T& prescribe)
605 {
606 auto current = this->layerUbar();
607
608 for (size_t i = 0; i < m_n_layer; ++i) {
609 for (size_t d = 0; d < 2; ++d) {
610 if (prescribe(i, d)) {
611 double du = ubar(i, d) - current(i, d);
612 for (auto& n : m_layer_node[i]) {
613 m_u(n, d) += du;
614 }
615 }
616 }
617 }
618
621 this->computeForceMaterial();
622 }
623
635 template <class T>
637 layerTargetUbar_affineSimpleShear(double delta_gamma, const T& height) const
638 {
639 FRICTIONQPOTFEM_ASSERT(xt::has_shape(height, {m_n_layer}));
640
641 auto ret = xt::zeros_like(m_layerdrive_targetubar);
642
643 for (size_t i = 0; i < m_n_layer; ++i) {
644 ret(i, 0) += 2.0 * delta_gamma * height(i);
645 }
646
647 return ret;
648 }
649
659 {
660 return m_fdrive;
661 }
662
672 {
673 array_type::tensor<double, 2> ret = xt::zeros<double>({m_n_layer, size_t(2)});
674
675 for (size_t i = 0; i < m_n_layer; ++i) {
676 for (size_t d = 0; d < 2; ++d) {
677 if (m_layerdrive_active(i, d)) {
678 ret(i, d) = m_drive_k * (m_layerdrive_targetubar(i, d) - m_layer_ubar(i, d));
679 }
680 }
681 }
682
683 return ret;
684 }
685
686protected:
691 {
692 m_layer_ubar.fill(0.0);
693 size_t nip = m_quad.nip();
694
697
698 for (size_t i = 0; i < m_n_layer; ++i) {
699 for (size_t d = 0; d < 2; ++d) {
700 if (m_layerdrive_active(i, d)) {
701 for (auto& e : m_layer_elem[i]) {
702 for (size_t q = 0; q < nip; ++q) {
703 m_layer_ubar(i, d) += m_uq(e, q, d) * m_dV(e, q);
704 }
705 }
706 }
707 }
708 }
709
711 }
712
722 {
723 m_uq.fill(0.0); // pre-allocated value that an be freely used
724 size_t nip = m_quad.nip();
725
726 for (size_t i = 0; i < m_n_layer; ++i) {
727 for (size_t d = 0; d < 2; ++d) {
728 if (m_layerdrive_active(i, d)) {
729 double f = m_drive_k * (m_layer_ubar(i, d) - m_layerdrive_targetubar(i, d));
730 if (m_drive_spring_symmetric || f < 0) { // buckle under compression
731 for (auto& e : m_layer_elem[i]) {
732 for (size_t q = 0; q < nip; ++q) {
733 m_uq(e, q, d) = f;
734 }
735 }
736 }
737 }
738 }
739 }
740
744 }
745
749 void updated_u() override
750 {
753 this->computeForceMaterial();
754 }
755
766 {
767 xt::noalias(m_fint) = m_fdrive + m_fmaterial + m_fdamp;
769 xt::noalias(m_fres) = m_fext - m_fint;
770 }
771
772protected:
773 size_t m_N;
774 size_t m_n_layer;
775 std::vector<array_type::tensor<size_t, 1>> m_layer_node;
776 std::vector<array_type::tensor<size_t, 1>> m_layer_elem;
782
784 double m_drive_k;
795
799};
800
801} // namespace UniformMultiLayerIndividualDrive2d
802} // namespace FrictionQPotFEM
803
804#endif
System with elastic elements and plastic elements (GMatElastoPlasticQPot).
Definition: Generic2d.h:183
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
array_type::tensor< double, 2 > m_fext
Nodal force: total external force (reaction force)
Definition: Generic2d.h:2130
double eta() const
Get the damping at the interface.
Definition: Generic2d.h:478
double rho() const
Mass density.
Definition: Generic2d.h:406
array_type::tensor< size_t, 1 > m_elem_elas
Elastic elements.
Definition: Generic2d.h:2085
array_type::tensor< double, 2 > m_fmaterial
Nodal force, deriving from elasticity.
Definition: Generic2d.h:2123
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
array_type::tensor< double, 2 > m_fres
Nodal force: residual force.
Definition: Generic2d.h:2131
double eventDriven_setDeltaU(const T &delta_u, bool autoscale=true)
Set purely elastic and linear response to specific boundary conditions.
Definition: Generic2d.h:1234
array_type::tensor< double, 3 > m_ue
Element vector (used for displacements).
Definition: Generic2d.h:2117
size_t m_inc
Current increment (current time = m_dt * m_inc).
Definition: Generic2d.h:2138
const auto & u() const
Nodal displacements.
Definition: Generic2d.h:728
void setU(const T &u)
Overwrite nodal displacements.
Definition: Generic2d.h:586
array_type::tensor< size_t, 1 > m_elem_plas
Plastic elements.
Definition: Generic2d.h:2086
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
array_type::tensor< double, 2 > m_fint
Nodal force: total internal force.
Definition: Generic2d.h:2129
virtual void setInc(size_t arg)
Set increment.
Definition: Generic2d.h:918
const auto & conn() const
Connectivity.
Definition: Generic2d.h:698
GooseFEM::Element::Quad4::Quadrature m_quad
Quadrature for all elements.
Definition: Generic2d.h:2087
array_type::tensor< double, 2 > m_fdamp
Nodal force from damping.
Definition: Generic2d.h:2126
double dt() const
Get time step.
Definition: Generic2d.h:566
array_type::tensor< double, 2 > m_u
Nodal displacements.
Definition: Generic2d.h:2104
GooseFEM::VectorPartitioned m_vector
Convert vectors between 'nodevec', 'elemvec', ....
Definition: Generic2d.h:2090
const auto & dofs() const
DOFs per node.
Definition: Generic2d.h:718
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).
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...
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)
Define basic geometry.
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 layerSetDriveStiffness(double k, bool symmetric=true)
Set the stiffness of the springs connecting the average displacement of a layer ("ubar") to its set t...
void computeLayerUbarActive()
Compute the average displacement of all layers with an active driving spring.
size_t N() const override
Return the linear system size (in number of blocks).
double initEventDriven(const S &ubar, const T &active, const U &delta_u)
Restore perturbation used from event driven protocol.
void layerSetTargetActive(const T &active)
Turn on (or off) springs connecting the average displacement of a layer ("ubar") to its set target va...
std::string type() const override
Return the type of system.
array_type::tensor< size_t, 1 > layerElements(size_t i) const
Return the elements belonging to the i-th layer.
void computeForceFromTargetUbar()
Compute force deriving from the activate springs between the average displacement of the layer and it...
array_type::tensor< double, 2 > layerFdrive() const
Force of each of the driving springs.
array_type::tensor< double, 2 > layerUbar()
List the average displacement of each layer.
array_type::tensor< size_t, 1 > layerNodes(size_t i) const
Return the nodes belonging to the i-th layer.
array_type::tensor< size_t, 1 > m_slice_plas
How to slice elastic_elem(): start & end index.
bool m_drive_spring_symmetric
If false the drive spring buckles in compression.
array_type::tensor< double, 2 > m_layer_dV1
volume per layer (as vector, same for all dimensions)
array_type::tensor< double, 2 > m_fdrive
Force related to driving frame.
void layerSetUbar(const S &ubar, const T &prescribe)
Move the layer such that the average displacement is exactly equal to its input value.
array_type::tensor< double, 2 > layerTargetUbar_affineSimpleShear(double delta_gamma, const T &height) const
Get target average displacements that correspond to affine simple shear (with the bottom fixed).
const array_type::tensor< double, 2 > & eventDriven_deltaUbar() const
Get target average position perturbation used for event driven code.
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< size_t, 1 > m_slice_elas
How to slice plastic_elem(): start & end index.
const array_type::tensor< double, 2 > & layerTargetUbar() const
List the target average displacement per layer.
const array_type::tensor< bool, 2 > & eventDriven_targetActive() const
Get if the target average position is prescribed in the event driven code.
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.
std::vector< array_type::tensor< size_t, 1 > > m_layer_node
Nodes per layer.
void updated_u() override
Evaluate relevant forces when m_u is updated.
array_type::tensor< bool, 1 > m_layer_is_plastic
Per layer true if the layer is plastic.
std::vector< array_type::tensor< size_t, 1 > > m_layer_elem
Elements per layer.
double initEventDriven(const S &ubar, const T &active)
Initialise the event driven protocol by applying a perturbation to the loading springs and computing ...
const array_type::tensor< bool, 1 > & layerIsPlastic() const
Return if a layer is elastic (false) or plastic (true).
array_type::tensor< size_t, 1 > m_slice_index
Per layer the index in m_slice_plas or m_slice_elas.
const array_type::tensor< bool, 2 > & layerTargetActive() const
List if the driving spring is activate.
const array_type::tensor< double, 2 > & fdrive() const
Nodal force induced by the driving springs.
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
auto dV() const -> const array_type::tensor< double, 2 > &
Integration volume.
Definition: Element.h:581
void int_N_vector_dV(const T &qvector, R &elemvec) const
Same as Int_N_vector_dV(), but writing to preallocated return.
Definition: Element.h:744
void interpQuad_vector(const T &elemvec, R &qvector) const
Same as InterpQuad_vector(), but writing to preallocated return.
Definition: Element.h:610
auto nip() const
Number of integration points.
Definition: Element.h:201
auto allocate_qtensor() const
Get an allocated array_type::tensor to store a "qtensor" of a certain rank (0 = scalar,...
Definition: Element.h:441
void copy_p(const array_type::tensor< double, 2 > &nodevec_src, array_type::tensor< double, 2 > &nodevec_dest) const
Copy prescribed DOFs from "nodevec" to another "nodvec":
const array_type::tensor< size_t, 2 > & conn() const
Definition: Vector.h:92
void asElement(const T &arg, R &ret) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
Definition: Vector.h:208
void assembleDofs(const T &arg, R &ret) const
Assemble "nodevec" or "elemvec" to "dofval" (adds entries that occur more that once).
Definition: Vector.h:234
array_type::tensor< double, 1 > allocate_dofval() const
Allocated "dofval".
Definition: Vector.h:310
array_type::tensor< double, 2 > allocate_nodevec() const
Allocated "nodevec".
Definition: Vector.h:334
void asNode(const T &arg, R &ret) const
Convert "dofval" or "elemvec" to "nodevec" (overwrite entries that occur more than once).
Definition: Vector.h:182
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_compiler()
Version information of the compilers.
std::vector< std::string > version_dependencies()
Return versions of this library and of all of its dependencies.
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
size_t nip()
Number of integration points:
Definition: ElementHex8.h:35
#define FRICTIONQPOTFEM_REQUIRE(expr)
Assertions that cannot be disabled.
Definition: config.h:70
#define FRICTIONQPOTFEM_ASSERT(expr)
All assertions are implementation as::
Definition: config.h:62