OOFEM 3.0
Loading...
Searching...
No Matches
t3dinterface.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 "t3dinterface.h"
36#include "errorestimator.h"
37#include "domain.h"
38#include "node.h"
39#include "element.h"
40#include "engngm.h"
41#include "remeshingcrit.h"
42#include "oofemtxtdatareader.h"
43#include "dynamicinputrecord.h"
44
45#include "crosssection.h"
46#include "classfactory.h"
47
48#include "nonlocalbarrier.h"
49#include "initialcondition.h"
50#include "classfactory.h"
51//#include "loadtimefunction.h"
52#include "function.h"
53#include "outputmanager.h"
54
55#include <cmath>
56
57namespace oofem {
59
60
61MesherInterface :: returnCode
62T3DInterface :: createMesh(TimeStep *tStep, int domainNumber, int domainSerNum, Domain **dNew)
63{
64 * dNew = NULL;
65 if ( this->createInput(this->domain, tStep) ) {
67 } else {
68 return MI_FAILED;
69 }
70}
71
72int
73T3DInterface :: createInput(Domain *d, TimeStep *tStep)
74{
75 int nnodes = d->giveNumberOfDofManagers(), nelem = d->giveNumberOfElements();
76 double density;
77 FILE *outputStrem;
78 Node *inode;
79 Element *ielem;
80 int edges, trias, quads, tetras, pyrams, wedges, hexas;
81 IntArray edgeIdArray, triaIdArray, quadIdArray, tetraIdArray, pyramIdArray, wedgeIdArray, hexaIdArray;
82 bool tri_tetra = false;
83 char fileName [ 32 ];
84
85 edges = trias = quads = tetras = pyrams = wedges = hexas = 0;
86 for ( int i = 1; i <= nelem; i++ ) {
87 ielem = d->giveElement(i);
88 switch ( ielem->giveGeometryType() ) {
89 case EGT_point:
90 break;
91 case EGT_line_1:
92 case EGT_line_2:
93 edges++;
94 break;
95 case EGT_triangle_1:
96 case EGT_triangle_2:
97 trias++;
98 break;
99 case EGT_quad_1:
100 case EGT_quad_2:
101 quads++;
102 break;
103 case EGT_tetra_1:
104 case EGT_tetra_2:
105 tetras++;
106 break;
107 case EGT_wedge_1:
108 case EGT_wedge_2:
109 wedges++;
110 break;
111 case EGT_hexa_1:
112 case EGT_hexa_2:
113 hexas++;
114 break;
115 default:
116 OOFEM_ERROR( "unknown element type (%s)",
118 }
119 }
120
121 edgeIdArray.resize(edges);
122 triaIdArray.resize(trias);
123 quadIdArray.resize(quads);
124 tetraIdArray.resize(tetras);
125 pyramIdArray.resize(pyrams);
126 wedgeIdArray.resize(wedges);
127 hexaIdArray.resize(hexas);
128
129 edges = trias = quads = tetras = pyrams = wedges = hexas = 0;
130 for ( int i = 1; i <= nelem; i++ ) {
131 ielem = d->giveElement(i);
132 switch ( ielem->giveGeometryType() ) {
133 case EGT_point:
134 break;
135 case EGT_line_1:
136 case EGT_line_2:
137 edgeIdArray.at(++edges) = i;
138 break;
139 case EGT_triangle_1:
140 case EGT_triangle_2:
141 triaIdArray.at(++trias) = i;
142 break;
143 case EGT_quad_1:
144 case EGT_quad_2:
145 quadIdArray.at(++quads) = i;
146 break;
147 case EGT_tetra_1:
148 case EGT_tetra_2:
149 tetraIdArray.at(++tetras) = i;
150 break;
151 case EGT_wedge_1:
152 case EGT_wedge_2:
153 wedgeIdArray.at(++wedges) = i;
154 break;
155 case EGT_hexa_1:
156 case EGT_hexa_2:
157 hexaIdArray.at(++hexas) = i;
158 break;
159 default:
160 break;
161 }
162 }
163
164 if ( quads + hexas + pyrams + wedges == 0 ) {
165 tri_tetra = true;
166 }
167
168 if ( d->giveEngngModel()->isParallel() ) {
169 sprintf( fileName, "%s.%d", BMF_FILENAME, d->giveEngngModel()->giveRank() );
170 } else {
171 sprintf(fileName, "%s", BMF_FILENAME);
172 }
173
174 outputStrem = fopen(fileName, "w");
175 if ( tri_tetra == true ) {
176 fprintf(outputStrem, "3 1 -1\n");
177 fprintf(outputStrem, "%d %d %d %d\n", nnodes, edges, trias, tetras);
178 } else {
179 fprintf(outputStrem, "7 1 -1\n");
180 fprintf(outputStrem, "%d %d %d %d %d %d %d %d\n", nnodes, edges, trias, quads, tetras, pyrams, wedges, hexas);
181 }
182
183 // loop over nodes
184 for ( int i = 1; i <= nnodes; i++ ) {
186 inode = d->giveNode(i);
187 fprintf(outputStrem, "%d %e %e %e %e\n", i, inode->giveCoordinate(1), inode->giveCoordinate(2), inode->giveCoordinate(3), density);
188 }
189
190 // loop separately for each type of element
191 // since T3ds support only linear elements in bg mesh, only corner nodes are stored
192 // alternatively quadratic elements may be splitted to linear (not supported now)
193
194 if ( edges != 0 ) {
195 for ( int i = 1; i <= edges; i++ ) {
196 ielem = d->giveElement( edgeIdArray.at(i) );
197 fprintf(outputStrem, "%d", i);
198 for ( int j = 1; j <= 2; j++ ) {
199 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
200 }
201
202 fprintf(outputStrem, "\n");
203 }
204 }
205
206 if ( trias != 0 ) {
207 for ( int i = 1; i <= trias; i++ ) {
208 ielem = d->giveElement( triaIdArray.at(i) );
209 fprintf(outputStrem, "%d", i);
210 for ( int j = 1; j <= 3; j++ ) {
211 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
212 }
213
214 fprintf(outputStrem, "\n");
215 }
216 }
217
218 if ( quads != 0 ) {
219 for ( int i = 1; i <= quads; i++ ) {
220 ielem = d->giveElement( quadIdArray.at(i) );
221 fprintf(outputStrem, "%d", i);
222 for ( int j = 1; j <= 4; j++ ) {
223 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
224 }
225
226 fprintf(outputStrem, "\n");
227 }
228 }
229
230 if ( tetras != 0 ) {
231 for ( int i = 1; i <= tetras; i++ ) {
232 ielem = d->giveElement( tetraIdArray.at(i) );
233 fprintf(outputStrem, "%d", i);
234 for ( int j = 1; j <= 4; j++ ) {
235 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
236 }
237
238 fprintf(outputStrem, "\n");
239 }
240 }
241
242 if ( pyrams != 0 ) {
243 for ( int i = 1; i <= pyrams; i++ ) {
244 ielem = d->giveElement( pyramIdArray.at(i) );
245 fprintf(outputStrem, "%d", i);
246 for ( int j = 1; j <= 5; j++ ) {
247 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
248 }
249
250 fprintf(outputStrem, "\n");
251 }
252 }
253
254 if ( wedges != 0 ) {
255 for ( int i = 1; i <= wedges; i++ ) {
256 ielem = d->giveElement( wedgeIdArray.at(i) );
257 fprintf(outputStrem, "%d", i);
258 for ( int j = 1; j <= 6; j++ ) {
259 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
260 }
261
262 fprintf(outputStrem, "\n");
263 }
264 }
265
266 if ( hexas != 0 ) {
267 for ( int i = 1; i <= hexas; i++ ) {
268 ielem = d->giveElement( hexaIdArray.at(i) );
269 fprintf(outputStrem, "%d", i);
270 for ( int j = 1; j <= 8; j++ ) {
271 fprintf( outputStrem, " %d", ielem->giveNode(j)->giveNumber() );
272 }
273
274 fprintf(outputStrem, "\n");
275 }
276 }
277
278 fclose(outputStrem);
279
280 OOFEM_LOG_INFO("t3d.bmf file created\n");
281 return 1;
282}
283
284
285
286
287
288int
289T3DInterface :: t3d_2_OOFEM(const char *t3dOutFile, Domain **dNew)
290{
291 std::ifstream inputStream;
292 inputStream.open( t3dOutFile );
293 if ( !inputStream.is_open() ) {
294 OOFEM_ERROR("OOFEMTXTDataReader::OOFEMTXTDataReader: Can't open T3D input stream (%s)", t3dOutFile);
295 return 0;
296 }
297 // create new domain
298 ( * dNew ) = new Domain( 2, this->domain->giveSerialNumber() + 1, this->domain->giveEngngModel() );
299 ( * dNew )->setDomainType( this->domain->giveDomainType() );
300
301 std::string line;
302
303 //read first line from t3d out file - 4 numbers
304 // 2 degree of interpolation
305 // other are not important so far
306 std::getline(inputStream, line);
307 //convert const char to char in order to use strtok
308 char *currentLine = new char[line.size() + 1];
309 std::strcpy ( currentLine, line.c_str() );
310 // tokenizing line
311 char *token = std::strtok(currentLine, " ");
312 // set counter to 0
313 int i = 0;
314 while (token != nullptr) {
315 if(i == 0)
316 {}//int n1 = atoi(token);
317 else if (i == 1)
318 {}//int interp = atoi(token);
319 else if(i == 2)
320 {}//int n3 = atoi(token);
321 else if(i == 3)
322 {}//int n4 = atoi(token);
323 else
324 break;
325 token = std::strtok(nullptr, " ");
326 i++;
327 }
328
329
330 int nnodes = 0, ntriangles = 0, ntetras = 0; // nedges,
331
332 /*read second line from t3d out file
333 4 numbers
334 1 - number of nodes
335 2 - number of edges
336 3 - number of triangles
337 4 - number of tetras
338 */
339 std::getline(inputStream, line);
340 //convert const char to char in order to use strtok
341 currentLine = new char[line.size() + 1];
342 std::strcpy ( currentLine, line.c_str() );
343 // tokenizing line
344 token = std::strtok(currentLine, " ");
345 // set counter to 0
346 i = 0;
347 while (token != nullptr) {
348 if(i == 0)
349 nnodes = atoi(token);
350 else if (i == 1)
351 {}//nedges = atoi(token);
352 else if(i == 2)
353 ntriangles = atoi(token);
354 else if(i == 3)
355 ntetras = atoi(token);
356 else
357 break;
358 token = std::strtok(nullptr, " ");
359 i++;
360 }
361 // create new domain
362 (*dNew)->resizeDofManagers(nnodes);
363
364 //one empty line
365 std::getline(inputStream, line);
366 // create nodes
367 // read dofs
368 const IntArray dofIDArrayPtr = domain->giveDefaultNodeDofIDArry();
369 int ndofs = dofIDArrayPtr.giveSize();
370 // loop over number of nodes, read coordinates and create new nodes
371 for ( int inode = 1; inode <= nnodes; inode++ ) {
372 FloatArray coords(3);
373 std::getline(inputStream, line);
374 //convert const char to char in order to use strtok
375 currentLine = new char[line.size() + 1];
376 std::strcpy ( currentLine, line.c_str() );
377 // tokenizing line
378 token = std::strtok(currentLine, " ");
379 // set counter to 0
380 i = 0;
381 while (token != nullptr) {
382 if(i == 0)
383 {}//int nodeNum = atoi(token);
384 else if (i == 1)
385 coords.at(1) = atof(token);
386 else if(i == 2)
387 coords.at(2) = atof(token);
388 else if(i == 3)
389 coords.at(3) = atof(token);
390 else
391 break;
392 token = std::strtok(NULL, " ");
393 i++;
394 }
395 // newly created node
396 auto node = std::make_unique<Node>(inode, * dNew);
397 //create new node with default DOFs
398 node->setNumberOfDofs(ndofs);
399 node->setCoordinates( coords );
400 // how to set boundary condition ??
401 // node->setBoundaryFlag( mesh->giveNode(inode)->isBoundary() );
402 // ( * dNew )->setDofManager(inode, std::move(node));
403
404 }//end loop over nodes
405
406 //read empty line
407 std::getline(inputStream, line);
408
409
410 Element *parentElementPtr = domain->giveElement(1); //??km??
411 // loop over triangles, read dofman numbers and create new elements
412 for (int itriangle = 1; itriangle <= ntriangles; itriangle++) {
413 int elemNumber = 0;
414 IntArray dofManagers(3);
415 std::getline(inputStream, line);
416 //convert const char to char in order to use strtok
417 currentLine = new char[line.size() + 1];
418 std::strcpy ( currentLine, line.c_str() );
419 // tokenizing line
420 token = std::strtok(currentLine, " ");
421 // set counter to 0
422 i = 0;
423 while (token != nullptr) {
424 if(i == 0)
425 elemNumber = atoi(token);
426 else if (i >= 1 && i<=4)
427 dofManagers.at(i) = atoi(token);
428 else
429 break;
430 token = std::strtok(nullptr, " ");
431 i++;
432 }
433 auto elem = classFactory.createElement(parentElementPtr->giveClassName(), elemNumber, * dNew);
434 elem->setDofManagers( dofManagers );
435 elem->setMaterial( parentElementPtr->giveMaterial()->giveNumber() );
436 elem->setCrossSection( parentElementPtr->giveCrossSection()->giveNumber() );
437 //
438 // ...
439 //
440
441 }//end loop over triangles
442
443
444 // loop over tetras, read dofman numbers and create new elements
445 for (int itetra = 1; itetra <= ntetras; itetra++) {
446 int elemNumber = 0;
447 IntArray dofManagers(4);
448 std::getline(inputStream, line);
449 //convert const char to char in order to use strtok
450 currentLine = new char[line.size() + 1];
451 std::strcpy ( currentLine, line.c_str() );
452 // tokenizing line
453 token = std::strtok(currentLine, " ");
454 // set counter to 0
455 i = 0;
456 while (token != nullptr) {
457 if(i == 0)
458 elemNumber = atoi(token);
459 else if (i >= 1 && i<=4)
460 dofManagers.at(i) = atoi(token);
461 else
462 break;
463 token = std::strtok(nullptr, " ");
464 i++;
465 }
466 //elem = classFactory.createElement(parentElementPtr->giveClassName(), elemNumber, * dNew);
467 auto elem = classFactory.createElement("LTRSpace", elemNumber, * dNew);
468 elem->setDofManagers( dofManagers );
469 elem->setMaterial( parentElementPtr->giveMaterial()->giveNumber() );
470 elem->setCrossSection( parentElementPtr->giveCrossSection()->giveNumber() );
471 (*dNew)->setElement(elemNumber, std::move(elem));
472 }//end loop over tetras
473
474
475 std::string name;
476
477 // copy of crossections from old domain
478 int ncrosssect = domain->giveNumberOfCrossSectionModels();
479 ( * dNew )->resizeCrossSectionModels(ncrosssect);
480 for ( int i = 1; i <= ncrosssect; i++ ) {
482 domain->giveCrossSection(i)->giveInputRecord(ir);
483 ir.giveRecordKeywordField(name);
484
485 auto crossSection = classFactory.createCrossSection(name.c_str(), i, * dNew);
486 crossSection->initializeFrom(ir);
487 ( * dNew )->setCrossSection(i, std::move(crossSection));
488 }
489
490 // copy of materials from old domain
491 int nmat = domain->giveNumberOfMaterialModels();
492 ( * dNew )->resizeMaterials(nmat);
493 for ( int i = 1; i <= nmat; i++ ) {
495 domain->giveMaterial(i)->giveInputRecord(ir);
496 ir.giveRecordKeywordField(name);
497
498 auto mat = classFactory.createMaterial(name.c_str(), i, * dNew);
499 mat->initializeFrom(ir);
500 ( * dNew )->setMaterial(i, std::move(mat));
501 }
502
503 // copy of crossections from old domain
504 int nbarriers = domain->giveNumberOfNonlocalBarriers();
505 ( * dNew )->resizeNonlocalBarriers(nbarriers);
506 for ( int i = 1; i <= nbarriers; i++ ) {
508 domain->giveNonlocalBarrier(i)->giveInputRecord(ir);
509 ir.giveRecordKeywordField(name);
510
511 auto barrier = classFactory.createNonlocalBarrier(name.c_str(), i, * dNew);
512 barrier->initializeFrom(ir);
513 ( * dNew )->setNonlocalBarrier(i, std::move(barrier));
514 }
515
516 // copy of boundary conditions from old domain
517 int nbc = domain->giveNumberOfBoundaryConditions();
518 ( * dNew )->resizeBoundaryConditions(nbc);
519 for ( int i = 1; i <= nbc; i++ ) {
521 domain->giveBc(i)->giveInputRecord(ir);
522 ir.giveRecordKeywordField(name);
523
524 auto bc = classFactory.createBoundaryCondition(name.c_str(), i, * dNew);
525 bc->initializeFrom(ir);
526 ( * dNew )->setBoundaryCondition(i, std::move(bc));
527 }
528
529 // copy of initial conditions from old domain
530 int nic = domain->giveNumberOfInitialConditions();
531 ( * dNew )->resizeInitialConditions(nic);
532 for ( int i = 1; i <= nic; i++ ) {
534 domain->giveIc(i)->giveInputRecord(ir);
535 ir.giveRecordKeywordField(name);
536
537 auto ic = std::make_unique<InitialCondition>(i, *dNew);
538 ic->initializeFrom(ir);
539 ( * dNew )->setInitialCondition(i, std::move(ic));
540 }
541
542 // copy of load time functions from old domain
543 // int nltf = domain->giveNumberOfLoadTimeFunctions();
544 int nltf = domain->giveNumberOfFunctions();
545 // ( * dNew )->resizeLoadTimeFunctions(nltf);
546 ( * dNew )->resizeFunctions(nltf);
547 for ( int i = 1; i <= nltf; i++ ) {
549 //domain->giveLoadTimeFunction(i)->giveInputRecord(ir);
550 domain->giveFunction(i)->giveInputRecord(ir);
551 ir.giveRecordKeywordField(name);
552
553 //ltf = classFactory.createLoadTimeFunction(name.c_str(), i, * dNew);
554 auto ltf = classFactory.createFunction(name.c_str(), i, * dNew);
555 ltf->initializeFrom(ir);
556 //( * dNew )->setLoadTimeFunction(i, ltf);
557 ( * dNew )->setFunction(i, std::move(ltf));
558 }
559
560 // copy output manager settings from old domain
561 ( * dNew )->giveOutputManager()->beCopyOf( domain->giveOutputManager() );
562 return 1;
563}
564
565// used by HTS element to create export mesh to vtk
566
567int
568T3DInterface :: createInput(Element *e, char *t3dInFile)
569{
570 FILE *inputStrem;
571 inputStrem = fopen(t3dInFile, "w");
572
573 int nnodes = e->giveNumberOfDofManagers();
574 // loop over nodes and write vertexes into t3d input file
575 for ( int i = 1; i <= nnodes; i++ ) {
576 Node *inode;
577 inode = e->giveNode(i);
578 fprintf(inputStrem, "vertex %d xyz %e %e %e\n", i, inode->giveCoordinate(1), inode->giveCoordinate(2), inode->giveCoordinate(3));
579 }
580 for (int i = 1; i<=nnodes; i++) {
581 if( i< nnodes)
582 fprintf(inputStrem, "curve %d order 2 vertex %d %d\n", i, i, i+1);
583 else
584 fprintf(inputStrem, "curve %d order 2 vertex %d %d\n", i, i, 1);
585 }
586 fprintf(inputStrem, "patch 1 normal 0 0 1 boundary curve");
587 for (int i = 1; i<=nnodes; i++) {
588 fprintf(inputStrem, " %d", i);
589 }
590 fclose(inputStrem);
591
592 return 1;
593
594}
595
596
597
598
599
600
601
602int
603T3DInterface :: createVTKExportMesh(const char *t3dOutFile,std::vector<FloatArray> &nodeCoords, std::vector<IntArray> &cellNodes, IntArray &cellTypes )
604{
605
606 std::ifstream inputStream;
607 inputStream.open( t3dOutFile );
608 if ( !inputStream.is_open() ) {
609 OOFEM_ERROR("OOFEMTXTDataReader::OOFEMTXTDataReader: Can't open T3D input stream (%s)", t3dOutFile);
610 return 0;
611 }
612 std::string line;
613 //read and skip first line from t3d out file - 4 numbers
614 std::getline(inputStream, line);
615 /*read second line from t3d out file
616 4 numbers
617 1 - number of nodes
618 2 - number of edges
619 3 - number of triangles
620 4 - number of tetras
621 */
622 int nnodes = 0, ntriangles = 0; // nedges, ntetras
623 std::getline(inputStream, line);
624 //convert const char to char in order to use strtok
625 char *currentLine = new char[line.size() + 1];
626 std::strcpy ( currentLine, line.c_str() );
627 // tokenizing line
628 char *token = std::strtok(currentLine, " ");
629 // set counter to 0
630 int i = 0;
631 while (token != NULL) {
632 if(i == 0)
633 nnodes = atoi(token);
634 else if (i == 1)
635 {}//nedges = atoi(token);
636 else if(i == 2)
637 ntriangles = atoi(token);
638 else if(i == 3)
639 {}//ntetras = atoi(token);
640 else
641 break;
642 token = std::strtok(NULL, " ");
643 i++;
644 }
645 delete [] currentLine;
646 //read one empty line
647 std::getline(inputStream, line);
648
649
650 // loop over number of nodes, read coordinates and put them into nodeCoords Array
651 for ( int inode = 1; inode <= nnodes; inode++ ) {
652 // int nodeNum;
653 FloatArray coords(3);
654 std::getline(inputStream, line);
655 //convert const char to char in order to use strtok
656 currentLine = new char[line.size() + 1];
657 std::strcpy ( currentLine, line.c_str() );
658 // tokenizing line
659 token = std::strtok(currentLine, " ");
660 // set counter to 0
661 i = 0;
662 while (token != NULL) {
663 if(i == 0)
664 {}// nodeNum = atoi(token);
665 else if (i == 1)
666 coords.at(1) = atof(token);
667 else if(i == 2)
668 coords.at(2) = atof(token);
669 else if(i == 3)
670 coords.at(3) = atof(token);
671 else
672 break;
673 token = std::strtok(NULL, " ");
674 i++;
675 }
676
677 nodeCoords.push_back(coords);
678 delete [] currentLine;
679 }//end loop over nodes
680
681
682
683 //one empty line
684 std::getline(inputStream, line);
685 cellTypes.resize(ntriangles);
686 // loop over triangles, and fill nodeCoords, cellNodes nad cellTypes arrays
687 for (int itriangle = 1; itriangle <= ntriangles; itriangle++) {
688 // int elemNumber;
689 IntArray dofManagers(3);
690 std::getline(inputStream, line);
691 //convert const char to char in order to use strtok
692 currentLine = new char[line.size() + 1];
693 std::strcpy ( currentLine, line.c_str() );
694 // tokenizing line
695 token = std::strtok(currentLine, " ");
696 // set counter to 0
697 i = 0;
698 while (token != NULL) {
699 if(i == 0)
700 {}//elemNumber = atoi(token);
701 else if (i >= 1 && i<=3)
702 dofManagers.at(i) = atoi(token) - 1;
703 else
704 break;
705 token = std::strtok(NULL, " ");
706 i++;
707 }
708 cellNodes.push_back(dofManagers);
709 // in vtk number 5 corresponds to linear triangle
710 cellTypes.at(itriangle) = 5;
711 delete [] currentLine;
712 }//end loop over triangles
713
714 return 1;
715}
716
717
718
719
720
721int
722T3DInterface :: createQCInterpolationMesh(const char *t3dOutFile,std::vector<FloatArray> &nodeCoords, std::vector<IntArray> &cellNodes, IntArray &cellTypes )
723//
724// create interpolation mest from t3dOutFile
725// node coordinates and element nodes are saved in "matrix" vector<FloatArray/IntArray>
726//
727{
728
729 std::ifstream inputStream;
730 inputStream.open( t3dOutFile );
731 if ( !inputStream.is_open() ) {
732 OOFEM_ERROR("OOFEMTXTDataReader::OOFEMTXTDataReader: Can't open T3D input stream (%s)", t3dOutFile);
733 return 0;
734 }
735 std::string line;
736 //read and skip first line from t3d out file - 4 numbers
737 std::getline(inputStream, line);
738 /*read second line from t3d out file
739 4 numbers
740 1 - number of nodes
741 2 - number of edges
742 3 - number of triangles
743 4 - number of tetras
744 */
745 int nnodes = 0, ntriangles = 0, ntetras = 0; //nedges,
746 std::getline(inputStream, line);
747 //convert const char to char in order to use strtok
748 char *currentLine = new char[line.size() + 1];
749 std::strcpy ( currentLine, line.c_str() );
750 // tokenizing line
751 char *token = std::strtok(currentLine, " ");
752 // set counter to 0
753 int i = 0;
754 while (token != NULL) {
755 if(i == 0)
756 nnodes = atoi(token);
757 else if (i == 1)
758 {}//nedges = atoi(token);
759 else if(i == 2)
760 ntriangles = atoi(token);
761 else if(i == 3)
762 ntetras = atoi(token);
763 else
764 break;
765 token = std::strtok(NULL, " ");
766 i++;
767 }
768 delete [] currentLine;
769 //read one empty line
770 std::getline(inputStream, line);
771
772 // check the number of interpolation element
773 if (ntriangles!=0 && ntetras!=0 ) {
774 OOFEM_ERROR( "T3DInterface: 2D and 3D interpolation elements are not supported together");
775 } else if (ntriangles!=0) {
776 cellTypes.resize(ntriangles);
777 } else if (ntetras!=0) {
778 cellTypes.resize(ntetras);
779 } else {
780 OOFEM_ERROR( "T3DInterface: No interpolation element found in %s", t3dOutFile);
781 }
782
783 // loop over number of nodes, read coordinates and put them into nodeCoords Array
784 for ( int inode = 1; inode <= nnodes; inode++ ) {
785 FloatArray coords(3);
786 // int nodeNum;
787 std::getline(inputStream, line);
788 //convert const char to char in order to use strtok
789 currentLine = new char[line.size() + 1];
790 std::strcpy ( currentLine, line.c_str() );
791 // tokenizing line
792 token = std::strtok(currentLine, " ");
793 // set counter to 0
794 i = 0;
795 while (token != NULL) {
796 if(i == 0)
797 {}// nodeNum = atoi(token);
798 else if (i == 1)
799 coords.at(1) = atof(token);
800 else if(i == 2)
801 coords.at(2) = atof(token);
802 else if(i == 3)
803 coords.at(3) = atof(token);
804 else
805 break;
806 token = std::strtok(NULL, " ");
807 i++;
808 }
809
810 nodeCoords.push_back(coords);
811 delete [] currentLine;
812 }//end loop over nodes
813
814 //one empty line
815 std::getline(inputStream, line);
816
817// loop over triangles, and fill nodeCoords, cellNodes nad cellTypes arrays
818 for (int itriangle = 1; itriangle <= ntriangles; itriangle++) {
819 IntArray dofManagers(3);
820 // int elemNumber;
821 std::getline(inputStream, line);
822 //convert const char to char in order to use strtok
823 currentLine = new char[line.size() + 1];
824 std::strcpy ( currentLine, line.c_str() );
825 // tokenizing line
826 token = std::strtok(currentLine, " ");
827 // set counter to 0
828 i = 0;
829 while (token != NULL) {
830 if(i == 0)
831 {}//elemNumber = atoi(token);
832 else if (i >= 1 && i<=3)
833 dofManagers.at(i) = atoi(token);
834 else
835 break;
836 token = std::strtok(NULL, " ");
837 i++;
838 }
839 cellNodes.push_back(dofManagers);
840 // in vtk number 5 corresponds to linear triangle
841 cellTypes.at(itriangle) = 5;
842 delete [] currentLine;
843 }//end loop over triangles
844
845// loop over tetras, read dofman numbers and fill nodeCoords, cellNodes nad cellTypes arrays
846 for (int itetra = 1; itetra <= ntetras; itetra++) {
847 IntArray dofManagers(4);
848 // int elemNumber;
849 std::getline(inputStream, line);
850 //convert const char to char in order to use strtok
851 currentLine = new char[line.size() + 1];
852 std::strcpy ( currentLine, line.c_str() );
853 // tokenizing line
854 token = std::strtok(currentLine, " ");
855 // set counter to 0
856 i = 0;
857 while (token != NULL) {
858 if(i == 0)
859 {}//elemNumber = atoi(token);
860 else if (i >= 1 && i<=4)
861 dofManagers.at(i) = atoi(token);
862 else
863 break;
864 token = std::strtok(NULL, " ");
865 i++;
866 }
867 cellNodes.push_back(dofManagers);
868 // in vtk number 5 corresponds to linear triangle
869 cellTypes.at(itetra) = 5; // ??km?? TODO: number for tetras in vtk = ???
870 delete [] currentLine;
871 }//end loop over tetras
872
873
874 return 1;
875}
876
877
878
879} // end namespace oofem
#define REGISTER_Mesher(class, type)
double giveCoordinate(int i) const
Definition dofmanager.h:383
ErrorEstimator * giveErrorEstimator()
Definition domain.C:1537
int giveNumberOfElements() const
Returns number of elements in domain.
Definition domain.h:463
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition domain.h:461
Element * giveElement(int n)
Definition domain.C:165
Node * giveNode(int n)
Definition domain.h:398
EngngModel * giveEngngModel()
Definition domain.C:419
void giveRecordKeywordField(std ::string &answer, int &value) override
Reads the record id field (type of record) and its corresponding number.
Node * giveNode(int i) const
Definition element.h:629
virtual Material * giveMaterial()
Definition element.C:523
const char * giveClassName() const override
Definition element.h:1219
virtual int giveNumberOfDofManagers() const
Definition element.h:695
CrossSection * giveCrossSection()
Definition element.C:534
virtual Element_Geometry_Type giveGeometryType() const =0
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1).
Definition engngm.h:1154
bool isParallel() const
Returns true if receiver in parallel mode.
Definition engngm.h:1152
virtual RemeshingCriteria * giveRemeshingCrit()=0
int giveNumber() const
Definition femcmpnn.h:104
double & at(Index i)
Definition floatarray.h:202
void resize(int n)
Definition intarray.C:73
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
virtual double giveRequiredDofManDensity(int num, TimeStep *tStep, int relative=0)=0
int createInput(Element *e, char *t3dInFile)
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
const char * __Element_Geometry_TypeToString(Element_Geometry_Type _value)
Definition cltypes.C:325
ClassFactory & classFactory
#define BMF_FILENAME

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