| 1362 | } |
| 1363 | |
| 1364 | void ASDConcrete3DMaterial::CrackPlanes::updateCurrentEquivalentStrain(double x, double smooth_angle) |
| 1365 | { |
| 1366 | if (m_closest_normal_loc < m_equivalent_strain.size()) { |
| 1367 | // smooth only if necessary |
| 1368 | if (m_normals) { |
| 1369 | double sig = std::max(1.0e-6, smooth_angle) / 2.3546; |
| 1370 | double sden = 2.0 * sig * sig; |
| 1371 | const auto& normals = *m_normals; |
| 1372 | for (std::size_t i = 0; i < normals.size(); ++i) { |
| 1373 | double adot = std::abs(m_current_normal.dot(normals[i])); |
| 1374 | double angle = std::acos(adot); |
| 1375 | double X1 = std::exp(-std::pow(angle, 2) / sden); |
| 1376 | double X2 = std::exp(-std::pow(angle + M_PI, 2) / sden); |
| 1377 | double X3 = std::exp(-std::pow(angle - M_PI, 2) / sden); |
| 1378 | double XX = std::max(X1, std::max(X2, X3)); |
| 1379 | double EEQ = m_equivalent_strain[i]; |
| 1380 | EEQ = std::max(EEQ, x * XX); |
| 1381 | m_equivalent_strain[i] = EEQ; |
| 1382 | } |
| 1383 | } |
| 1384 | // impose the closest always |
| 1385 | double EEQ_closest = m_equivalent_strain[m_closest_normal_loc]; |
| 1386 | EEQ_closest = std::max(EEQ_closest, x); |
| 1387 | m_equivalent_strain[m_closest_normal_loc] = EEQ_closest; |
| 1388 | } |
| 1389 | } |
| 1390 | |
| 1391 | void ASDConcrete3DMaterial::CrackPlanes::reset() |
| 1392 | { |