1 //#************************************************************** 2 //# filename: UserOutput.h 3 //# 4 //# author: Yury Vetyukov 5 //# 6 //# generated: 2003 7 //# description: 8 //# remarks: 9 //# 10 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian 11 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the 12 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved. 13 //# 14 //# This file is part of HotInt. 15 //# HotInt is free software: you can redistribute it and/or modify it under the terms of 16 //# the HOTINT license. See folder 'licenses' for more details. 17 //# 18 //# bug reports are welcome!!! 19 //# WWW: www.hotint.org 20 //# email: bug_reports@hotint.org or support@hotint.org 21 //#*************************************************************************************** 22 23 #ifndef __USER_OUTPUT_H__ 24 #define __USER_OUTPUT_H__ 25 26 27 #include "ioincludes.h" 28 29 #include "WinCompDriverInterface.h" 30 31 32 #include <assert.h> 33 #include <memory.h> 34 #include <math.h> 35 36 #include "tarray.h" //+i2 37 #include "mystring.h" 38 #include "femath.h" 39 40 #include "useroutputinterface.h" 41 42 //#define ENDL "\n" 43 //const char* ENDL="\n"; 44 45 46 47 class UserOutput : public UserOutputInterface 48 { 49 char buf[100]; 50 char e_buf[100]; 51 char f_buf[100]; 52 53 int localmessagelevel; // level of message, set by UO(UO_MSGLVL), valid until next call UO() 54 int* globalmessagelevel; // global message level 55 //PG: 56 int* globalfilemessagelevel; // global log file message level 57 ofstream* logfile; // hotint logfile 58 double* critical_logfile_size; // if the file size is passing a multiple of this factor, then a warning is displayed 59 int counter_critical_logfile_size; // counts, how often a multiple of *critical_logfile_size has been exceeded 60 61 int output_precision; // output precision for the next output 62 int* oprec_double; // output precision of a double 63 int* oprec_vector; // output precision of a double number in vector (s) 64 int* oprec_matrix; // output precision of a double number in matrix (s) 65 66 int* maxerrors; // maximum number of displayed errors, linked to Solver_Options 67 int* maxwarnings; // maximum number of displayed warningss, linked to Solver_Options 68 // counters 69 int errorcount; 70 int warningcount; 71 // defaults, to be linked to options or set on access 72 int default_localmessagelevel; 73 int default_globalmessagelevel; 74 75 int default_oprec; 76 int default_oprec_double; 77 int default_oprec_vector; 78 int default_oprec_matrix; 79 80 int default_maxerror; 81 int default_maxwarnings; 82 83 // used to save the current localmessagelevel, in order to reset to this level later 84 int localmessagelevel_save; 85 86 87 public: 88 89 WCDInterface::UserInterface * pUI; 90 UserOutput()91 UserOutput() : pUI(NULL) 92 { 93 // reset counters 94 errorcount = 0; 95 warningcount = 0; 96 // defaults - valid until linked to options 97 default_localmessagelevel = UO_LVL_all; 98 default_globalmessagelevel = UO_LVL_all; 99 default_oprec = 8; 100 default_oprec_double = 8; 101 default_oprec_vector = 8; 102 default_oprec_matrix = 8; 103 default_maxerror = 100; 104 default_maxwarnings = 100; 105 106 localmessagelevel = default_localmessagelevel; 107 globalmessagelevel = &default_globalmessagelevel; 108 globalfilemessagelevel = &default_globalmessagelevel; 109 110 output_precision = default_oprec; 111 oprec_double = &default_oprec_double; 112 oprec_vector = &default_oprec_vector; 113 oprec_matrix = &default_oprec_matrix; 114 maxerrors = &default_maxerror; 115 maxwarnings = &default_maxwarnings; 116 117 logfile = NULL; 118 critical_logfile_size = NULL; 119 counter_critical_logfile_size = 0; 120 } 121 122 // sets message level at access & until next access, increases counters SetLocalMessageLevel(UO_MSGLVL message_level)123 void SetLocalMessageLevel(UO_MSGLVL message_level) 124 { 125 localmessagelevel=message_level; 126 if (localmessagelevel==UO_LVL_err) CountError(); 127 if (localmessagelevel==UO_LVL_warn) CountWarning(); 128 } 129 // sets message level at access & until next access, increases counters SetLocalMessageLevel(int message_level)130 void SetLocalMessageLevel(int message_level) { SetLocalMessageLevel( (UO_MSGLVL) message_level); } GetLocalMessageLevel()131 int GetLocalMessageLevel() { return localmessagelevel; } 132 133 // save the current localmessagelevel SaveLocalMessageLevel()134 void SaveLocalMessageLevel() 135 { 136 localmessagelevel_save = localmessagelevel; 137 } 138 //reset to the saved localmessagelevel ResetLocalMessageLevel()139 void ResetLocalMessageLevel() 140 { 141 SetLocalMessageLevel(localmessagelevel_save); 142 } 143 GetGlobalMessageLevel()144 int GetGlobalMessageLevel() { return *globalmessagelevel; } GetGlobalFileMessageLevel()145 int GetGlobalFileMessageLevel() { return *globalfilemessagelevel; } 146 SetOutputPrec(int output_prec)147 void SetOutputPrec(int output_prec) { output_precision = output_prec; } 148 149 // links UserOutput to Solver_Options, to be called after UserOutput object is created HookToSolverSettings(int * globalmessagelevel,int * globalfilemessagelevel,ofstream * logfile,double * critical_logfile_size,int * maxerrors,int * maxwarnings,int * oprec_double,int * oprec_vector,int * oprec_matrix)150 void HookToSolverSettings(int* globalmessagelevel, int* globalfilemessagelevel, ofstream* logfile, double* critical_logfile_size, 151 int* maxerrors, int* maxwarnings, int* oprec_double, int* oprec_vector, int* oprec_matrix) 152 { 153 UserOutput::globalmessagelevel = globalmessagelevel; 154 UserOutput::globalfilemessagelevel = globalfilemessagelevel; 155 UserOutput::logfile = logfile; 156 UserOutput::critical_logfile_size = critical_logfile_size; 157 UserOutput::maxerrors = maxerrors; 158 UserOutput::maxwarnings = maxwarnings; 159 UserOutput::oprec_double = oprec_double; 160 UserOutput::oprec_vector = oprec_vector; 161 UserOutput::oprec_matrix = oprec_matrix; 162 } 163 MaxErrors()164 int& MaxErrors() {return *maxerrors;} MaxWarnings()165 int& MaxWarnings() {return *maxwarnings;} 166 PrintMsg()167 int PrintMsg() // decides whether to print the message or not 168 { 169 if (pUI==NULL) return 0; // do not print in invalid UserInterface 170 if (*globalmessagelevel < localmessagelevel) return 0; // do not print when local message level is larger then global 171 if ((localmessagelevel == UO_LVL_err) && ( errorcount > (*maxerrors) )) return 0; // print no more errors 172 if ((localmessagelevel == UO_LVL_warn) && ( warningcount > (*maxwarnings) )) return 0; // print no more warnings 173 return 1; 174 } 175 //PG: PrintMsgToLogFile()176 int PrintMsgToLogFile() // decides whether to print the message to log file or not 177 { 178 if (logfile==NULL) return 0; // do not print in invalid UserInterface 179 if (*globalfilemessagelevel < localmessagelevel && *globalmessagelevel < localmessagelevel) return 0; // do not print when local message level is larger then global 180 if ((localmessagelevel == UO_LVL_err) && ( errorcount > (*maxerrors) )) return 0; // print no more errors 181 if ((localmessagelevel == UO_LVL_warn) && ( warningcount > (*maxwarnings) )) return 0; // print no more warnings 182 return 1; 183 } 184 CountError()185 void CountError() // counts errors, displays message when maxerrors is reached 186 { 187 errorcount++; 188 if (errorcount == (*maxerrors)+1) 189 { 190 pUI->AddText("Maximum number of displayed errors reached, no more Errormessages will be displayed!\n"); 191 } 192 } 193 CountWarning()194 void CountWarning() // counts warnings, displays message when maxwarnings is reached 195 { 196 warningcount++; 197 if (warningcount == (*maxwarnings)+1) 198 { 199 pUI->AddText("Maximum number of displayed warnings reached, no more Warningmessages will be displayed!\n"); 200 } 201 } 202 InstantMessageText(const char * pStr)203 virtual void InstantMessageText(const char* pStr) 204 { 205 pUI->InstantMessageText(pStr); 206 } 207 /* 208 void AddLevelTag() // On Access start line with a level tag for some 209 { 210 if (!PrintMsg()) return; 211 switch (localmessagelevel) 212 { 213 case UO_LVL_0: break; // no Output 214 case UO_LVL_err: AddText("Error: "); break; // necessary output (Errors, start/end simulation) 215 case UO_LVL_warn: AddText("Warning: "); break;// almost necessary output (Warnings) 216 case UO_LVL_ext: break; // extended output (useful information) 217 case UO_LVL_all: break; // complete information 218 case UO_LVL_dbg1: break; // debug level 1 219 case UO_LVL_dbg2: break; // debug level 2 220 default: break; 221 } 222 } 223 */ 224 //PG: 225 //void AddText(const char * pStr) 226 //{ 227 // if (!PrintMsg()) return; 228 // pUI->AddText(pStr); 229 //} 230 //void AddText(double x) 231 //{ 232 // if (!PrintMsg()) return; 233 // sprintf_s(buf,"%.*g",output_precision,x); 234 // pUI->AddText(buf); 235 //} 236 //void AddText(int x) 237 //{ 238 // if (!PrintMsg()) return; 239 // sprintf_s(buf,"%d",x); 240 // pUI->AddText(buf); 241 //} AddText(const char * pStr)242 void AddText(const char * pStr) 243 { 244 if (PrintMsg()) pUI->AddText(pStr); 245 if (PrintMsgToLogFile()) 246 { 247 (*logfile) << pStr; 248 logfile->flush(); 249 250 // print warning, if log file is exceeding critical size 251 if (*globalfilemessagelevel >= UO_LVL_warn || *globalmessagelevel >= UO_LVL_warn) 252 { 253 if (logfile->rdbuf()->pubseekoff(0,ios::end,ios::out) > (*critical_logfile_size)*(counter_critical_logfile_size + 1)*1048576.) //critical_logfile_size is given in megabytes, while pubseekoff returns size in bytes 254 { 255 counter_critical_logfile_size++; 256 int memo = localmessagelevel; 257 localmessagelevel = UO_LVL_warn; 258 AddText(mystr("WARNING: size of log file exceeds critical size of ") + mystr((*critical_logfile_size)*counter_critical_logfile_size) + mystr(" MB.\n")); 259 localmessagelevel = memo; 260 } 261 } 262 } 263 return; 264 } AddText(double x)265 void AddText(double x) 266 { 267 sprintf_s(buf,"%.*g",output_precision,x); 268 AddText(buf); 269 } AddText(int x)270 void AddText(int x) 271 { 272 sprintf_s(buf,"%d",x); 273 AddText(buf); 274 } 275 276 virtual UserOutputInterface & operator <<(const char * pStr) 277 { 278 AddText(pStr); 279 return *this; 280 } 281 virtual UserOutputInterface & operator <<(int x) 282 { 283 sprintf_s(buf,"%d",x); 284 AddText(buf); 285 return *this; 286 } 287 virtual UserOutputInterface & operator <<(double x) 288 { 289 if (output_precision==-1) output_precision = *oprec_double; 290 sprintf_s(buf,"%.*g",output_precision,x); 291 AddText(buf); 292 return *this; 293 } 294 virtual UserOutputInterface & operator <<(const Vector3D & v) 295 { 296 if (output_precision==-1) output_precision = *oprec_vector; 297 mystr str; 298 str += mystr("["); 299 str += mystr(v.X(),output_precision); 300 str += mystr(", "); 301 str += mystr(v.Y(),output_precision); 302 str += mystr(", "); 303 str += mystr(v.Z(),output_precision); 304 str += mystr("]"); 305 AddText(str.c_str()); 306 return *this; 307 } 308 virtual UserOutputInterface & operator <<(const Box3D & b) 309 { 310 if (output_precision==-1) output_precision = *oprec_vector; 311 mystr str; 312 str += mystr("["); 313 str += mystr(b.PMin().X(),output_precision); 314 str += mystr(", "); 315 str += mystr(b.PMin().Y(),output_precision); 316 str += mystr(", "); 317 str += mystr(b.PMin().Z(),output_precision); 318 str += mystr("] - ["); 319 str += mystr(b.PMax().X(),output_precision); 320 str += mystr(", "); 321 str += mystr(b.PMax().Y(),output_precision); 322 str += mystr(", "); 323 str += mystr(b.PMax().Z(),output_precision); 324 str += mystr("]"); 325 AddText(str.c_str()); 326 return *this; 327 } 328 virtual UserOutputInterface & operator <<(const Vector2D & v) 329 { 330 if (output_precision==-1) output_precision = *oprec_vector; 331 mystr str; 332 str += mystr("["); 333 str += mystr(v.X(),output_precision); 334 str += mystr(", "); 335 str += mystr(v.Y(),output_precision); 336 str += mystr("]"); 337 AddText(str.c_str()); 338 return *this; 339 } 340 virtual UserOutputInterface & operator <<(const Vector & v) 341 { 342 if (output_precision==-1) output_precision = *oprec_vector; 343 mystr str; 344 if (v.GetLen()<=70) 345 { 346 str+=mystr("["); 347 for (int i=1; i<v.GetLen(); i++) 348 { 349 str+=mystr(v(i),output_precision); 350 str+=mystr(", "); 351 } 352 if (v.GetLen()!=0) 353 { 354 str+=mystr(v(v.GetLen()),output_precision); 355 } 356 str+=mystr("]"); 357 } 358 else 359 { 360 361 str+=mystr("["); 362 for (int i=1; i<=v.GetLen(); i++) 363 { 364 str+=mystr(v(i),output_precision); 365 if (i!=v.GetLen()) {str+=mystr(", ");} 366 if (i%16==0 && i!=v.GetLen()) {str+=mystr("\n col("); str+=mystr(i); str+=mystr( "): ");} 367 } 368 str+=mystr("]"); 369 370 } 371 AddText(str.c_str()); 372 return *this; 373 } 374 375 virtual UserOutputInterface & operator <<(const IVector & v) 376 { 377 if (output_precision==-1) output_precision = *oprec_vector; 378 mystr str; 379 if (v.Length()<=70) 380 { 381 str+=mystr("["); 382 for (int i=1; i<v.Length(); i++) 383 { 384 str+=mystr(v(i)); 385 str+=mystr(", "); 386 } 387 if (v.Length()!=0) 388 { 389 str+=mystr(v(v.Length())); 390 } 391 str+=mystr("]"); 392 } 393 else 394 { 395 str+=mystr("["); 396 for (int i=1; i<=v.Length(); i++) 397 { 398 str+=mystr(v(i)); 399 if (i!=v.Length()) {str+=mystr(", ");} 400 if (i%16==0 && i!=v.Length()) {str+=mystr("\n col("); str+=mystr(i); str+=mystr( "): ");} 401 } 402 str+=mystr("]"); 403 404 } 405 AddText(str.c_str()); 406 return *this; 407 } 408 409 virtual UserOutputInterface & operator <<(const TArray<double> & v) 410 { 411 if (output_precision==-1) output_precision = *oprec_vector; 412 mystr str; 413 if (v.Length()<=70) 414 { 415 str+=mystr("["); 416 for (int i=1; i<v.Length(); i++) 417 { 418 str+=mystr(v(i),output_precision); 419 str+=mystr(", "); 420 } 421 if (v.Length()!=0) 422 { 423 str+=mystr(v(v.Length()),output_precision); 424 } 425 str+=mystr("]"); 426 } 427 else 428 { 429 430 str+=mystr("["); 431 for (int i=1; i<=v.Length(); i++) 432 { 433 str+=mystr(v(i),output_precision); 434 if (i!=v.Length()) {str+=mystr(", ");} 435 if (i%16==0 && i!=v.Length()) {str+=mystr("\n col("); str+=mystr(i); str+=mystr( "): ");} 436 } 437 str+=mystr("]"); 438 439 } 440 AddText(str.c_str()); 441 return *this; 442 } 443 444 445 virtual UserOutputInterface & operator <<(const SparseVector & v) 446 { 447 if (output_precision==-1) output_precision = *oprec_vector; 448 mystr str; 449 if (v.GetLen()<=70) 450 { 451 str+=mystr("["); 452 for (int i=1; i<v.GetLen(); i++) 453 { 454 str+=mystr(v(i),output_precision); 455 str+=mystr(", "); 456 } 457 if (v.GetLen()!=0) 458 { 459 str+=mystr(v(v.GetLen()),output_precision); 460 } 461 str+=mystr("]"); 462 } else 463 { 464 465 str+=mystr("["); 466 for (int i=1; i<=v.GetLen(); i++) 467 { 468 str+=mystr(v(i),output_precision); 469 if (i!=v.GetLen()) {str+=mystr(", ");} 470 if (i%16==0 && i!=v.GetLen()) {str+=mystr("\n col("); str+=mystr(i); str+=mystr( "): ");} 471 } 472 str+=mystr("]"); 473 474 } 475 AddText(str.c_str()); 476 return *this; 477 } 478 479 virtual UserOutputInterface & operator <<(const Matrix3D & m) 480 { 481 if (output_precision==-1) output_precision = *oprec_matrix; 482 mystr str; 483 for (int i=0; i < m.Getrows(); i++) 484 { 485 str+=mystr("["); 486 for (int j=0; j < m.Getcols()-1; j++) 487 { 488 str+=mystr(m.Get0(i,j),output_precision); 489 str+=", "; 490 } 491 str+=mystr(m.Get0(i,m.Getcols()-1),output_precision); 492 str+="]\n"; 493 } 494 AddText(str.c_str()); 495 return *this; 496 } 497 498 virtual UserOutputInterface & operator <<(const Matrix & m) 499 { 500 if (output_precision==-1) output_precision = *oprec_matrix; 501 mystr str; 502 double max = m.MaxNorm(); 503 int i; 504 505 if (max==0) {max=1;} 506 max=(int)log10(max); 507 max=pow(10,max); 508 509 str+=mystr(max,output_precision); 510 str+=mystr(" *\n"); 511 512 for (i=1; i<=m.Getrows(); i++) 513 { 514 str+=mystr("["); 515 for (int j=1; j<=m.Getcols(); j++) 516 { 517 char str1[32]; 518 sprintf_s(str1,"% 1.*f",output_precision,m(i,j)/max); 519 str+=mystr(str1); 520 521 if (j!=m.Getcols()) {str+=mystr(",");} 522 } 523 str+=mystr("]\n"); 524 } 525 AddText(str.c_str()); 526 return *this; 527 } 528 529 virtual UserOutputInterface & operator <<(const SparseMatrix & m) 530 { 531 if (output_precision==-1) output_precision = *oprec_matrix; 532 mystr str; 533 double max = m.MaxNorm(); 534 int i; 535 536 if (max==0) {max=1;} 537 max=(int)log10(max); 538 max=pow(10,max); 539 540 str+=mystr(max); str+=mystr(" *\n"); 541 542 for (i=1; i<=m.Getrows(); i++) 543 { 544 str+=mystr("["); 545 for (int j=1; j<=m.Getcols(); j++) 546 { 547 char str1[32]; 548 sprintf_s(str1,"% 1.*f",output_precision,m(i,j)/max); 549 str+=mystr(str1); 550 551 if (j!=m.Getcols()) {str+=mystr(",");} 552 } 553 str+=mystr("]\n"); 554 } 555 AddText(str.c_str()); 556 return *this; 557 } 558 559 virtual int CallWCDriverFunction(int action, int option = 0, int value = 0, ElementDataContainer* edc = NULL) 560 { 561 return pUI->CallWCDriverFunction(action, option, value, edc); 562 } 563 }; 564 565 566 #endif // __USER_OUTPUT_H__