v0.16.3
Loading...
Searching...
No Matches
EshelbianTestingMonitor.cpp
Go to the documentation of this file.
1/** @file
2 @brief Contains definition of EshelbianTestingMonitor class.
3 @ingroup EshelbianPlasticty
4*/
5
7 using SetPtsData = FieldEvaluatorInterface::SetPtsData;
8
10 boost::shared_ptr<EshelbianMonitor> base_monitor_ptr)
11 : baseMonitorPtr(base_monitor_ptr), eP(baseMonitorPtr->getEpCore()),
12 ptsHashMap(baseMonitorPtr->getHashMap()),
13 reactionForcesMap(baseMonitorPtr->getReactionMap()),
14 gEnergy(baseMonitorPtr->getEnergy()),
15 dataFieldEval(baseMonitorPtr->getDataField()) {
16
17 PetscBool test_cook_flg = PETSC_FALSE;
18 PetscInt atom_test = 0;
19 CHK_THROW_MESSAGE(PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook_pts",
20 &test_cook_flg, PETSC_NULLPTR),
21 "get post proc points");
22 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atom_test,
23 PETSC_NULLPTR);
24
25 if (test_cook_flg) {
26 ptsHashMap["Point A"] = {48., 60., 4.999};
27 ptsHashMap["Point B"] = {48. / 2., 44. + (60. - 44.) / 2., 0.};
28 ptsHashMap["Point C"] = {48. / 2., (44. - 0.) / 2., 0.};
29 }
30 if (atom_test == 14) {
31 // Points for atom test 14: check external strain
32 ptsHashMap["Point (2.5, 0., 0.)"] = {2.5, 0, 0.};
33 }
34 }
35
36 MoFEMErrorCode preProcess() { return 0; }
37
38 MoFEMErrorCode operator()() { return 0; }
39
40 MoFEMErrorCode postProcess() {
42
43 MOFEM_LOG("EP", Sev::inform) << "Testing Monitor postProcess";
44
45 PetscInt atom_test = 0;
46 char reaction_block_name[255] = "FIX_ALL";
47 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atom_test,
48 PETSC_NULLPTR);
49 CHKERR PetscOptionsGetString(PETSC_NULLPTR, "", "-atom_test_reaction_block",
50 reaction_block_name, 255, PETSC_NULLPTR);
51
52 switch (atom_test) {
53 case 14:
54 // Points for external strain
55 for (auto &pts : ptsHashMap) {
56 CHKERR checkExternalStrain(pts.second, pts.first, atom_test);
57 }
58 break;
59 case 15:
60 if (ts_t > 0.0) {
61 // L = 5, ty = tz = 1, A = 1, UDL Top face 0.1,
62 // Moment at x = 0 should be 0.25.
63 if (std::abs(reactionForcesMap[reaction_block_name][5] - 0.25) > 1e-3) {
65 SETERRQ(
66 PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
67 "Atom test 15 failed: reaction moment does not match expected "
68 "value. Got [%3.6e], expected [0.25].",
69 reactionForcesMap[reaction_block_name][5]);
70 }
71 }
72 break;
73 case 16:
74 if (ts_t > 0.0) {
75 // L = 5, ty = tz = 1, A = 1, E = 1000 * exp(0.1*x), u = 0.1, F = 1000 *
76 // 0.1/(1-exp(-0.5)) = 25.4149, so reaction force should
77 // be -25.4149
78 if (std::abs(reactionForcesMap[reaction_block_name][0] - (-25.4149)) >
79 1e-4) {
81 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
82 "Atom test 16 failed: reaction force does not match expected "
83 "value. Got [%3.6e, %3.6e, %3.6e], expected [-25.4149, 0.0, "
84 "0.0].",
85 reactionForcesMap[reaction_block_name][0],
86 reactionForcesMap[reaction_block_name][1],
87 reactionForcesMap[reaction_block_name][2]);
88 }
89 }
90 break;
91 case 17:
92 if (ts_t > 0.0) {
93 if (std::abs(*gEnergy - 1.27096) > 1e-5) {
95 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
96 "Atom test 17 failed: strain energy does not match expected "
97 "value. Got %3.6e, expected 1.27096.",
98 *gEnergy);
99 }
100 }
101 break;
102 case 18:
103 if (ts_step == 7) {
104 if (std::abs(eP.loadFactor - 16.0393) > 1e-5) {
106 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
107 "Atom test 18 failed: load factor does not match expected "
108 "value. Got %3.6e, expected 16.093.",
109 eP.loadFactor);
110 }
111 }
112 break;
113 case 19:
114 if (ts_t > 0.0) {
115 if (std::abs(reactionForcesMap["SPRING_BC"][2] - 2.016e1) > 1e-3) {
117 SETERRQ(
118 PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
119 "Atom test 19 failed: reaction force does not match expected "
120 "value. Got [%3.6e], expected [2.016e1].",
121 reactionForcesMap["SPRING_BC"][2]);
122 }
123 }
124 break;
125 case 20:
126 if (ts_t > 0.0) {
127 // cook.jou: end face height 16, thickness 5. The COOK traction
128 // profile is 4*eta*(1-eta), with eta=(y-44)/16 and load scale t.
129 // Its integral is 16*5*(2/3)*t, balanced by the clamp y reaction.
130 const double expected_reaction = -(160.0 / 3.0) * ts_t;
131 const double reaction = reactionForcesMap[reaction_block_name][1];
132 if (!(std::abs(reaction - expected_reaction) <= 1e-7)) {
134 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
135 "Atom test 20 failed: Cook clamp reaction does not balance "
136 "the applied traction. Got %.12g, expected %.12g.",
137 reaction, expected_reaction);
138 }
139 MOFEM_LOG_C("EP", Sev::inform,
140 "Cook cantilever reaction balance passed at time %g", ts_t);
141 }
142 break;
143 default:
144 break;
145 }
146
148 }
149
150 MoFEMErrorCode checkExternalStrain(std::array<double, 3> point,
151 std::string str, PetscInt atom_test);
152
153 protected:
154 boost::shared_ptr<EshelbianMonitor> baseMonitorPtr;
156 std::map<std::string, std::array<double, 6>> &reactionForcesMap;
157 boost::shared_ptr<SetPtsData> dataFieldEval;
158 std::map<std::string, std::array<double, 3>> &ptsHashMap;
159 boost::shared_ptr<double> gEnergy;
160};
161
163 std::array<double, 3> point, std::string str, PetscInt atom_test) {
165
166 dataFieldEval->setEvalPoints(point.data(), point.size() / 3);
167 auto vec = createVectorMPI(eP.mField.get_comm(), 1, 1);
168 auto w_l2_at_pts = eP.dataAtPts->getSmallWL2AtPts();
169 w_l2_at_pts->resize(0, 0, false);
170
171 if (auto fe_ptr = dataFieldEval->feMethodPtr) {
172 CHKERR eP.mField.getInterface<FieldEvaluatorInterface>()
173 ->evalFEAtThePoint<SPACE_DIM>(
174 point.data(), 1e-12, problemPtr->getName(), "EP", dataFieldEval,
176 MF_EXIST, QUIET);
177 }
178 if (w_l2_at_pts->size1() == 0 || w_l2_at_pts->size2() == 0) {
179 CHKERR VecSetValue(vec, 0, 0.0, ADD_VALUES);
180 } else if (w_l2_at_pts->size1() == 1 || w_l2_at_pts->size2() == 1) {
181 auto add = [&]() {
182 std::ostringstream s;
183 s << str << " elem " << getFEEntityHandle() << " ";
184 return s.str();
185 };
186 MOFEM_LOG("EPSYNC", Sev::inform)
187 << add() << "comm rank " << eP.mField.get_comm_rank();
188 MOFEM_LOG("EPSYNC", Sev::inform)
189 << add() << "point " << getVectorAdaptor(point.data(), 3);
190 MOFEM_LOG("EPSYNC", Sev::inform)
191 << add() << "w " << *w_l2_at_pts;
192 double disp_at_point = (*w_l2_at_pts)(0, 0);
193 CHKERR VecSetValue(vec, 0, disp_at_point, ADD_VALUES);
194 } else {
195 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
196 "Unexpected displacement data shape (%ld, %ld).",
197 static_cast<long>(w_l2_at_pts->size1()),
198 static_cast<long>(w_l2_at_pts->size2()));
199 }
200
202 if (ts_t > 0.0) {
203 CHKERR VecAssemblyBegin(vec);
204 CHKERR VecAssemblyEnd(vec);
205 double error;
206 PetscInt idx = 0;
207 if (eP.mField.get_comm_rank() == 0) {
208 CHKERR VecGetValues(vec, 1, &idx, &error);
209 }
210 MPI_Bcast(&error, 1, MPI_DOUBLE, 0, PETSC_COMM_WORLD);
211 // Check if the displacement is correct for the applied external
212 // strain For the bar problem, we expect a displacement of 0.25 at
213 // point A
214 if (std::abs(error - 0.25) > 1e-5) {
215 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
216 "Atom test %d failed: wrong displacement %.12g.", atom_test,
217 error);
218 }
219 }
221}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
@ QUIET
@ MF_EXIST
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
MoFEM::Interface & mField
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
std::map< std::string, std::array< double, 3 > > & ptsHashMap
boost::shared_ptr< double > gEnergy
boost::shared_ptr< EshelbianMonitor > baseMonitorPtr
std::map< std::string, std::array< double, 6 > > & reactionForcesMap
EshelbianTestingMonitor(EshelbianCore &ep, boost::shared_ptr< EshelbianMonitor > base_monitor_ptr)
boost::shared_ptr< SetPtsData > dataFieldEval
MoFEMErrorCode checkExternalStrain(std::array< double, 3 > point, std::string str, PetscInt atom_test)
FieldEvaluatorInterface::SetPtsData SetPtsData
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
int atom_test
Atom test.
Definition plastic.cpp:121