OOFEM 3.0
Loading...
Searching...
No Matches
errorcheckingexportmodule.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include <vector>
36#include <cstdio>
37#include <iostream>
38
40#include "engngm.h"
41#include "domain.h"
42#include "node.h"
43#include "element.h"
44#include "timestep.h"
45#include "classfactory.h"
46#include "dof.h"
47#include "oofemtxtinputrecord.h"
48#ifdef _USE_XML
49 #include "xmlinputrecord.h"
50 #include "xmldatareader.h"
51#endif
52#include "mathfem.h"
53#ifdef __SM_MODULE
57#endif
58
59namespace oofem {
61
62
63bool
64ErrorCheckingRule :: checkValue(double computedValue)
65{
66 return computedValue >= value - tolerance && computedValue <= value + tolerance;
67}
68
69
70NodeErrorCheckingRule :: NodeErrorCheckingRule(const std :: string &line, double tol) :
72{
73/*
74 char unknown;
75 std :: string kwd;
76 OOFEMTXTInputRecord rec (0, line), *ptr = &rec;
77 rec.giveRecordKeywordField(kwd);
78 if (kwd == "#NODE") {
79 IR_GIVE_FIELD (ptr,tstep, "tStep");
80 IR_GIVE_OPTIONAL_FIELD (ptr,tsubstep, "tStepVer");
81 IR_GIVE_FIELD (ptr,number, "number");
82 IR_GIVE_FIELD (ptr,dofid, "dofid");
83 IR_GIVE_FIELD (ptr,unknown, "unknown");
84 IR_GIVE_FIELD (ptr,value, "value");
85 IR_GIVE_OPTIONAL_FIELD (ptr,tolerance, "tolerance");
86 } else {
87 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
88 }
89*/
90 char unknown;
91 int ret = std :: sscanf(line.c_str(), "#NODE tStep %d number %d dof %d unknown %c value %le tolerance %le",
92 &tstep, & number, & dofid, & unknown, & value, & tolerance);
93 if ( ret < 2 ) {
94 ret = std :: sscanf(line.c_str(), "#NODE tStep %d tStepVer %d number %d dof %d unknown %c value %le tolerance %le",
95 &tstep, &tsubstep, & number, & dofid, & unknown, & value, & tolerance);
96 }
97 if ( ret < 5 ) {
98 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
99 }
100
101 if ( unknown == 'd' ) {
102 mode = VM_Total;
103 } else if ( unknown == 'v' ) {
104 mode = VM_Velocity;
105 } else if ( unknown == 'a' ) {
106 mode = VM_Acceleration;
107 } else {
108 OOFEM_ERROR("Can't recognize unknown '%c'", unknown);
109 }
110}
111
112NodeErrorCheckingRule :: NodeErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol){
113 std::string unknown;
114 ir.giveField(tstep,"tStep");
115 ir.giveOptionalField(tsubstep,"tStepVer");
116 ir.giveField(number,"number");
117 ir.giveField(dofid,"dof");
118 ir.giveField(unknown,"unknown");
119 ir.giveField(value,"value");
120 ir.giveOptionalField(tolerance,"tolerance");
121 if ( unknown == "d" ) {
122 mode = VM_Total;
123 } else if ( unknown == "v" ) {
124 mode = VM_Velocity;
125 } else if ( unknown == "a" ) {
126 mode = VM_Acceleration;
127 } else {
128 OOFEM_ERROR("Can't recognize unknown '%s' (must be one of: d, v, a)", unknown.c_str());
129 }
130}
131
132bool
133NodeErrorCheckingRule :: getValue(double &answer, Domain *domain, TimeStep *tStep)
134{
135 DofManager *dman = domain->giveGlobalDofManager(number);
136 if ( !dman ) {
137 if ( domain->giveEngngModel()->isParallel() ) {
138 return false;
139 } else {
140 OOFEM_WARNING("Dof manager %d not found.", number);
141 return false;
142 }
143 }
144
146 return false;
147 }
148
149 Dof *dof = dman->giveDofWithID(dofid);
150 answer = dof->giveUnknown(mode, tStep);
151 return true;
152}
153
154
155bool
156NodeErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
157{
158 // Rule doesn't apply yet.
159 if ( tStep->giveNumber() != tstep || tStep->giveVersion() != tsubstep ) {
160 return true;
161 }
162
163 DofManager *dman = domain->giveGlobalDofManager(number);
164 if ( !dman ) {
165 if ( domain->giveEngngModel()->isParallel() ) {
166 return true;
167 } else {
168 OOFEM_WARNING("Dof manager %d not found.", number);
169 return false;
170 }
171 }
172
174 return true;
175 }
176
177 Dof *dof = dman->giveDofWithID(dofid);
178
179 double dmanValue = dof->giveUnknown(mode, tStep);
180 bool check = checkValue(dmanValue);
181 if ( !check ) {
182 OOFEM_WARNING("Check failed in %s: tstep %d, node %d, dof %d, mode %d:\n"
183 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
185 dmanValue, value, fabs(dmanValue-value), tolerance );
186 }
187 return check;
188}
189
190
193{
194 char unknown;
195 int ret = std :: sscanf(line.c_str(), "#ELEMENTNODE tStep %d number %d dofman %d dof %d unknown %c value %le tolerance %le",
196 &tstep, & number, &idofman, & dofid, & unknown, & value, & tolerance);
197 if ( ret < 5 ) {
198 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
199 }
200
201 if ( unknown == 'd' ) {
202 mode = VM_Total;
203 } else if ( unknown == 'v' ) {
204 mode = VM_Velocity;
205 } else if ( unknown == 'a' ) {
206 mode = VM_Acceleration;
207 } else {
208 OOFEM_ERROR("Can't recognize unknown '%c'", unknown);
209 }
210}
211
213 std::string unknown;
214 ir.giveField(tstep,"tStep");
215 ir.giveField(number,"number");
216 ir.giveField(idofman,"dofman");
217 ir.giveField(dofid,"dof");
218 ir.giveField(unknown,"unknown");
219 ir.giveField(value,"value");
220 if(unknown=="d") mode=VM_Total;
221 else if(unknown=="v") mode=VM_Velocity;
222 else if(unknown=="a") mode=VM_Acceleration;
223 else OOFEM_ERROR("Can't recognize unknown '%s' (must be one of: d, v, a)",unknown.c_str());
224}
225
226
227bool
228InternalElementDofManErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
229{
230 // Rule doesn't apply yet.
231 if ( tStep->giveNumber() != tstep || tStep->giveVersion() != tsubstep ) {
232 return true;
233 }
234
235 Element *element = domain->giveGlobalElement(number);
236 if ( !element ) {
237 if ( domain->giveEngngModel()->isParallel() ) {
238 return true;
239 } else {
240 OOFEM_WARNING("Element %d not found.", number);
241 return false;
242 }
243 }
244 if ( element->giveParallelMode() != Element_local ) {
245 return true;
246 }
247 DofManager *dman = element->giveInternalDofManager(idofman);
248 if ( !dman ) {
249 OOFEM_WARNING("Internal DofManager %d on element %d not found.", idofman, number);
250 return false;
251 }
252
253 Dof *dof = dman->giveDofWithID(dofid);
254
255 double dmanValue = dof->giveUnknown(mode, tStep);
256 bool check = checkValue(dmanValue);
257 if ( !check ) {
258 OOFEM_WARNING("Check failed in %s: tstep %d, node %d, dof %d, mode %d:\n"
259 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
261 dmanValue, value, fabs(dmanValue-value), tolerance );
262 }
263 return check;
264}
265
266bool
267InternalElementDofManErrorCheckingRule :: getValue(double &answer, Domain *domain, TimeStep *tStep)
268{
269 Element *element = domain->giveGlobalElement(number);
270 if ( !element ) {
271 if ( domain->giveEngngModel()->isParallel() ) {
272 return false;
273 } else {
274 OOFEM_WARNING("Element %d not found.", number);
275 return false;
276 }
277 }
278 if ( element->giveParallelMode() != Element_local ) {
279 return false;
280 }
281 DofManager *dman = element->giveInternalDofManager(idofman);
282 if ( !dman ) {
283 OOFEM_WARNING("Internal DofManager %d on element %d not found.", idofman, number);
284 return false;
285 }
286
287 Dof *dof = dman->giveDofWithID(dofid);
288
289 answer = dof->giveUnknown(mode, tStep);
290 return true;
291}
292
293ElementErrorCheckingRule :: ElementErrorCheckingRule(const std :: string &line, double tol) :
294 ErrorCheckingRule(tol), irule(0)
295{
296 int istnum;
297 int ret = std :: sscanf(line.c_str(), "#ELEMENT tStep %d number %d irule %d gp %d keyword %d component %d value %le tolerance %le",
298 &tstep, & number, & irule, & gpnum, & istnum, & component, & value, & tolerance);
299 if ( ret < 2 ) {
300 ret = std :: sscanf(line.c_str(), "#ELEMENT tStep %d tStepVer %d number %d irule %d gp %d keyword %d component %d value %le tolerance %le",
301 &tstep, &tsubstep, & number, & irule, & gpnum, & istnum, & component, & value, & tolerance);
302 if (ret < 4) {
303 ret = std :: sscanf(line.c_str(), "#ELEMENT tStep %d tStepVer %d number %d gp %d keyword %d component %d value %le tolerance %le",
304 &tstep, &tsubstep, & number, & gpnum, & istnum, & component, & value, & tolerance);
305 }
306 } else if ( ret < 3 ) {
307 ret = std :: sscanf(line.c_str(), "#ELEMENT tStep %d number %d gp %d keyword %d component %d value %le tolerance %le",
308 &tstep, & number, & gpnum, & istnum, & component, & value, & tolerance);
309 }
310 if ( ret < 6 ) {
311 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
312 }
313 ist = (InternalStateType)istnum;
314}
315
316ElementErrorCheckingRule :: ElementErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol) {
317 ir.giveField(tstep,"tStep");
318 ir.giveOptionalField(tsubstep,"tStepVer");
319 ir.giveField(number,"number");
320 ir.giveOptionalField(irule,"irule");
321 ir.giveField(gpnum,"gp");
322 int istnum;
323 ir.giveField(istnum,"keyword");
324 ist = (InternalStateType)istnum;
325 ir.giveField(component,"component");
326 ir.giveField(value,"value");
327 ir.giveOptionalField(tolerance,"tolerance");
328}
329
330bool
331ElementErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
332{
333 // Rule doesn't apply yet.
334 if ( tStep->giveNumber() != tstep || tStep->giveVersion() != tsubstep ) {
335 return true;
336 }
337
338 FloatArray ipval;
339 Element *element = domain->giveGlobalElement(number);
340 // std::cerr<<"Element "<<number<<" @ "<<(void*)element<<std::endl;
341 if ( !element ) {
342 if ( domain->giveEngngModel()->isParallel() ) {
343 return true;
344 } else {
345 OOFEM_WARNING("Element %d not found.", number);
346 return false;
347 }
348 }
349 if ( element->giveParallelMode() != Element_local ) {
350 return true;
351 }
352
353 // note! GPs are numbered from 0 internally, but written with 1-index, inconsistent!
355 element->giveIPValue(ipval, gp, ist, tStep);
356
357 if ( component > ipval.giveSize() || component < 1 ) {
358 OOFEM_WARNING("Check failed in %s: element %d, gpnum %d, ist %d, component %d:\n"
359 "Component not found!",
361 ipval.printYourself();
362 return false;
363 }
364
365 double elementValue = ipval.at(component);
366 bool check = checkValue(elementValue);
367 if ( !check ) {
368 OOFEM_WARNING("Check failed in %s: tstep %d, element %d, gpnum %d, ist %d, component %d:\n" "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
370 elementValue, value, fabs(elementValue-value), tolerance );
371 ipval.printYourself();
372 }
373 return check;
374}
375
376
377bool
378ElementErrorCheckingRule :: getValue(double & answer, Domain *domain, TimeStep *tStep)
379{
380 FloatArray ipval;
381 Element *element = domain->giveGlobalElement(number);
382 if ( !element ) {
383 if ( domain->giveEngngModel()->isParallel() ) {
384 return false;
385 } else {
386 OOFEM_WARNING("Element %d not found.", number);
387 return false;
388 }
389 }
390 if ( element->giveParallelMode() != Element_local ) {
391 return false;
392 }
393
394 // note! GPs are numbered from 0 internally, but written with 1-index, inconsistent!
396 element->giveIPValue(ipval, gp, ist, tStep);
397
398 if ( component > ipval.giveSize() || component < 1 ) {
399 OOFEM_WARNING("Check failed in %s: element %d, gpnum %d, ist %d, component %d:\n"
400 "Component not found!",
402 ipval.printYourself();
403 return false;
404 }
405
406 answer = ipval.at(component);
407 return true;
408}
409
410
411BeamElementErrorCheckingRule :: BeamElementErrorCheckingRule(const std :: string &line, double tol) :
413{
414 int istnum;
415 int ret = std :: sscanf(line.c_str(), "#BEAM_ELEMENT tStep %d number %d keyword %d component %d value %le tolerance %le",
416 &tstep, & number, & istnum, & component, & value, & tolerance);
417 if ( ret < 2 ) {
418 ret = std :: sscanf(line.c_str(), "#BEAM_ELEMENT tStep %d tStepVer %d number %d keyword %d component %d value %le tolerance %le",
419 &tstep, &tsubstep, & number, & istnum, & component, & value, & tolerance);
420 }
421 if ( ret < 5 ) {
422 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
423 }
425}
426
427BeamElementErrorCheckingRule :: BeamElementErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol) {
428 ir.giveField(tstep,"tStep");
429 ir.giveOptionalField(tsubstep,"tStepVer");
430 ir.giveField(number,"number");
431 int istnum;
432 ir.giveField(istnum,"keyword");
434 ir.giveField(component,"component");
435 ir.giveField(value,"value");
436 ir.giveOptionalField(tolerance,"tolerance");
437}
438
439bool
440BeamElementErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
441{
442 // Rule doesn't apply yet.
443 if ( tStep->giveNumber() != tstep || tStep->giveVersion() != tsubstep ) {
444 return true;
445 }
446
447 FloatArray val;
448 Element *element = domain->giveGlobalElement(number);
449 if ( !element ) {
450 if ( domain->giveEngngModel()->isParallel() ) {
451 return true;
452 } else {
453 OOFEM_WARNING("Element %d not found.", number);
454 return false;
455 }
456 }
457 if ( element->giveParallelMode() != Element_local ) {
458 return true;
459 }
460
462 element->computeVectorOf(VM_Total, tStep, val);
463 } else if (ist == BET_localEndForces) {
464#ifdef __SM_MODULE
465 if(Beam2d* b = dynamic_cast<Beam2d*>(element)) b->giveEndForcesVector(val, tStep);
466 else if(Beam3d* b = dynamic_cast<Beam3d*>(element)) b->giveEndForcesVector(val, tStep);
467 else {
468 OOFEM_WARNING("Element %d has no beam interface.", number);
469 return false;
470 }
471#else
472 OOFEM_WARNING("Element %d has no beam interface.", number);
473 return false;
474#endif
475 }
476
477 if ( component > val.giveSize() || component < 1 ) {
478 OOFEM_WARNING("Check failed in %s: beam_element %d, ist %d, component %d:\n"
479 "Component not found!",
481 val.printYourself();
482 return false;
483 }
484
485 double elementValue = val.at(component);
486 bool check = checkValue(elementValue);
487 if ( !check ) {
488 OOFEM_WARNING("Check failed in %s: tstep %d, beam_element %d, ist %d, component %d:\n"
489 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
491 elementValue, value, fabs(elementValue-value), tolerance );
492 val.printYourself();
493 }
494 return check;
495}
496
497
498bool
499BeamElementErrorCheckingRule :: getValue(double& answer, Domain *domain, TimeStep *tStep)
500{
501 FloatArray val;
502 Element *element = domain->giveGlobalElement(number);
503 if ( !element ) {
504 if ( domain->giveEngngModel()->isParallel() ) {
505 return false;
506 } else {
507 OOFEM_WARNING("Element %d not found.", number);
508 return false;
509 }
510 }
511 if ( element->giveParallelMode() != Element_local ) {
512 return false;
513 }
514
516 element->computeVectorOf(VM_Total, tStep, val);
517 } else if (ist == BET_localEndForces) {
518#ifdef __SM_MODULE
519 if(Beam2d* b = dynamic_cast<Beam2d*>(element)) b->giveEndForcesVector(val, tStep);
520 else if(Beam3d* b = dynamic_cast<Beam3d*>(element)) b->giveEndForcesVector(val, tStep);
521 else {
522 OOFEM_WARNING("Element %d has no beam interface.", number);
523 return false;
524 }
525#else
526 OOFEM_WARNING("Element %d has no beam interface.", number);
527 return false;
528#endif
529 }
530
531 if ( component > val.giveSize() || component < 1 ) {
532 OOFEM_WARNING("Check failed in %s: beam_element %d, ist %d, component %d:\n"
533 "Component not found!",
535 val.printYourself();
536 return false;
537 }
538
539 answer = val.at(component);
540 return true;
541}
542
543
544ReactionErrorCheckingRule :: ReactionErrorCheckingRule(const std :: string &line, double tol) :
546{
547 int ret = std :: sscanf(line.c_str(), "#REACTION tStep %d number %d dof %d value %le tolerance %le",
548 &tstep, & number, & dofid, & value, & tolerance);
549 if ( ret < 2 ) {
550 ret = std :: sscanf(line.c_str(), "#REACTION tStep %d tStepVer %d number %d dof %d value %le tolerance %le",
551 &tstep, &tsubstep, & number, & dofid, & value, & tolerance);
552 }
553 if ( ret < 4 ) {
554 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
555 }
556}
557
558ReactionErrorCheckingRule :: ReactionErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol) {
559 ir.giveField(tstep,"tStep");
560 ir.giveOptionalField(tsubstep,"tStepVer");
561 ir.giveField(number,"number");
562 ir.giveField(dofid,"dof");
563 ir.giveField(value,"value");
564 ir.giveOptionalField(tolerance,"tolerance");
565}
566
567bool
568ReactionErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
569{
570 // Rule doesn't apply yet.
571 if ( tStep->giveNumber() != tstep || tStep->giveVersion() != tsubstep ) {
572 return true;
573 }
574
575#ifdef __SM_MODULE
576 //EngngModel *emodel = domain->giveEngngModel();
577 StructuralEngngModel *emodel = static_cast< StructuralEngngModel* >( domain->giveEngngModel() );
580 //std :: map< int, std :: map< int, double > > reactionForces; // reactionForces[nodeNumber][dofid] like this
581 //emodel->computeReaction(std :: reactionForces, tStep, domain->giveNumber());
582 FloatArray reactionForces;
583 IntArray restrDofMans, restrDofs, eqn;
584 emodel->buildReactionTable(restrDofMans, restrDofs, eqn, tStep, domain->giveNumber());
585 emodel->computeReaction(reactionForces, tStep, domain->giveNumber());
586
587 bool found = false;
588 int index;
589 for ( index = 1; index <= restrDofs.giveSize(); ++index ) {
590 if ( restrDofs.at(index) == dofid && domain->giveNode(restrDofMans.at(index))->giveLabel() == number ) {
591 found = true;
592 break;
593 }
594 }
595 if ( !found ) {
596 if ( domain->giveEngngModel()->isParallel() ) {
597 return true;
598 } else {
599 OOFEM_WARNING("Reaction force node: %d dof: %d not found.", number, dofid);
600 return false;
601 }
602 }
603
604 double reactionForce = reactionForces.at(index);
605 bool check = checkValue(reactionForce);
606 if ( !check ) {
607 OOFEM_WARNING("Check failed in %s: tstep %d, reaction forces number %d, dof %d:\n"
608 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
610 reactionForce, value, fabs(reactionForce-value), tolerance );
611 }
612 return check;
613#else
614 OOFEM_WARNING("Reaction forces only supported for structural problems yet");
615 return false;
616#endif
617}
618
619bool
620ReactionErrorCheckingRule :: getValue(double &answer, Domain *domain, TimeStep *tStep)
621{
622
623#ifdef __SM_MODULE
624 //EngngModel *emodel = domain->giveEngngModel();
625 StructuralEngngModel *emodel = static_cast< StructuralEngngModel* >( domain->giveEngngModel() );
628 //std :: map< int, std :: map< int, double > > reactionForces; // reactionForces[nodeNumber][dofid] like this
629 //emodel->computeReaction(std :: reactionForces, tStep, domain->giveNumber());
630 FloatArray reactionForces;
631 IntArray restrDofMans, restrDofs, eqn;
632 emodel->buildReactionTable(restrDofMans, restrDofs, eqn, tStep, domain->giveNumber());
633 emodel->computeReaction(reactionForces, tStep, domain->giveNumber());
634
635 bool found = false;
636 int index;
637 for ( index = 1; index <= restrDofs.giveSize(); ++index ) {
638 if ( restrDofs.at(index) == dofid && domain->giveNode(restrDofMans.at(index))->giveLabel() == number ) {
639 found = true;
640 break;
641 }
642 }
643 if ( !found ) {
644 if ( domain->giveEngngModel()->isParallel() ) {
645 return false;
646 } else {
647 OOFEM_WARNING("Reaction force node: %d dof: %d not found.", number, dofid);
648 return false;
649 }
650 }
651
652 answer = reactionForces.at(index);
653 return true;
654#else
655 OOFEM_WARNING("Reaction forces only supported for structural problems yet");
656 return false;
657#endif
658}
659
660LoadLevelErrorCheckingRule :: LoadLevelErrorCheckingRule(const std :: string &line, double tol) :
662{
663 int ret = std :: sscanf(line.c_str(), "#LOADLEVEL tStep %d value %le tolerance %le",
664 &tstep, & value, & tolerance);
665 if ( ret < 2 ) {
666 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
667 }
668}
669
670LoadLevelErrorCheckingRule :: LoadLevelErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol) {
671 ir.giveField(tstep,"tStep");
672 ir.giveField(value,"value");
673 ir.giveOptionalField(tolerance,"tolerance");
674}
675
676
677bool
678LoadLevelErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
679{
680 // Rule doesn't apply yet.
681 if ( tStep->giveNumber() != tstep ) {
682 return true;
683 }
684
685 double loadLevel = domain->giveEngngModel()->giveLoadLevel();
686 bool check = checkValue(loadLevel);
687 if ( !check ) {
688 OOFEM_WARNING("Check failed in %s: tstep %d, load level:\n"
689 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
690 domain->giveEngngModel()->giveOutputBaseFileName().c_str(), tstep,
691 loadLevel, value, fabs(loadLevel-value), tolerance );
692 }
693 return check;
694}
695
696bool
697LoadLevelErrorCheckingRule :: getValue(double& answer, Domain *domain, TimeStep *tStep)
698{
699
700 answer = domain->giveEngngModel()->giveLoadLevel();
701 return true;
702}
703
704EigenValueErrorCheckingRule :: EigenValueErrorCheckingRule(const std :: string &line, double tol) :
706{
707 int ret = std :: sscanf(line.c_str(), "#EIGVAL tStep %d EigNum %d value %le tolerance %le",
708 &tstep, & number, & value, & tolerance);
709 if ( ret < 3 ) {
710 OOFEM_ERROR("Something wrong in the error checking rule: %s\n", line.c_str());
711 }
712}
713
714EigenValueErrorCheckingRule :: EigenValueErrorCheckingRule(InputRecord& ir, double tol): ErrorCheckingRule(tol) {
715 ir.giveField(tstep,"tStep");
716 ir.giveField(number,"EigNum");
717 ir.giveField(value,"value");
718 ir.giveOptionalField(tolerance,"tolerance");
719}
720
721bool
722EigenValueErrorCheckingRule :: check(Domain *domain, TimeStep *tStep)
723{
724 // Rule doesn't apply yet.
725 if ( tStep->giveNumber() != tstep ) {
726 return true;
727 }
728
729 double eig = domain->giveEngngModel()->giveEigenValue(number);
730 bool check = checkValue(eig);
731 if ( !check ) {
732 OOFEM_WARNING("Check failed in %s: tstep %d, eigen value %d:\n"
733 "value is %.8e, but should be %.8e ( error is %e but tolerance is %e )",
734 domain->giveEngngModel()->giveOutputBaseFileName().c_str(), tstep, number,
735 eig, value, fabs(eig-value), tolerance );
736 }
737 return check;
738}
739bool
740EigenValueErrorCheckingRule :: getValue(double&answer, Domain *domain, TimeStep *tStep)
741{
742 answer = domain->giveEngngModel()->giveEigenValue(number);
743 return true;
744}
745
746TimeCheckingRule :: TimeCheckingRule(const std :: string &line, double tol) :
748{
749}
750
752
753bool
754TimeCheckingRule :: check(Domain *domain, TimeStep *tStep)
755{
756 return true;
757}
758bool
759TimeCheckingRule :: getValue(double&answer, Domain *domain, TimeStep *tStep)
760{
761 answer = tStep->giveTargetTime();
762 return true;
763}
764
765
766
768
769
770ErrorCheckingExportModule :: ErrorCheckingExportModule(int n, EngngModel *e) : ExportModule(n, e)
771{
772}
773
774void
775ErrorCheckingExportModule :: initializeFrom(InputRecord &ir)
776{
777 ExportModule :: initializeFrom(ir);
778
779 allPassed = true;
780 this->errorCheckingRules.clear();
781
782 filename = std::string("");
783
786 }
787 else {
788 filename = emodel->giveReferenceFileName();
789 }
790 #ifdef _USE_XML
791 /* we need to cast to XMLInputRecord just to get the reader object */
792 XMLInputRecord* xmlrec=dynamic_cast<XMLInputRecord*>(&ir);
793 if(xmlrec) this->readRulesFromRecords(*(xmlrec->giveReader()),ir);
794 else
795 #endif
796 this->readRulesFromTextFile(ir);
797
798 this->writeIST.clear();
800 if ( writeChecks ) {
802 }
803
804 if ( errorCheckingRules.size() == 0 && !writeChecks ) {
805 OOFEM_WARNING("No rules found (possibly wrong file or syntax).");
806 }
807
809}
810
812 // Reads all the rules;
813 std :: ifstream inputStream(this->filename);
814 if ( !inputStream ) {
815 throw ValueInputException(ir, _IFT_ErrorCheckingExportModule_filename, "Couldn't open file");
816 }
817 double tol = 0.;
818 if ( this->scanToErrorChecks(inputStream, tol) ) {
819 for (;;) {
820 std :: unique_ptr< ErrorCheckingRule > rule = this->giveErrorCheck(inputStream, tol);
821 if ( !rule ) {
822 break;
823 }
824 errorCheckingRules.push_back(std :: move(rule));
825 }
826 }
827}
828
830 double tol=1e-6;
831 ir.giveOptionalField(tol,"tolerance");
833 for(auto& rir: ruleRecs){
834 std::string n;
835 rir.giveRecordKeywordField(n);
836 // std::cerr<<"Check rule of type "<<n<<std::endl;
837 std::unique_ptr<ErrorCheckingRule> rule;
838 if (n=="NODE") { rule=std::make_unique<NodeErrorCheckingRule>(rir,tol); }
839 if (n=="ELEMENT") { rule=std::make_unique<ElementErrorCheckingRule>(rir,tol); }
840 if (n=="REACTION") { rule=std::make_unique<ReactionErrorCheckingRule>(rir,tol); }
841 if (n=="BEAM_ELEMENT") { rule=std::make_unique<BeamElementErrorCheckingRule>(rir,tol); }
842 if (n=="EIGVAL") { rule=std::make_unique<EigenValueErrorCheckingRule>(rir,tol); }
843 if (n=="LOADLEVEL") { rule=std::make_unique<LoadLevelErrorCheckingRule>(rir,tol); }
844 if (n=="TIME") { rule=std::make_unique<TimeCheckingRule>(rir,tol); }
845 if (n=="ELEMENTNODE") { rule=std::make_unique<InternalElementDofManErrorCheckingRule>(rir,tol); }
846 if(rule) errorCheckingRules.push_back(std::move(rule));
847 else { std::cerr<<"No rule for "<<n<<" created (not yet implemented for XML?)."<<std::endl; }
848 }
849}
850
851
852void
853ErrorCheckingExportModule :: doOutput(TimeStep *tStep, bool forcedOutput)
854{
855#if 0
856 if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
857 return;
858 }
859#endif
860
861 if (!this->extractorMode) {
862 // Error checking rules are hardcoded to domain 1 always.
863 Domain *domain = emodel->giveDomain(1);
864
865 OOFEM_LOG_INFO("Checking rules...\n");
866 for ( auto &rule: this->errorCheckingRules ) {
867 this->allPassed &= rule->check(domain, tStep);
868 }
869
870 if ( !tStep->isNotTheLastStep() ) {
871 if ( !this->allPassed ) {
872 OOFEM_ERROR("Rule not passed, exiting with error");
873 }
874 }
875
876 if ( this->writeChecks ) {
877 this->writeCheck(domain, tStep);
878 }
879 } else {
880
881 // Error checking rules are hardcoded to domain 1 always.
882 Domain *domain = emodel->giveDomain(1);
883
884 double value;
885 for ( auto &rule: this->errorCheckingRules ) {
886 bool result = rule->getValue(value, domain, tStep);
887 if (result) {
888 fprintf (outputFile, "%+12.8e ", value);
889 } else {
890 fprintf (outputFile, "%12s","-");
891 }
892 }
893 fprintf(outputFile, "\n");
894 }
895}
896
897void
899{
900 if (this->extractorMode) {
901 char filename [100];
902 sprintf( filename, "%s.m%d", this->emodel->giveOutputBaseFileName().c_str(), this->number);
903 this->outputFile = fopen(filename, "w");
904 }
905}
906
908{
909 if (this->extractorMode) {
910 fclose (this->outputFile);
911 }
912}
913
914
915void
916ErrorCheckingExportModule :: writeCheck(Domain *domain, TimeStep *tStep)
917{
918 if ( tStep->isTheFirstStep() ) {
919 std :: cout << "#%BEGIN_CHECK% tolerance 1.e-3\n";
920 }
921
922 for ( auto &dman : domain->giveDofManagers() ) {
923 for ( Dof *dof: *dman ) {
924 if ( dof->giveEqn() < 0 ) {
925 continue;
926 }
927 std :: cout << "#NODE tStep " << tStep->giveNumber();
928 std :: cout << " number " << dman->giveNumber();
929 std :: cout << " dof " << dof->giveDofID();
930 std :: cout << " unknown " << 'd';
931 std :: cout << " value " << dof->giveUnknown(VM_Total, tStep);
932 std :: cout << std :: endl;
933 }
934 }
935
936 for ( auto &element : domain->giveElements() ) {
937 IntegrationRule *iRule = element->giveDefaultIntegrationRulePtr();
938 FloatArray ipval;
939 for ( int ist: this->writeIST ) {
940 for ( int gpnum = 0; gpnum < iRule->giveNumberOfIntegrationPoints(); ++gpnum ){
941 GaussPoint *gp = iRule->getIntegrationPoint(gpnum);
942 element->giveIPValue(ipval, gp, (InternalStateType)ist, tStep);
943 for ( int component = 1; component <= ipval.giveSize(); ++component ) {
944 std :: cout << "#ELEMENT tStep " << tStep->giveNumber();
945 std :: cout << " number " << element->giveNumber();
946 std :: cout << " gp " << gpnum+1;
947 std :: cout << " keyword " << ist;
948 std :: cout << " component " << component;
949 std :: cout << " value " << ipval.at(component);
950 std :: cout << std :: endl;
951 }
952 }
953 }
954 }
955
956 if ( !tStep->isNotTheLastStep() ) {
957 std :: cout << "#%END_CHECK%" << std :: endl;
958 }
959}
960
961
962bool
963ErrorCheckingExportModule :: scanToErrorChecks(std :: ifstream &stream, double &errorTolerance)
964{
965 while ( !stream.eof() ) {
966 std :: string line;
967 std :: getline(stream, line);
968 if ( line.compare(0, 14, "#%BEGIN_CHECK%") == 0 ) {
969 errorTolerance = 1e-6;
970 if ( line.size() >= 25 ) {
971 errorTolerance = std :: stod( line.substr(25) );
972 }
973 return true;
974 }
975 }
976 return false;
977}
978
979std::unique_ptr<ErrorCheckingRule>
980ErrorCheckingExportModule :: giveErrorCheck(std :: ifstream &stream, double errorTolerance)
981{
982 std :: string line;
983 while ( !stream.eof() ) {
984 std :: getline(stream, line);
985 if ( line.compare(0, 12, "#%END_CHECK%") == 0 ) {
986 return NULL;
987 }
988 if (line.size() > 2 && line[0] == '#' && line[1] != '#') {
989 break;
990 }
991
992 }
993
994 if ( line.compare(0, 5, "#NODE") == 0 ) {
995 return std::make_unique<NodeErrorCheckingRule>(line, errorTolerance);
996 } else if ( line.compare(0, 12, "#ELEMENTNODE") == 0 ) {
997 return std::make_unique<InternalElementDofManErrorCheckingRule>(line, errorTolerance);
998 } else if ( line.compare(0, 8, "#ELEMENT") == 0 ) {
999 return std::make_unique<ElementErrorCheckingRule>(line, errorTolerance);
1000 } else if ( line.compare(0, 13, "#BEAM_ELEMENT") == 0 ) {
1001 return std::make_unique<BeamElementErrorCheckingRule>(line, errorTolerance);
1002 } else if ( line.compare(0, 9, "#REACTION") == 0 ) {
1003 return std::make_unique<ReactionErrorCheckingRule>(line, errorTolerance);
1004 } else if ( line.compare(0, 10, "#LOADLEVEL") == 0 ) {
1005 return std::make_unique<LoadLevelErrorCheckingRule>(line, errorTolerance);
1006 } else if ( line.compare(0, 7, "#EIGVAL") == 0 ) {
1007 return std::make_unique<EigenValueErrorCheckingRule>(line, errorTolerance);
1008 } else if ( line.compare(0, 5, "#TIME") == 0 ) {
1009 return std::make_unique<TimeCheckingRule>(line, errorTolerance);
1010 } else {
1011 OOFEM_ERROR("Unsupported rule '%s'", line.c_str());
1012 }
1013}
1014
1015} // end namespace oofem
#define REGISTER_ExportModule(class)
bool check(Domain *domain, TimeStep *tStep) override
Internal range-like class, return type for giveGroupRecords methods.
Definition datareader.h:137
GroupRecords giveGroupRecords(const std::shared_ptr< InputRecord > &ir, InputFieldType ift, const std::string &name, InputRecordType irType, bool optional)
Definition datareader.C:46
int giveLabel() const
Definition dofmanager.h:516
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
dofManagerParallelMode giveParallelMode() const
Definition dofmanager.h:526
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
DofManager * giveGlobalDofManager(int n)
Definition domain.C:329
Element * giveGlobalElement(int n)
Definition domain.C:176
int giveNumber()
Returns domain number.
Definition domain.h:281
std ::vector< std ::unique_ptr< DofManager > > & giveDofManagers()
Definition domain.h:427
Node * giveNode(int n)
Definition domain.h:398
EngngModel * giveEngngModel()
Definition domain.C:419
std ::vector< std ::unique_ptr< Element > > & giveElements()
Definition domain.h:294
bool check(Domain *domain, TimeStep *tStep) override
bool check(Domain *domain, TimeStep *tStep) override
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
virtual IntegrationRule * giveIntegrationRule(int i)
Definition element.h:899
elementParallelMode giveParallelMode() const
Definition element.h:1139
virtual DofManager * giveInternalDofManager(int i) const
Definition element.h:249
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Definition element.C:1298
std::string giveOutputBaseFileName()
Definition engngm.h:386
virtual double giveLoadLevel()
Returns the current load level.
Definition engngm.h:553
virtual double giveEigenValue(int eigNum)
Only relevant for eigen value analysis. Otherwise returns zero.
Definition engngm.h:556
bool isParallel() const
Returns true if receiver in parallel mode.
Definition engngm.h:1152
std::unique_ptr< ErrorCheckingRule > giveErrorCheck(std ::ifstream &stream, double errorTolerance)
void writeCheck(Domain *domain, TimeStep *tStep)
void readRulesFromRecords(DataReader &dr, InputRecord &ir)
std ::vector< std ::unique_ptr< ErrorCheckingRule > > errorCheckingRules
bool scanToErrorChecks(std ::ifstream &stream, double &errorTolerance)
bool checkValue(double computedValue)
ExportModule(int n, EngngModel *e)
Constructor. Creates empty Output Manager with number n.
EngngModel * emodel
Problem pointer.
bool testTimeStepOutput(TimeStep *tStep)
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
virtual void printYourself() const
Definition floatarray.C:762
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
void giveOptionalField(T &answer, InputFieldType id)
virtual void giveField(int &answer, InputFieldType id)=0
Reads the integer field value.
DataReader * giveReader() const
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
int giveNumberOfIntegrationPoints() const
GaussPoint * getIntegrationPoint(int n)
bool check(Domain *domain, TimeStep *tStep) override
InternalElementDofManErrorCheckingRule(const std ::string &line, double tol)
bool check(Domain *domain, TimeStep *tStep) override
bool check(Domain *domain, TimeStep *tStep) override
bool check(Domain *domain, TimeStep *tStep) override
void buildReactionTable(IntArray &restrDofMans, IntArray &restrDofs, IntArray &eqn, TimeStep *tStep, int di)
void computeReaction(FloatArray &answer, TimeStep *tStep, int di)
TimeCheckingRule(const std ::string &line, double tol)
int giveVersion()
Returns receiver's version.
Definition timestep.h:148
double giveTargetTime()
Returns target time.
Definition timestep.h:164
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
bool isTheFirstStep()
Definition timestep.C:148
bool isNotTheLastStep()
Definition timestep.C:142
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define _IFT_ErrorCheckingExportModule_writeIST
Which internal state types to write rules for.
#define _IFT_ErrorCheckingExportModule_filename
Filename where rules are defined (normally the input file).
#define _IFT_ErrorCheckingExportModule_extractormode
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
const double tolerance
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
std::pair< FloatArrayF< N >, FloatMatrixF< N, N > > eig(const FloatMatrixF< N, N > &mat, int nf=9)
@ DofManager_null
Definition dofmanager.h:74
@ DofManager_remote
Definition dofmanager.h:71
@ unknown
Definition drawmode.h:40

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011