Skip to content

Commit 5f991ed

Browse files
committed
PASSMO-NL: stress prediction at Gauss points
1 parent 5abe6f6 commit 5f991ed

File tree

12 files changed

+142
-112
lines changed

12 files changed

+142
-112
lines changed

femutils/ArcaneFemFunctions.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
using namespace Arcane;
3030
using namespace Arcane::FemUtils;
31-
31+
Real REL_PREC{1.0e-15};
3232
/*---------------------------------------------------------------------------*/
3333
/**
3434
* @brief Contains various functions & operations related to FEM calculations.
@@ -1436,7 +1436,7 @@ class ArcaneFemFunctions
14361436
/**
14371437
* @brief Provides methods based on the Dispatcher mechanism available in Arcane,
14381438
* allowing to compute FEM methods without declaring the FE entity type
1439-
* (coming fro PASSMO).
1439+
* (coming from PASSMO).
14401440
*/
14411441
/*---------------------------------------------------------------------------*/
14421442
class CellFEMDispatcher
@@ -1464,7 +1464,7 @@ class ArcaneFemFunctions
14641464
* This class includes static methods for computing shape functions and their
14651465
* derivatives depending on finite element types. These methods are used within
14661466
* the Dispatcher mechanism available in Arcane through the class
1467-
* CellFEMDispatcher (coming fro PASSMO).
1467+
* CellFEMDispatcher (coming from PASSMO).
14681468
*/
14691469
/*---------------------------------------------------------------------------*/
14701470
class FemShapeMethods
@@ -2560,7 +2560,7 @@ class ArcaneFemFunctions
25602560
* @brief Provides methods for Gauss quadrature.
25612561
*
25622562
* This class includes static methods for computing Gauss-Legendre integration
2563-
* depending on finite element types (coming fro PASSMO).
2563+
* depending on finite element types (coming from PASSMO).
25642564
*/
25652565
/*---------------------------------------------------------------------------*/
25662566
class FemGaussQuadrature

femutils/FemUtils.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <arcane/MeshVariableArrayRef.h>
3131
/*---------------------------------------------------------------------------*/
3232
/*---------------------------------------------------------------------------*/
33-
extern Arcane::Real REL_PREC;
3433

