7#ifndef FRICTIONQPOTFEM_GENERIC2D_H
8#define FRICTIONQPOTFEM_GENERIC2D_H
16#include <xtensor/xnorm.hpp>
17#include <xtensor/xset_operation.hpp>
18#include <xtensor/xshape.hpp>
19#include <xtensor/xtensor.hpp>
39array_type::tensor<double, 2> myaverage(
40 const array_type::tensor<double, 4>& a,
41 const array_type::tensor<double, 4>& w,
42 const std::array<size_t, 2>& axis)
48 array_type::tensor<double, 2> ret = xt::zeros<double>({a.shape(2), a.shape(3)});
49 array_type::tensor<double, 2> norm = xt::zeros<double>({a.shape(2), a.shape(3)});
51 for (
size_t i = 0; i < a.shape(0); ++i) {
52 for (
size_t j = 0; j < a.shape(1); ++j) {
53 for (
size_t k = 0; k < a.shape(2); ++k) {
54 for (
size_t l = 0; l < a.shape(3); ++l) {
55 ret(k, l) += a(i, j, k, l) *
w(i, j, k, l);
56 norm(k, l) +=
w(i, j, k, l);
83 for (
size_t e = 0; e < arg.shape(0); ++e) {
84 for (
size_t q = 0; q < nip; ++q) {
85 std::copy(&arg(e, 0), &arg(e, 0) + arg.shape(1), &ret(e, q, 1));
86 ret(e, q, 0) = -arg(e, 0);
107 for (
size_t e = 0; e < arg.shape(0); ++e) {
108 for (
size_t q = 0; q < nip; ++q) {
128 if (xt::allclose(arg.flat(0), arg)) {
132 throw std::runtime_error(
"Values not uniform");
143bool is_same(
double a,
double b)
145 return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b &&
146 std::nextafter(a, std::numeric_limits<double>::max()) >= b;
214 template <
class C,
class E,
class L,
class M,
class Y>
226 const Y& plastic_epsy,
254 template <
class C,
class E,
class L,
class M,
class Y>
266 const Y& plastic_epsy,
311#ifdef FRICTIONQPOTFEM_ENABLE_ASSERT
385 virtual size_t N()
const
394 virtual std::string
type()
const
396 return "FrictionQPotFEM.Generic2d.System";
435 if (xt::allclose(val_elem, val_elem(0))) {
448 for (
size_t q = 0; q < nodalQuad.
nip(); ++q) {
449 xt::view(val_quad, xt::all(), q) = val_elem;
463 if (detail::is_same(
eta, 0.0)) {
491 if (detail::is_same(
alpha, 0.0)) {
526 if (xt::allclose(val_elem, val_elem(0))) {
528 if (detail::is_same(
m_alpha, 0.0)) {
542 for (
size_t q = 0; q < nodalQuad.
nip(); ++q) {
543 xt::view(val_quad, xt::all(), q) = val_elem;
559 return xt::allclose(k, k.data()[0]) && xt::allclose(g, g.data()[0]);
589 xt::noalias(
m_u) =
u;
604 xt::noalias(
m_v) =
v;
618 xt::noalias(
m_a) =
a;
728 const auto&
u()
const
738 const auto&
v()
const
748 const auto&
a()
const
794 xt::flatten_indices(xt::argwhere(xt::isclose(xt::view(
m_coor, xt::all(), 1),
t))));
796 xt::flatten_indices(xt::argwhere(xt::isclose(xt::view(
m_coor, xt::all(), 1), b))));
799 for (
size_t i = 0; i < top.size() - 1; i++) {
803 for (
size_t d = 0; d < 2; d++) {
813 for (
size_t d = 0; d < 2; d++) {
818 m_fext(top.front(), 0) = 0.5 * sigxy * h;
819 m_fext(top.back(), 0) = 0.5 * sigxy * h;
821 for (
size_t i = 1; i < top.size() - 1; i++) {
822 m_fext(top(i), 0) = sigxy * h;
867 double r_fres = xt::norm_l2(
m_fres)();
868 double r_fext = xt::norm_l2(
m_fext)();
870 return r_fres / r_fext;
901 this->
setInc(
static_cast<size_t>(std::round(arg /
m_dt)));
928 const auto&
dV()
const
984 const auto& ret_elas =
m_elas.
K();
985 const auto& ret_plas =
m_plas.
K();
986 size_t n = xt::strides(ret_elas, 0);
991 &ret_elas(e, xt::missing),
992 &ret_elas(e, xt::missing) + n,
998 &ret_plas(e, xt::missing),
999 &ret_plas(e, xt::missing) + n,
1016 const auto& ret_elas =
m_elas.
G();
1017 const auto& ret_plas =
m_plas.
G();
1018 size_t n = xt::strides(ret_elas, 0);
1023 &ret_elas(e, xt::missing),
1024 &ret_elas(e, xt::missing) + n,
1030 &ret_plas(e, xt::missing),
1031 &ret_plas(e, xt::missing) + n,
1090 const auto& ret_plas =
m_plas.
C();
1091 const auto& ret_elas =
m_elas.
C();
1092 size_t n = xt::strides(ret_elas, 0);
1097 &ret_elas(e, xt::missing),
1098 &ret_elas(e, xt::missing) + n,
1104 &ret_plas(e, xt::missing),
1105 &ret_plas(e, xt::missing) + n,
1149 size_t n = xt::strides(Eps_elas, 0);
1154 &Eps_elas(e, xt::missing),
1155 &Eps_elas(e, xt::missing) + n,
1158 &Sig_elas(e, xt::missing),
1159 &Sig_elas(e, xt::missing) + n,
1164 &Eps_plas(e, xt::missing),
1165 &Eps_plas(e, xt::missing) + n,
1168 &Sig_plas(e, xt::missing),
1169 &Sig_plas(e, xt::missing) + n,
1248 auto d = xt::amin(xt::diff(
m_plas.
epsy(), 1))();
1249 double c = 0.1 * d / deps;
1304 bool yield_element =
false,
1305 bool iterative =
false)
1320 if (direction > 0 && kick) {
1321 target = epsy_r + 0.5 * deps;
1323 else if (direction > 0) {
1324 target = epsy_r - 0.5 * deps;
1327 target = epsy_l - 0.5 * deps;
1330 target = epsy_l + 0.5 * deps;
1334 auto d = target - eps;
1335 if (direction > 0 && xt::any(d < 0.0)) {
1338 if (direction < 0 && xt::any(d > 0.0)) {
1343 auto scale = xt::empty_like(target);
1346 for (
size_t q = 0; q <
m_nip; ++q) {
1348 double e_t = Epsd_plastic(e, q, 0, 0);
1349 double g_t = Epsd_plastic(e, q, 0, 1);
1352 double epsd_target = target(e, q);
1354 double a = e_d * e_d + g_d * g_d;
1355 double b = 2.0 * (e_t * e_d + g_t * g_d);
1356 double c = e_t * e_t + g_t * g_t - epsd_target * epsd_target;
1357 double D = std::sqrt(b * b - 4.0 *
a * c);
1360 scale(e, q) = (-b + D) / (2.0 *
a);
1366 size_t bound = direction > 0 ? nyield - 2 : 0;
1367 if (xt::all(xt::equal(idx, bound))) {
1370 scale = xt::where(xt::equal(idx, bound), std::numeric_limits<double>::max(), scale);
1379 auto index = xt::unravel_index(xt::argmin(xt::abs(scale))(), scale.shape());
1383 if (kick && yield_element) {
1384 q = xt::argmax(xt::view(xt::abs(scale), e, xt::all()))();
1389 if ((direction > 0 && ret < 0) || (direction < 0 && ret > 0)) {
1395 (direction > 0 && ret > 0) || (direction < 0 && ret < 0));
1402 double dir =
static_cast<double>(direction);
1403 auto steps = xt::sort(xt::ravel(xt::eval(xt::abs(scale))));
1405 xt::xtensor<long, 2> jdx = xt::cast<long>(
m_plas.
i());
1407 long nip =
static_cast<long>(
m_nip);
1413 for (i = 0; i < steps.size(); ++i) {
1415 auto jdx_new = xt::cast<long>(
m_plas.
i());
1416 auto S = xt::abs(jdx_new - jdx);
1417 if (!yield_element || !kick) {
1418 if (xt::any(S > 0)) {
1423 if (xt::any(xt::equal(xt::sum(S > 0, 1), nip))) {
1431 double right = steps(i);
1436 left = steps(i - 1);
1441 for (
size_t step = 0; step < 1100; ++step) {
1443 ret = 0.5 * (right + left);
1445 auto jdx_new = xt::cast<long>(
m_plas.
i());
1446 auto S = xt::abs(jdx_new - jdx);
1449 if (xt::any(S > 0)) {
1456 else if (yield_element) {
1457 if (xt::any(xt::equal(xt::sum(S > 0, 1), nip))) {
1465 if (xt::any(S > 0)) {
1473 if ((right - left) / left < 1e-5) {
1483 auto jdx_new = xt::cast<long>(
m_plas.
i());
1484 auto S = xt::abs(jdx_new - jdx);
1487 if (kick && yield_element) {
1496 auto jdx_new = xt::cast<long>(
m_plas.
i());
1497 auto S = xt::abs(jdx_new - jdx);
1501 if (kick && yield_element) {
1523 const auto& idx_new =
m_plas.
i();
1529 auto eps_target = target(e, q);
1606 size_t nmax = nyield - nmargin;
1612 for (step = 1; step < static_cast<long>(n + 1); ++step) {
1617 if (xt::any(
m_plas.
i() > nmax)) {
1641 size_t niter_tol = 20,
1642 size_t max_iter = 1e7)
1647 double tol2 = tol * tol;
1650 size_t nmax = nyield - nmargin;
1657 for (step = 1; step < max_iter + 1; ++step) {
1661 if (xt::any(xt::not_equal(
m_plas.
i(), i_n))) {
1708 size_t niter_tol = 20,
1709 size_t max_iter = 1e7)
1714 double tol2 = tol * tol;
1718 size_t nmax = nyield - nmargin;
1724 std::vector<double>
fext;
1725 std::vector<std::vector<double>> ux(nodes.size());
1726 std::vector<std::vector<double>> uy(nodes.size());
1728 for (
size_t step = 1; step < max_iter + 1; ++step) {
1733 if (step % t_step == 0) {
1736 for (
auto& n : top) {
1739 fext.push_back(f /
static_cast<double>(top.size() - 1));
1741 for (
size_t i = 0; i < nodes.size(); ++i) {
1742 size_t n = nodes(i);
1743 ux[i].push_back(
m_u(n, 0));
1744 uy[i].push_back(
m_u(n, 1));
1749 if (xt::any(
m_plas.
i() > nmax) || xt::any(
m_plas.
i() < nmargin)) {
1750 throw std::runtime_error(
"Out of bounds");
1757 size_t n =
fext.size();
1759 std::copy(
fext.begin(),
fext.end(), ret_fext.begin());
1763 for (
size_t i = 0; i < nodes.size(); ++i) {
1764 std::copy(ux[i].begin(), ux[i].end(), ret_ux.begin() + i * n);
1769 for (
size_t i = 0; i < nodes.size(); ++i) {
1770 std::copy(uy[i].begin(), uy[i].end(), ret_uy.begin() + i * n);
1774 return std::make_tuple(ret_fext, ret_ux, ret_uy);
1778 throw std::runtime_error(
"No convergence found");
1809 size_t nmax = nyield - nmargin;
1815 for (step = 1; step < static_cast<long>(n + 1); ++step) {
1821 if (xt::any(
m_plas.
i() > nmax)) {
1871 size_t niter_tol = 20,
1872 size_t max_iter = 1e7,
1873 bool time_activity =
false,
1874 bool max_iter_is_error =
true)
1879 double tol2 = tol * tol;
1883 size_t nmax = nyield - nmargin;
1893 for (step = 1; step < static_cast<long>(max_iter + 1); ++step) {
1899 if (xt::any(
m_plas.
i() > nmax)) {
1904 if (time_activity) {
1906 s = xt::sum(xt::abs(i - i_n))();
1923 if (max_iter_is_error) {
1924 throw std::runtime_error(
"No convergence found");
1964 size_t A_truncate = 0,
1965 size_t S_truncate = 0,
1967 size_t niter_tol = 20,
1968 size_t max_iter = 1e7)
1974 double tol2 = tol * tol;
1977 for (
size_t step = 1; step < max_iter + 1; ++step) {
1989 if (
static_cast<size_t>(xt::sum(xt::not_equal(idx_n, idx))()) >= A_truncate) {
1994 std::cout <<
"residuals = " << xt::adapt(residuals.
data()) << std::endl;
1995 bool converged =
false;
2024 size_t A_truncate = 0,
2025 size_t S_truncate = 0,
2027 size_t niter_tol = 20,
2028 size_t max_iter = 1e7)
2031 return this->
minimise_truncate(idx_n, A_truncate, S_truncate, tol, niter_tol, max_iter);
2045 for (
size_t n = 0; n <
m_nnode; ++n) {
2046 ret(n, 0) += 2.0 * delta_gamma * (
m_coor(n, 1) -
m_coor(0, 1));
2068 for (
size_t n = 0; n <
m_nnode; ++n) {
2069 ret(n, 0) += 2.0 * delta_gamma * (
m_coor(n, 1) - y0);
Basic include of common methods.
Sparse matrix that is partitioned in:
System with elastic elements and plastic elements (GMatElastoPlasticQPot).
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.
size_t m_nelem_elas
Number of elastic elements.
const GooseFEM::Element::Quad4::Quadrature & quad() const
GooseFEM quadrature definition.
array_type::tensor< double, 3 > m_ue_elas
m_ue for elastic element only
size_t m_nne
Number of nodes per element.
array_type::tensor< double, 2 > m_fext
Nodal force: total external force (reaction force)
double eta() const
Get the damping at the interface.
double m_rho
Mass density (non-zero only if homogeneous).
double rho() const
Mass density.
array_type::tensor< double, 2 > G() const
Shear modulus per integration point.
void computeEpsSig()
Compute m_Sig and m_Eps using m_u.
array_type::tensor< double, 4 > m_Eps
Quad-point tensor: strain.
array_type::tensor< size_t, 1 > m_elem_elas
Elastic elements.
long flowSteps(size_t n, const T &v, size_t nmargin=0)
Make a number of steps with the following protocol.
const array_type::tensor< double, 4 > & Eps()
Strain tensor of each integration point.
array_type::tensor< double, 2 > m_fmaterial
Nodal force, deriving from elasticity.
void setFext(const T &fext)
Overwrite external force.
const auto & dV() const
Integration point volume (of each integration point)
size_t minimise_truncate(size_t A_truncate=0, size_t S_truncate=0, double tol=1e-5, size_t niter_tol=20, size_t max_iter=1e7)
Like Generic2d::minimise(), but stops when a certain number of blocks has yielded at least once.
size_t minimise_truncate(const T &idx_n, size_t A_truncate=0, size_t S_truncate=0, double tol=1e-5, size_t niter_tol=20, size_t max_iter=1e7)
Like Generic2d::minimise(), but stops when a certain number of blocks has yielded at least once.
auto & damping() const
Damping matrix, see setAlpha() and setDampingMatrix().
const auto & elastic_elem() const
List of elastic elements.
void setMassMatrix(const T &val_elem)
Overwrite mass matrix, based on certain density that is uniform per element.
void setDt(double dt)
Overwrite time step.
array_type::tensor< double, 4 > m_pert_Epsd_plastic
Strain deviator for m_pert_u.
void setV(const T &v)
Overwrite nodal velocities.
array_type::tensor< double, 2 > m_pert_u
See eventDriven_setDeltaU()
array_type::tensor< double, 2 > m_coor
Nodal coordinates, see coor().
GMatElastoPlasticQPot::Cartesian2d::Cusp< 2 > m_plas
Material for plastic el.
size_t m_nnode
Number of nodes.
array_type::tensor< double, 2 > m_a_n
Nodal accelerations last time-step.
void setAlpha(double alpha)
Overwrite background damping density (proportional to the velocity), To use a non-homogeneous density...
const auto & v() const
Nodal velocities.
GooseFEM::Element::Quad4::Quadrature m_quad_elas
m_quad for elastic elements only.
size_t m_qs_inc_last
Last increment with plastic activity during minimisation.
size_t m_nelem
Number of elements.
GooseFEM::Element::Quad4::Quadrature m_quad_plas
m_quad for plastic elements only.
array_type::tensor< double, 2 > m_felas
Nodal force from elasticity of elastic elements.
void quench()
Set nodal velocities and accelerations equal to zero.
const auto & fdamp() const
Force deriving from damping.
size_t m_N
Number of plastic elements, alias of m_nelem_plas.
std::tuple< array_type::tensor< double, 1 >, array_type::tensor< double, 2 >, array_type::tensor< double, 2 > > minimise_highfrequency(const array_type::tensor< size_t, 1 > &nodes, const array_type::tensor< size_t, 1 > &top, size_t t_step=1, size_t nmargin=0, double tol=1e-5, size_t niter_tol=20, size_t max_iter=1e7)
Minimise energy while doing a high-frequency measurement of:
size_t m_qs_inc_first
First increment with plastic activity during minimisation.
const array_type::tensor< double, 4 > & plastic_Epsdot()
Strain-rate tensor of integration points of plastic elements only, see System::plastic.
System(const C &coor, const E &conn, const E &dofs, const L &iip, const L &elastic_elem, const M &elastic_K, const M &elastic_G, const L &plastic_elem, const M &plastic_K, const M &plastic_G, const Y &plastic_epsy, double dt, double rho, double alpha, double eta)
Define the geometry, including boundary conditions and element sets.
array_type::tensor< double, 2 > m_a
Nodal accelerations.
array_type::tensor< double, 3 > m_ue_plas
m_ue for plastic element only
array_type::tensor< double, 2 > m_fres
Nodal force: residual force.
GooseFEM::MatrixDiagonalPartitioned m_M
Mass matrix (diagonal).
GooseFEM::VectorPartitioned m_vector_plas
m_vector for plastic elements only.
array_type::tensor< double, 2 > m_fplas
Nodal force from elasticity of plastic elements.
double residual() const
Norm of the relative residual force (the external force at the top/bottom boundaries is used for norm...
void setEta(double eta)
Overwrite the value of the damping at the interface.
void updated_v()
Evaluate relevant forces when m_v is updated.
double eventDriven_setDeltaU(const T &delta_u, bool autoscale=true)
Set purely elastic and linear response to specific boundary conditions.
array_type::tensor< double, 3 > m_fe
Element vector (used for forces).
array_type::tensor< double, 4 > m_Epsdot_plas
Quad-point tensor: strain-rate for plastic el.
const auto & plastic_elem() const
List of plastic elements.
array_type::tensor< double, 2 > m_ftmp
Temporary for internal use.
array_type::tensor< double, 3 > m_ue
Element vector (used for displacements).
size_t m_ndim
Number of spatial dimensions.
size_t m_inc
Current increment (current time = m_dt * m_inc).
const auto & u() const
Nodal displacements.
GooseFEM::MatrixPartitioned stiffness() const
Stiffness tensor of each integration point.
const auto & a() const
Nodal accelerations.
GMatElastoPlasticQPot::Cartesian2d::Cusp< 2 > & plastic()
Elastic material mode, used for all elastic elements.
double m_alpha
Background damping density (non-zero only if homogeneous).
const array_type::tensor< double, 4 > & Sig()
Stress tensor of each integration point.
void setU(const T &u)
Overwrite nodal displacements.
double t() const
Current time.
array_type::tensor< double, 2 > K() const
Bulk modulus per integration point.
array_type::tensor< size_t, 1 > m_elem_plas
Plastic elements.
array_type::tensor< double, 3 > m_fe_elas
m_fe for elastic element only
const auto & fmaterial() const
Force deriving from elasticity.
array_type::tensor< double, 4 > m_Sig
Quad-point tensor: stress.
array_type::tensor< double, 2 > m_v
Nodal velocities.
virtual size_t N() const
Return the linear system size (in number of blocks).
const auto & coor() const
Nodal coordinates.
GooseFEM::Matrix m_K_elas
Stiffness matrix for elastic elements only.
bool m_set_visco
Use m_eta only if it is non-zero.
void computeForceMaterial()
Update m_fmaterial based on the current displacement field m_u.
size_t quasistaticActivityLast() const
Increment with the last plastic event.
array_type::tensor< double, 2 > m_fint
Nodal force: total internal force.
virtual void setInc(size_t arg)
Set increment.
const auto & conn() const
Connectivity.
void applyShearStress(double sigxy)
Modify the external force such that a shear stress is applied to the top boundary.
GooseFEM::Element::Quad4::Quadrature m_quad
Quadrature for all elements.
array_type::tensor< double, 2 > m_fdamp
Nodal force from damping.
double dt() const
Get time step.
array_type::tensor< double, 2 > m_u
Nodal displacements.
double m_eta
Damping at the interface.
virtual void computeInternalExternalResidualForce()
Compute:
void setT(double arg)
Overwrite time.
GooseFEM::VectorPartitioned m_vector
Convert vectors between 'nodevec', 'elemvec', ....
GooseFEM::MatrixDiagonal m_D
Damping matrix (diagonal).
array_type::tensor< double, 2 > affineSimpleShear(double delta_gamma) const
Get the displacement field that corresponds to an affine simple shear of a certain strain.
array_type::tensor< double, 2 > m_fvisco
Nodal force from damping at the interface.
array_type::tensor< double, 3 > m_fe_plas
m_fe for plastic element only
const auto & dofs() const
DOFs per node.
bool m_full_outdated
Keep track of the need to recompute fields on full geometry.
const auto & fext()
External force.
size_t inc() const
The increment, see setInc().
bool m_set_D
Use m_D only if it is non-zero.
virtual std::string type() const
Return the type of system.
long timeSteps(size_t n, size_t nmargin=0)
Make a number of time steps, see timeStep().
bool isHomogeneousElastic() const
Check if elasticity is homogeneous.
void refresh()
Recompute all forces.
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...
const auto & eventDriven_deltaU() const
Get displacement perturbation used for event driven code, see eventDriven_setDeltaU().
double alpha() const
Background damping density.
void setRho(double rho)
Overwrite the mass density to a homogeneous quantity.
void setA(const T &a)
Overwrite nodal accelerations.
const auto & fint()
Internal force.
auto & mass() const
Mass matrix, see System::m_M.
void setDampingMatrix(const T &val_elem)
Overwrite damping matrix, based on certain density (taken uniform per element).
const GooseFEM::VectorPartitioned & vector() const
GooseFEM vector definition.
size_t quasistaticActivityFirst() const
Increment with the first plastic event.
size_t m_nip
Number of integration points.
GooseFEM::VectorPartitioned m_vector_elas
m_vector for elastic elements only.
array_type::tensor< double, 4 > Epsddot() const
Symmetric gradient of the nodal accelerations of each integration point.
GMatElastoPlasticQPot::Cartesian2d::Elastic< 2 > m_elas
Material for elastic el.
virtual void updated_u()
Evaluate relevant forces when m_u is updated.
array_type::tensor< double, 2 > m_v_n
Nodal velocities last time-step.
array_type::tensor< double, 2 > affineSimpleShearCentered(double delta_gamma) const
Get the displacement field that corresponds to an affine simple shear of a certain strain.
size_t timeStepsUntilEvent(size_t nmargin=0, double tol=1e-5, size_t niter_tol=20, size_t max_iter=1e7)
Perform a series of time-steps until the next plastic event, or equilibrium.
void timeStep()
Make a time-step: apply velocity-Verlet integration.
size_t m_nelem_plas
Number of plastic elements.
GMatElastoPlasticQPot::Cartesian2d::Elastic< 2 > & elastic()
Elastic material mode, used for all elastic elements.
array_type::tensor< double, 4 > Epsdot() const
Strain-rate tensor (the symmetric gradient of the nodal velocities) of each integration point.
Array of material points with an elasto-plastic material model.
const array_type::tensor< size_t, N > & i() const
Index of the current yield strain per item.
const array_type::tensor< double, N+1 > & epsy() const
Yield strains per item.
void refresh(bool compute_tangent=true) override
Recompute stress from strain.
array_type::tensor< double, N > epsy_right() const
Current yield strain right per item.
array_type::tensor< double, N > epsy_left() const
Current yield strain left per item.
Array of material points with a linear elastic constitutive response.
const array_type::tensor< double, N+2 > & Sig() const
Stress tensor per item.
const array_type::tensor< double, N > & G() const
Shear modulus per item.
const array_type::tensor< double, N+4 > & C() const
Tangent tensor per item.
const array_type::tensor< double, N+2 > & Eps() const
Strain tensor per item.
virtual void refresh(bool compute_tangent=true)
Recompute stress from strain.
const array_type::tensor< double, N > & K() const
Bulk modulus per item.
Interpolation and quadrature.
auto Int_N_scalar_NT_dV(const T &qscalar) const -> array_type::tensor< double, 3 >
Element-by-element: integral of the scalar product of the shape function with a scalar.
auto SymGradN_vector(const T &elemvec) const -> array_type::tensor< double, 4 >
The symmetric output of GradN_vector().
void symGradN_vector(const T &elemvec, R &qtensor) const
Same as SymGradN_vector(), but writing to preallocated return.
void int_gradN_dot_tensor2_dV(const T &qtensor, R &elemvec) const
Same as Int_gradN_dot_tensor2_dV(), but writing to preallocated return.
auto dV() const -> const array_type::tensor< double, 2 > &
Integration volume.
auto Int_gradN_dot_tensor4_dot_gradNT_dV(const T &qtensor) const -> array_type::tensor< double, 3 >
Element-by-element: integral of the dot products of the shape function gradients with a fourth order ...
auto nip() const
Number of integration points.
auto allocate_qtensor() const
Get an allocated array_type::tensor to store a "qtensor" of a certain rank (0 = scalar,...
Class to perform a residual check based on the last "n" iterations.
void roll_insert(double res)
Roll the list with the residuals, and add a new residual to the end.
bool all_less(double tol) const
Check of the sequence of n residuals are all below a tolerance.
bool descending() const
Check of the sequence of n residuals is in descending order.
const std::vector< double > & data() const
Get the historic residuals.
void assemble(const T &elemmat)
Assemble from "elemmat".
void dot(const array_type::tensor< double, 2 > &x, array_type::tensor< double, 2 > &b) const
Dot-product .
void solve(const array_type::tensor< double, 2 > &b, array_type::tensor< double, 2 > &x)
Solve .
Diagonal and partitioned matrix.
Sparse matrix partitioned in an unknown and a prescribed part.
Class to switch between storage types, based on a mesh and DOFs that are partitioned in:
const array_type::tensor< size_t, 1 > & iip() const
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
void asElement(const T &arg, R &ret) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
void assembleNode(const T &arg, R &ret) const
Assemble "elemvec" to "nodevec" (adds entries that occur more that once.
array_type::tensor< double, 2 > allocate_nodevec() const
Allocated "nodevec".
array_type::tensor< double, 3 > AsElement(const T &arg) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
array_type::tensor< double, 3 > allocate_elemvec() const
Allocated "elemvec".
const array_type::tensor< size_t, 2 > & dofs() const
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.
Friction simulations based on a disorder potential energy landscape and the finite element method.
array_type::tensor< double, 2 > moduli_toquad(const array_type::tensor< double, 1 > &arg, size_t nip=GooseFEM::Element::Quad4::Gauss::nip())
Broadcast array of moduli stored per element [nelem] to be the same for all quadrature points,...
array_type::tensor< double, 3 > epsy_initelastic_toquad(const array_type::tensor< double, 2 > &arg, size_t nip=GooseFEM::Element::Quad4::Gauss::nip())
Convert array of yield strains stored per element [nelem, n]:
T::value_type getuniform(const T &arg)
Extract uniform value (throw if not uniform):
auto Epsd(const T &A) -> typename GMatTensor::allocate< xt::get_rank< T >::value - 2, T >::type
Equivalent strain: norm of strain deviator.
auto Deviatoric(const T &A)
Deviatoric part of a tensor:
std::vector< std::string > version_dependencies(bool greedy=true)
Return versions of this library and of all of its major dependencies.
std::vector< std::string > version_compiler()
Return information on the compiler, the platform, the C++ standard, and the compilation data.
array_type::tensor< double, 1 > w()
Integration point weights.
size_t nip()
Number of integration points:
array_type::tensor< double, 1 > w()
Integration point weights.
array_type::tensor< double, 2 > xi()
Integration point coordinates (local coordinates).
bool is_unique(const T &arg)
Returns true is a list is unique (has not duplicate items).
#define FRICTIONQPOTFEM_REQUIRE(expr)
Assertions that cannot be disabled.
#define FRICTIONQPOTFEM_WIP(expr)
Assertions on a implementation limitation (that in theory can be resolved)
#define FRICTIONQPOTFEM_ASSERT(expr)
All assertions are implementation as::