OOFEM 3.0
Loading...
Searching...
No Matches
util.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 "util.h"
36#include "engngm.h"
37#include "classfactory.h"
38#include "inputrecord.h"
39#include "datareader.h"
40#include "error.h"
41
42#include <cstring>
43#include <cmath>
44#if defined ( __GNUC__ ) && defined ( HAVE_EXECINFO_H )
45#include <cxxabi.h>
46#include <execinfo.h>
47#include <cstdio>
48#include <cstdlib>
49#endif
50
51#include <iostream>
52#include <iomanip>
53#ifdef _WIN32
54 #include <io.h>
55 #define isatty _isatty
56 #define fileno _fileno
57#else
58 #include <unistd.h>
59#endif
60
61namespace oofem {
62
63void print_stacktrace(FILE *out, int skip, unsigned int max_frames)
64{
65#if defined ( __GNUC__ ) && defined ( HAVE_EXECINFO_H )
66#if 0
67 // Much simpler example from SO
68 void *trace_elems[max_frames];
69 int trace_elem_count(backtrace( trace_elems, max_frames ));
70 char **stack_syms(backtrace_symbols( trace_elems, trace_elem_count ));
71 for ( int i = 0 ; i < trace_elem_count ; ++i ) {
72 std::cout << stack_syms[i] << "\n";
73 }
74 free( stack_syms );
75#endif
76 // Taken from https://idlebox.net/2008/0901-stacktrace-demangled/ which indicated free usage.
77 int addrlen = 0;
78 fprintf(out, "stack trace:\n");
79
80 // storage array for stack trace address data
81 void *addrlist [ max_frames + 1 ];
82
83 // retrieve current stack addresses
84 addrlen = backtrace( addrlist, sizeof( addrlist ) / sizeof( void * ) );
85 if ( addrlen == 0 ) {
86 fprintf(out, " <empty, possibly corrupt>\n");
87 return;
88 }
89
90 // resolve addresses into strings containing "filename(function+address)",
91 // this array must be free()-ed
92 char **symbollist;
93 symbollist = backtrace_symbols(addrlist, addrlen);
94 // allocate string which will be filled with the demangled function name
95 size_t funcnamesize = 256;
96 char *funcname = ( char * ) malloc(funcnamesize);
97
98 // iterate over the returned symbol lines. skip the first, it is the
99 // address of this function.
100 for ( int i = skip+1; i < addrlen; i++ ) {
101 char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
102
103 // find parentheses and +address offset surrounding the mangled name:
104 // ./module(function+0x15c) [0x8048a6d]
105 for ( char *p = symbollist [ i ]; * p; ++p ) {
106 if ( * p == '(' ) {
107 begin_name = p;
108 } else if ( * p == '+' ) {
109 begin_offset = p;
110 } else if ( * p == ')' && begin_offset ) {
111 end_offset = p;
112 break;
113 }
114 }
115
116 if ( begin_name && begin_offset && end_offset &&
117 begin_name < begin_offset ) {
118 * begin_name++ = '\0';
119 * begin_offset++ = '\0';
120 * end_offset = '\0';
121
122 // mangled name is now in [begin_name, begin_offset) and caller
123 // offset in [begin_offset, end_offset). now apply
124 // __cxa_demangle():
125
126 int status;
127 char *ret = abi :: __cxa_demangle(begin_name,
128 funcname, & funcnamesize, & status);
129 if ( status == 0 ) {
130 funcname = ret; // use possibly realloc()-ed string
131 fprintf(out, " %s : %s+%s\n",
132 symbollist [ i ], funcname, begin_offset);
133 } else {
134 // demangling failed. Output function name as a C function with
135 // no arguments.
136 fprintf(out, " %s : %s()+%s\n",
137 symbollist [ i ], begin_name, begin_offset);
138 }
139 } else {
140 // couldn't parse the line? print the whole line.
141 fprintf(out, " %s\n", symbollist [ i ]);
142 }
143 }
144
145 free(funcname);
146 free(symbollist);
147#else
148 fprintf(out, "No backtrace available\n");
149#endif
150}
151
152
153std::unique_ptr<EngngModel> InstanciateProblem(DataReader &dr, problemMode mode, int contextFlag, EngngModel *_master, bool parallelFlag)
154{
155 std :: string problemName, dataOutputFileName, desc;
156
157 dataOutputFileName = dr.giveOutputFileName();
158 desc = dr.giveDescription();
159
160 /* here we need copy of input record. The pointer returned by dr.giveInputRecord can (and will)
161 * be updated as reading e-model components (nodes, etc). But we need this record being available
162 * through the whole e-model instanciation
163 */
164 auto emodelir = dr.giveInputRecord(DataReader :: IR_emodelRec, 1).clone();
165 emodelir->giveRecordKeywordField(problemName);
166
167 auto problem = classFactory.createEngngModel(problemName.c_str(), 1, _master);
168 if ( !problem ) {
169 OOFEM_WARNING( "Failed to construct engineering model of type \"%s\".\n", problemName.c_str() );
170 return NULL;
171 }
172
173 problem->setProblemMode(mode);
174 problem->setParallelMode(parallelFlag);
175
176 if ( contextFlag ) {
177 problem->setContextOutputMode(COM_Always);
178 }
179
180 problem->instanciateYourself( dr, *emodelir, dataOutputFileName.c_str(), desc.c_str() );
181 //emodelir->finish();
182
183 return problem;
184}
185
186void printProgress(double percentage, const std::string &title, std::ostream& out) {
187 const int barWidth = 30;
188 int filled = static_cast<int>(barWidth * percentage);
189 out << title;
190
191 if (&out == &std::cout && isatty(fileno(stdout))) {
192 for (int i = 0; i < barWidth; ++i) {
193 out << (i < filled ? "█" : "░");
194 }
195 out << " " << std::fixed << std::setprecision(1) << percentage * 100.0 << "%";
196 out << "\r";
197 out.flush();
198 } else {
199 out << (percentage * 100.0) << "%" << std::endl;
200 }
201}
202
203
204} // end namespace oofem
std::string giveOutputFileName()
Gives the output file name.
Definition datareader.h:116
virtual InputRecord & giveInputRecord(InputRecordType irType, int recordId)=0
std::string giveDescription()
Gives the problem description.
Definition datareader.h:118
virtual std::shared_ptr< InputRecord > clone() const =0
#define OOFEM_WARNING(...)
Definition error.h:80
void printProgress(double percentage, const std::string &title, std::ostream &out)
Definition util.C:186
@ COM_Always
Enable for post-processing.
std::unique_ptr< EngngModel > InstanciateProblem(DataReader &dr, problemMode mode, int contextFlag, EngngModel *_master, bool parallelFlag)
Definition util.C:153
ClassFactory & classFactory
void print_stacktrace(FILE *out, int skip, unsigned int max_frames)
Definition util.C:63

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