3534
struct Real4
3635
{
@@ -631,8 +630,9 @@ class Tensor2
631630

632631
//! Define the == operator
633632
ARCCORE_HOST_DEVICE bool operator==(const Tensor2& vec) {
633+
Real eps{1.0e-15};
634634
for (Arcane::Int32 i = 0; i < 6; ++i) {
635-
if (fabs(m_vec(i) - vec(i)) > REL_PREC)
635+
if (fabs(m_vec(i) - vec(i)) > eps)
636636
return false;
637637
}
638638
return true;
@@ -792,6 +792,14 @@ class Tensor2
792792
return sqrt(dot(m_vec,m_vec));
793793
}
794794

795+
//! Function to convert Real3x3 matrix (symmetric) to Tensor
796+
ARCCORE_HOST_DEVICE void fromReal3x3ToTensor2(const Real3x3& mat) {
797+
for (Arcane::Int32 i = 0; i < 3; i++) (*this)(i) = mat[i][i];
798+
for (Arcane::Int32 i = 3; i < 5; i++) (*this)(i) = mat[0][i - 2];
799+
(*this)(5) = mat[1][2];
800+
}
801+
802+
795803
//! Friend function for scalar multiplication: scalar * Tensor
796804
ARCCORE_HOST_DEVICE friend Tensor2 operator*(Real scalar, const Tensor2& vector) {
797805
Tensor2 result;

modules/passmo/ElastodynamicModule.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
/*---------------------------------------------------------------------------*/
3030
using namespace Arcane;
3131
using namespace Arcane::FemUtils;
32+
extern Real REL_PREC;
3233
/*---------------------------------------------------------------------------*/
3334
/*---------------------------------------------------------------------------*/
3435
ElastodynamicModule::ElastodynamicModule(const ModuleBuildInfo& mbi)
@@ -521,14 +522,16 @@ compute(){
521522
// Update the nodal variable according to the integration scheme (e.g. Newmark)
522523
_updateNewmark();
523524

524-
525+
/*
525526
if (t < tf) {
526527
if (t + dt > tf) {
527528
dt = tf - t;
528529
m_global_deltat = dt;
529530
}
530531
}
531532
else {
533+
*/
534+
if (t >= tf) {
532535
// Save/Check results
533536
_checkResultFile();
534537
subDomain()->timeLoopMng()->stopComputeLoop(true);
@@ -546,7 +549,7 @@ _checkResultFile()
546549
if (filename.empty())
547550
return;
548551
const double epsilon = 1.0e-4;
549-
const double min_value_to_test = 1.0e-10;
552+
const double min_value_to_test = 1.0e-16;
550553
Arcane::FemUtils::checkNodeResultFile(traceMng(), filename, m_displ, epsilon, min_value_to_test);
551554
}
552555
/*---------------------------------------------------------------------------*/

modules/passmonl/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ add_executable(Passmonl
44
NLDynamicModule.h
55
NLDynamicModule.cc
66
main.cc
7+
utilFEM.h
8+
utilFEM.cc
9+
LawDispatcher.h
10+
LawDispatcher.cc
711
analytic_func.cc
812
analytical_func.h
9-
utilFEM.h
1013
hooke.cc
1114
druckerp.cc
12-
LawDispatcher.h
13-
LawDispatcher.cc
14-
utilFEM.cc
1515
)
1616

1717
arcane_generate_axl(NLDynamic)

modules/passmonl/LawDispatcher.cc

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,20 @@ LawDispatcher::LawDispatcher(TypesNLDynamic::eLawType law_type, bool default_par
9393
//! Initialize intern useful constants allowing to the material constitutive model type
9494
m_init_consts[TypesNLDynamic::HOOKE] = HookeInitConsts;
9595
m_init_consts[TypesNLDynamic::DRUCKP] = DruckPInitConsts;
96+
97+
switch(law_type){
98+
99+
case TypesNLDynamic::UNKNOWN:
100+
case TypesNLDynamic::HOOKE: m_nb_law_param = 2;
101+
break;
102+
103+
case TypesNLDynamic::DRUCKP:
104+
case TypesNLDynamic::MOHRC: m_nb_law_param = 7;
105+
break;
106+
107+
default: m_nb_law_param = 2;
108+
break;
109+
}
96110
}
97111

98112
/////////////////////////////////////////////////////////////////////////////
@@ -228,24 +242,22 @@ RealUniqueArray LawDispatcher::initConsts(RealConstArrayView& law_params)
228242

229243
/*---------------------------------------------------------------------------*/
230244
/*---------------------------------------------------------------------------*/
231-
void ReadLawBlock(istream& is, Integer nblock){
245+
void ReadLawBlock(istream& is, Integer nblock) {
246+
232247
char c[500];
233248
String str;
234-
bool stop { false};
235-
String s_end_b{"</"};
236-
237-
for (Integer i = 0; i < nblock; ++i){
238-
239-
if (!i) {
240-
is >> str;
241-
is.getline(c, 500); // read until end of line "\n"
242-
stop = (str.contains(s_end_b));
243-
}
244-
245-
while(!stop) {
246-
is >> str;
247-
is.getline(c, 500); // read until end of line "\n"
248-
stop = (str.contains(s_end_b));
249+
bool stop{ false };
250+
String str_nblock = String::fromNumber(nblock);
251+
String sblock = String("<") + str_nblock + String(">");
252+
253+
do {
254+
255+
is.getline(c, 500); // read whole line
256+
std::istringstream iss(c);
257+
String token;
258+
while (iss >> token) {
259+
if (token.contains(sblock))
260+
stop = true;
249261
}
250-
}
262+
} while(!stop);
251263
}

modules/passmonl/LawDispatcher.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,15 @@ class LawDispatcher {
6868
[[nodiscard]] Tensor2 getStrainIncrement() const;
6969
void setStrainIncrement(const Tensor2&);
7070

71+
[[nodiscard]] Integer getNbLawParam() const { return m_nb_law_param; }
72+
7173
void setLambda(Real lambda) { m_Lambda = lambda; }
7274
void setMu(Real mu) { m_Mu = mu; }
7375
void setName(const String& name) { m_name = name; }
7476
void setDefault(bool is_default) { m_default = is_default; }
77+
void setLawParams(const RealUniqueArray& lawparams) {
78+
m_law_params = lawparams.clone();
79+
}
7580

7681
private:
7782
std::function<Tensor4(RealConstArrayView& law_params, RealArrayView& history_vars, Tensor2& sig, Tensor2& eps, Tensor2& epsp, Tensor2& dsig,
@@ -84,6 +89,7 @@ class LawDispatcher {
8489
std::function<RealUniqueArray(RealConstArrayView& law_params)> m_init_consts[NB_LAW_TYPE];
8590

8691
Tensor2 m_sig{};
92+
Tensor2 m_sign{};
8793
Tensor2 m_eps{};
8894
Tensor2 m_dsig{};
8995
Tensor2 m_epsp{};
@@ -97,6 +103,7 @@ class LawDispatcher {
97103
TypesNLDynamic::eLawType m_law_type{TypesNLDynamic::HOOKE};
98104
String m_name{};
99105
bool m_default{true};
106+
Integer m_nb_law_param{2};
100107
};
101108

102109
#endif //PASSMO_LAWDISPATCHER_H

modules/passmonl/NLDynamicModule.cc

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "IDoFLinearSystemFactory.h"
2525
#include "ArcaneFemFunctions.h"
2626
#include "NLDynamicModule.h"
27+
#include "LawDispatcher.h"
2728

2829
/*---------------------------------------------------------------------------*/
2930
/*---------------------------------------------------------------------------*/
@@ -455,9 +456,9 @@ _applyInitialCellConditions(){
455456
for (Integer i = 0, nb = options()->lawModel().size(); i < nb; ++i){
456457

457458
CellGroup cell_group = options()->lawModel[i]->cellGroup();
458-
Integer ilaw = options()->lawModel[i]->iLawParam();
459-
TypesNLDynamic::eLawType lawtyp = options()->lawModel[i]->lawType();
460-
Integer nblaw = options()->lawModel[i]->nbLawParam();
459+
auto ilaw = options()->lawModel[i]->iLawParam();
460+
auto lawtyp = options()->lawModel[i]->lawType();
461+
auto nblaw = options()->lawModel[i]->nbLawParam();
461462
m_nb_law_param = math::max(m_nb_law_param, nblaw);
462463

463464
bool is_default = (m_law_param_file.empty() || nblaw == 2);
@@ -552,6 +553,7 @@ _applyInitialCellConditions(){
552553
void NLDynamicModule::
553554
_initGaussStep()
554555
{
556+
Real eps{1.0e-15};
555557
auto gauss_point(m_gauss_on_cells.gaussCellConnectivityView());
556558

557559
VariableDoFReal& gauss_jacobian(m_gauss_on_cells.gaussJacobian());
@@ -597,7 +599,7 @@ _initGaussStep()
597599
else
598600
jacobian = ArcaneFemFunctions::MeshOperation::computeLengthEdge2(cell, m_node_coord) / 2.;
599601

600-
if (fabs(jacobian) < REL_PREC) {
602+
if (fabs(jacobian) < eps) {
601603
ARCANE_FATAL("Cell jacobian is null");
602604
}
603605
gauss_jacobian[gauss_pti] = jacobian;
@@ -1583,6 +1585,7 @@ Real3x3 NLDynamicModule::
15831585
_computeJacobian(const ItemWithNodes& cell,const Int32& ig, const RealUniqueArray& vec, Real& jacobian) {
15841586

15851587
auto n = cell.nbNode();
1588+
Real eps{1.0e-15};
15861589

15871590
// Jacobian matrix computed at the integration point
15881591
Real3x3 jac;
@@ -1602,17 +1605,16 @@ _computeJacobian(const ItemWithNodes& cell,const Int32& ig, const RealUniqueArra
16021605
}
16031606

16041607
Int32 ndim = ArcaneFemFunctions::MeshOperation::getGeomDimension(cell);
1605-
// if (NDIM == 3)
1608+
16061609
if (ndim == 3)
16071610
jacobian = math::matrixDeterminant(jac);
16081611

1609-
// else if (NDIM == 2) {
16101612
else if (ndim == 2)
16111613
jacobian = jac.x.x * jac.y.y - jac.x.y * jac.y.x;
16121614
else
16131615
jacobian = ArcaneFemFunctions::MeshOperation::computeLengthEdge2(cell, m_node_coord) / 2.;
16141616

1615-
if (fabs(jacobian) < REL_PREC) {
1617+
if (fabs(jacobian) < eps) {
16161618
ARCANE_FATAL("Cell jacobian is null");
16171619
}
16181620
return jac;
@@ -2343,19 +2345,73 @@ _assembleLinearRHS(){
23432345
/*---------------------------------------------------------------------------*/
23442346
// ! Stress prediction
23452347
//
2346-
bool NLDynamicModule::stress_prediction(bool init, bool isRef)
2348+
void NLDynamicModule::stress_prediction(bool init, bool isRef)
23472349
{
2348-
bool stop = false;
2349-
return stop;
2350+
auto gauss_point(m_gauss_on_cells.gaussCellConnectivityView());
2351+
2352+
VariableDoFArrayReal3x3& gauss_stress(m_gauss_on_cells.gaussStress());
2353+
VariableDoFArrayReal3x3& gauss_strain(m_gauss_on_cells.gaussStrain());
2354+
VariableDoFArrayReal3x3& gauss_strain_plastic(m_gauss_on_cells.gaussStrainPlastic());
2355+
VariableDoFArrayReal& gauss_lawparam(m_gauss_on_cells.gaussLawParam());
2356+
2357+
ENUMERATE_CELL (icell, allCells()) {
2358+
const Cell& cell = *icell;
2359+
auto cell_type = cell.type();
2360+
auto cell_nbnod = cell.nbNode();
2361+
Int32 numcell = cell.localId();
2362+
2363+
auto is_default = m_default_law[cell];
2364+
auto lawtyp = static_cast<TypesNLDynamic::eLawType>(m_law[cell]);
2365+
auto ilaw = m_iparam_law[cell];
2366+
LawDispatcher cell_law(lawtyp, is_default);
2367+
auto nblaw = cell_law.getNbLawParam();
2368+
RealUniqueArray lawparams(nblaw);
2369+
2370+
auto cell_nbgauss = ArcaneFemFunctions::FemGaussQuadrature::getNbGaussPointsfromOrder(cell_type, ninteg);
2371+
2372+
for (Int32 ig = 0; ig < cell_nbgauss; ++ig) {
2373+
DoFLocalId gauss_pti = gauss_point.dofId(cell, ig);
2374+
Int32 gaussnum = gauss_pti.localId();
2375+
2376+
Tensor2 epsn;
2377+
epsn.fromReal3x3ToTensor2(gauss_strain[gauss_pti][1]);
2378+
Tensor2 sign;
2379+
sign.fromReal3x3ToTensor2(gauss_stress[gauss_pti][1]);
2380+
Tensor2 epspn;
2381+
epspn.fromReal3x3ToTensor2(gauss_strain_plastic[gauss_pti][1]);
2382+
Tensor2 deps;
2383+
{
2384+
// calcul deps à faire avec unodes
2385+
}
2386+
2387+
for (Int32 ip = 0; ip < nblaw; ++ip) {
2388+
lawparams[ip] = gauss_lawparam[gauss_pti][ip];
2389+
}
2390+
cell_law.setLawParams(lawparams);
2391+
cell_law.setStrain(epsn);
2392+
cell_law.setStress(sign);
2393+
cell_law.setPlasticStrain(epspn);
2394+
cell_law.setStrainIncrement(deps);
2395+
2396+
// bool isRef = false at prediction
2397+
// => it avoids computing tangent stiffness operator
2398+
cell_law.computeStress(isRef);
2399+
2400+
// Current plastic strains and stresses have been updated by the law
2401+
gauss_strain_plastic[gauss_pti][2] = fromTensor2Real3x3(cell_law.getPlasticStrain());
2402+
gauss_stress[gauss_pti][2] = fromTensor2Real3x3(cell_law.getStress());
2403+
gauss_strain[gauss_pti][2] = fromTensor2Real3x3(epsn + deps);
2404+
2405+
}
2406+
}
23502407
}
2408+
23512409
/*---------------------------------------------------------------------------*/
23522410
/*---------------------------------------------------------------------------*/
23532411
// ! Stress correction
23542412
//
2355-
bool NLDynamicModule::stress_correction(bool is_converge)
2413+
void NLDynamicModule::stress_correction(bool isRef)
23562414
{
2357-
bool stop = false;
2358-
return stop;
23592415
}
23602416

23612417
/*---------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)