OOFEM 3.0
Loading...
Searching...
No Matches
vtkxmlperiodicexportmodule.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
36#include "element.h"
37#include "gausspoint.h"
38#include "timestep.h"
39#include "engngm.h"
40#include "node.h"
41#include "materialinterface.h"
42#include "mathfem.h"
43#include "cltypes.h"
44#include "material.h"
45#include "classfactory.h"
46#include "crosssection.h"
47#include "dof.h"
48
49#ifdef __SM_MODULE
55#endif
56
57namespace oofem {
59
60VTKXMLPeriodicExportModule :: VTKXMLPeriodicExportModule(int n, EngngModel *e) : VTKXMLExportModule(n, e)
61{
62 //Find out the element type and elemNodes
63}
64
65
66VTKXMLPeriodicExportModule :: ~VTKXMLPeriodicExportModule()
67{}
68
69
70void
71VTKXMLPeriodicExportModule :: initializeFrom(InputRecord &ir)
72{
73 VTKXMLExportModule :: initializeFrom(ir);
74}
75
76
77void
78VTKXMLPeriodicExportModule :: giveSwitches(IntArray &answer, int location) {
79 answer.resize(3);
80 answer.zero();
81 int counter = 1;
82 for ( int x = -1; x < 2; x++ ) {
83 for ( int y = -1; y < 2; y++ ) {
84 for ( int z = -1; z < 2; z++ ) {
85 if ( !( z == 0 && y == 0 && x == 0 ) ) {
86 if ( counter == location ) {
87 answer(0) = x;
88 answer(1) = y;
89 answer(2) = z;
90 }
91 counter++;
92 }
93 }
94 }
95 }
96
97 return;
98}
99
100
101void
102VTKXMLPeriodicExportModule :: setupVTKPiece(ExportRegion &vtkPiece, TimeStep *tStep, Set& region)
103{
104 // Stores all neccessary data (of a region) in a VTKPiece so it can be exported later.
105
106 Domain *d = emodel->giveDomain(1);
107 Element *elem;
108
109 int nnodes = d->giveNumberOfDofManagers();
110
111 this->giveSmoother(); // make sure smoother is created
112
113 // Assemble local->global and global->local region map and get number of
114 // single cells to process, the composite cells exported individually.
115 this->initRegionNodeNumbering(vtkPiece, d, tStep, region);
116 const int numNodes = vtkPiece.giveNumberOfNodes();
117 const int numRegionEl = vtkPiece.giveNumberOfCells();
118 const IntArray& mapG2L = vtkPiece.getMapG2L();
119 const IntArray& mapL2G = vtkPiece.getMapL2G();
120
121
122 if ( numNodes > 0 && numRegionEl > 0 ) {
123 // Export nodes as vtk vertices
124 vtkPiece.setNumberOfNodes(numNodes);
125 for ( int inode = 1; inode <= numNodes; inode++ ) {
126 if ( mapL2G.at(inode) <= nnodes && mapL2G.at(inode) != 0 ) { //DofManagers in domain (input file)
127 const auto &coords = d->giveNode(mapL2G.at(inode) )->giveCoordinates();
128 vtkPiece.setNodeCoords(inode, coords);
129 } else if ( mapL2G.at(inode) > nnodes && mapL2G.at(inode) <= numNodes && mapL2G.at(inode) != 0 ) { //extra image nodes
130 FloatArray helpArray(3);
131 helpArray.at(1) = uniqueNodeTable.at(mapL2G.at(inode), 1);
132 helpArray.at(2) = uniqueNodeTable.at(mapL2G.at(inode), 2);
133 helpArray.at(3) = uniqueNodeTable.at(mapL2G.at(inode), 3);
134 vtkPiece.setNodeCoords(inode, helpArray);
135 } else {
136 FloatArray helpArray(3);
137 helpArray.zero();
138 vtkPiece.setNodeCoords(inode, helpArray);
139 }
140 }
141
142
143 //-------------------------------------------
144 // Export all the cell data for the piece
145 //-------------------------------------------
146 IntArray cellNodes;
147 vtkPiece.setNumberOfCells(numRegionEl);
148
149 int offset = 0;
150 int cellNum = 0;
151 IntArray elems = region.giveElementList();
152 int helpCounter = 0;
153 for ( int ei = 1; ei <= elems.giveSize(); ei++ ) {
154 int elNum = elems.at(ei);
155 elem = d->giveElement(elNum);
156
157 // Skip elements that:
158 // are inactivated or of composite type ( these are exported individually later)
159 if ( this->isElementComposite(elem) || !elem->isActivated(tStep) ) {
160 continue;
161 }
162
163 if ( elem->giveParallelMode() != Element_local ) {
164 continue;
165 }
166
167 cellNum++;
168
169 // Set the connectivity
170#ifdef __SM_MODULE
171 if ( dynamic_cast< LTRSpaceBoundary * >( elem ) ) {
172 cellNodes.resize(4);
173 IntArray loc = elem->giveLocation();
174 for ( int ielnode = 1; ielnode <= 4; ielnode++ ) {
175 if ( loc.at(ielnode) != 0 ) {
176 helpCounter++;
177 cellNodes.at(ielnode) = regionToUniqueMap.at(nnodes + helpCounter);
178 } else {
179 cellNodes.at(ielnode) = elem->giveNode(ielnode)->giveNumber();
180 }
181 }
182 } else if ( dynamic_cast< LIBeam3dBoundary * >( elem ) || dynamic_cast< Lattice3dBoundary * >( elem ) || dynamic_cast< LatticeLink3dBoundary * >( elem ) || dynamic_cast< Lattice2dBoundary * >( elem ) ) {
183 cellNodes.resize(2);
184 IntArray loc = elem->giveLocation();
185 for ( int ielnode = 1; ielnode <= 2; ielnode++ ) {
186 if ( loc.at(ielnode) != 0 ) {
187 helpCounter++;
188 cellNodes.at(ielnode) = regionToUniqueMap.at(nnodes + helpCounter);
189 } else {
190 cellNodes.at(ielnode) = elem->giveNode(ielnode)->giveNumber();
191 }
192 }
193 } else { //Standard case
194#endif
195 this->giveElementCell(cellNodes, elem);
196#ifdef __SM_MODULE
197 }
198#endif
199 // Map from global to local node numbers for the current piece
200 int numElNodes = cellNodes.giveSize();
201
202
203 IntArray connectivity(numElNodes);
204 for ( int i = 1; i <= numElNodes; i++ ) {
205 connectivity.at(i) = mapG2L.at(cellNodes.at(i) );
206 }
207
208 vtkPiece.setConnectivity(cellNum, connectivity);
209
210 vtkPiece.setCellType(cellNum, this->giveCellType(elem) ); // VTK cell type
211
212 offset += numElNodes;
213 vtkPiece.setOffset(cellNum, offset);
214 }
215
216
217 // Export primary, internal and XFEM variables as nodal quantities
218 this->exportPrimaryVars(vtkPiece, region, primaryVarsToExport, *primVarSmoother, tStep);
219 this->exportIntVars (vtkPiece, region, internalVarsToExport, *smoother, tStep);
220
221 this->exportCellVars(vtkPiece, region, cellVarsToExport, tStep);
222
223 } // end of default piece for simple geometry elements
224}
225
226int
227VTKXMLPeriodicExportModule :: initRegionNodeNumbering(ExportRegion& vtkPiece,
228 Domain *domain, TimeStep *tStep, Set& region)
229{
230 int nnodes = domain->giveNumberOfDofManagers();
231 int elementNode, node;
232 int currOffset = 1;
233 Element *element;
234
235 int regionDofMans = 0;
236 int regionSingleCells = 0;
237 IntArray& regionG2LNodalNumbers = vtkPiece.getMapG2L();
238 IntArray& regionL2GNodalNumbers = vtkPiece.getMapL2G();
239
240
241 IntArray elements = region.giveElementList();
242
243 int extraNodes = 0.;
244 for ( int ie = 1; ie <= elements.giveSize(); ie++ ) {
245 element = domain->giveElement(elements.at(ie) );
246
247#ifdef __SM_MODULE
248 if ( dynamic_cast< LTRSpaceBoundary * >( element ) ) {
249 IntArray loc = element->giveLocation();
250 for ( int ielnode = 1; ielnode <= 4; ielnode++ ) {
251 if ( loc.at(ielnode) != 0 ) {
252 extraNodes++;
253 }
254 }
255 } else if ( dynamic_cast< LIBeam3dBoundary * >( element ) || dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) {
256 IntArray loc = element->giveLocation();
257 for ( int ielnode = 1; ielnode <= 2; ielnode++ ) {
258 if ( loc.at(ielnode) != 0 ) {
259 extraNodes++;
260 }
261 }
262 }
263#endif
264 }
265
266 regionG2LNodalNumbers.resize(nnodes + extraNodes);
267 regionG2LNodalNumbers.zero();
268
269 periodicMap.resize(nnodes + extraNodes);
270 regionToUniqueMap.resize(nnodes + extraNodes);
271 locationMap.resize(nnodes + extraNodes);
272
273 uniqueNodeTable.resize(nnodes + extraNodes, 3);
274 uniqueNodeTable.zero();
275
276 int totalNodes = 0;
277 int uniqueNodes = 0;
278
279 for ( int ie = 1; ie <= elements.giveSize(); ie++ ) {
280 int ielem = elements.at(ie);
281 element = domain->giveElement(ielem);
282
283 if ( this->isElementComposite(element) ) {
284 continue; // composite cells exported individually
285 }
286
287 if ( !element->isActivated(tStep) ) { //skip inactivated elements
288 continue;
289 }
290
291 if ( element->giveParallelMode() != Element_local ) {
292 continue;
293 }
294
295 regionSingleCells++;
296 elemNodes = element->giveNumberOfNodes();
297
298#ifdef __SM_MODULE
299 if ( dynamic_cast< LTRSpaceBoundary * >( element ) ) {
300 elemNodes = 4;
301 } else if ( dynamic_cast< LIBeam3dBoundary * >( element ) || dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) {
302 elemNodes = 2;
303 }
304#endif
305
306 for ( elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
307#ifdef __SM_MODULE
308 if ( dynamic_cast< LTRSpaceBoundary * >( element ) ) {
309 IntArray loc = element->giveLocation();
310 FloatArray nodeCoords;
311 if ( loc.at(elementNode) != 0 ) { //boundary element with mirrored node
312 totalNodes++;
313 regionDofMans++;
314 regionG2LNodalNumbers.at(nnodes + totalNodes) = 1;
315 node = element->giveNode(elementNode)->giveNumber();
316 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
317 /* mark for assignment. This is done later, as it allows to preserve
318 * natural node numbering.
319 */
320
321 regionG2LNodalNumbers.at(node) = 1;
322 regionDofMans++;
323 }
324 if ( regionG2LNodalNumbers.at(nnodes) == 0 ) {
325 regionG2LNodalNumbers.at(nnodes) = 1;
326 regionDofMans++;
327 }
328
329 periodicMap.at(nnodes + totalNodes) = node;
330 locationMap.at(nnodes + totalNodes) = loc.at(elementNode);
331
332 element->recalculateCoordinates(elementNode, nodeCoords);
333
334 //get only the unique nodes
335 int repeatFlag = 0;
336 for ( int j = nnodes + 1; j <= nnodes + uniqueNodes; j++ ) {
337 double dx = fabs(uniqueNodeTable.at(j, 1) - nodeCoords.at(1) );
338 double dy = fabs(uniqueNodeTable.at(j, 2) - nodeCoords.at(2) );
339 double dz = fabs(uniqueNodeTable.at(j, 3) - nodeCoords.at(3) );
340 if ( dx < 1e-9 && dy < 1e-9 && dz < 1e-9 ) {//node already present
341 repeatFlag++;
342 regionToUniqueMap.at(nnodes + totalNodes) = j;
343 }
344 }
345
346 if ( repeatFlag == 0 ) {//new unique node
347 uniqueNodes++;
348 uniqueNodeTable.at(nnodes + uniqueNodes, 1) = nodeCoords.at(1);
349 uniqueNodeTable.at(nnodes + uniqueNodes, 2) = nodeCoords.at(2);
350 uniqueNodeTable.at(nnodes + uniqueNodes, 3) = nodeCoords.at(3);
351 regionToUniqueMap.at(nnodes + totalNodes) = nnodes + uniqueNodes;
352 }
353 } else { //boundary element but node not mirrored
354 node = element->giveNode(elementNode)->giveNumber();
355 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
356 /* mark for assignment. This is done later, as it allows to preserve
357 * natural node numbering.
358 */
359 regionG2LNodalNumbers.at(node) = 1;
360 regionDofMans++;
361 }
362 }
363 } else if ( dynamic_cast< LIBeam3dBoundary * >( element ) || dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) { //beam elements - only unique nodes
364 IntArray loc = element->giveLocation();
365 FloatArray nodeCoords;
366 if ( loc.at(elementNode) != 0 ) { //boundary element with mirrored node
367 totalNodes++;
368 regionDofMans++;
369 regionG2LNodalNumbers.at(nnodes + totalNodes) = 1;
370 node = element->giveNode(elementNode)->giveNumber();
371 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
372 /* mark for assignment. This is done later, as it allows to preserve
373 * natural node numbering.
374 */
375
376 regionG2LNodalNumbers.at(node) = 1;
377 regionDofMans++;
378 }
379 if ( regionG2LNodalNumbers.at(nnodes) == 0 ) {
380 regionG2LNodalNumbers.at(nnodes) = 1;
381 regionDofMans++;
382 }
383
384 periodicMap.at(nnodes + totalNodes) = node;
385 locationMap.at(nnodes + totalNodes) = loc.at(elementNode);
386
387 element->recalculateCoordinates(elementNode, nodeCoords);
388
389 //get only the unique nodes
390 int repeatFlag = 0;
391 for ( int j = nnodes + 1; j <= nnodes + uniqueNodes; j++ ) {
392 double dx = fabs(uniqueNodeTable.at(j, 1) - nodeCoords.at(1) );
393 double dy = fabs(uniqueNodeTable.at(j, 2) - nodeCoords.at(2) );
394 double dz = fabs(uniqueNodeTable.at(j, 3) - nodeCoords.at(3) );
395 if ( dx < 1e-9 && dy < 1e-9 && dz < 1e-9 ) {//node already present
396 repeatFlag++;
397 regionToUniqueMap.at(nnodes + totalNodes) = j;
398 }
399 }
400
401 if ( repeatFlag == 0 ) {//new unique node
402 uniqueNodes++;
403 uniqueNodeTable.at(nnodes + uniqueNodes, 1) = nodeCoords.at(1);
404 uniqueNodeTable.at(nnodes + uniqueNodes, 2) = nodeCoords.at(2);
405 uniqueNodeTable.at(nnodes + uniqueNodes, 3) = nodeCoords.at(3);
406 regionToUniqueMap.at(nnodes + totalNodes) = nnodes + uniqueNodes;
407 }
408 }
409 } else { //regular element
410#endif
411 node = element->giveNode(elementNode)->giveNumber();
412 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
413 /* mark for assignment. This is done later, as it allows to preserve
414 * natural node numbering.
415 */
416 regionG2LNodalNumbers.at(node) = 1;
417 regionDofMans++;
418 }
419#ifdef __SM_MODULE
420 }
421#endif
422 }
423 }
424
425 uniqueNodeTable.resizeWithData(nnodes + uniqueNodes, 3);
426 regionDofMans = nnodes + uniqueNodes;
427 regionG2LNodalNumbers.resizeWithValues(regionDofMans);
428 regionL2GNodalNumbers.resize(regionDofMans);
429
430 vtkPiece.setNumberOfNodes(regionDofMans);
431 vtkPiece.setNumberOfCells(regionSingleCells);
432
433 for ( int i = 1; i <= regionDofMans; i++ ) {
434 if ( regionG2LNodalNumbers.at(i) ) {
435 regionG2LNodalNumbers.at(i) = currOffset++;
436 regionL2GNodalNumbers.at(regionG2LNodalNumbers.at(i) ) = i;
437 }
438 }
439 return 1;
440}
441
442
443void VTKXMLPeriodicExportModule :: exportPrimaryVars(ExportRegion &vtkPiece, Set& region, IntArray& primaryVarsToExport, NodalRecoveryModel& smoother, TimeStep *tStep)
444{
445 Domain *d = emodel->giveDomain(1);
446 int nnodes = d->giveNumberOfDofManagers();
447 FloatArray valueArray;
448 smoother.clear(); // Makes sure primary smoother is up-to-date with potentially new mesh.
449
450 //const IntArray& mapG2L = vtkPiece.getMapG2L();
451 const IntArray& mapL2G = vtkPiece.getMapL2G();
453
454 //Get the macroscopic field (deformation gradients, curvatures etc.)
455 DofManager *controlNode = d->giveNode(nnodes); //assuming the control node is last
456 IntArray dofIdArray;
457 controlNode->giveCompleteMasterDofIDArray(dofIdArray);
458 std::vector<int> dofIDVector;
459 dofIDVector.assign(dofIdArray.begin(), dofIdArray.end());
460
461 FloatArray macroField(controlNode->giveNumberOfDofs() );
462 for ( int j = 1; j <= controlNode->giveNumberOfDofs(); j++ ) {
463 macroField.at(j) = controlNode->giveDofWithID(dofIdArray.at(j) )->giveUnknown(VM_Total, tStep);
464 }
465
466 std::vector<int> macroTrussIDs = { E_xx };
467 std::vector<int> macroMembraneIDs = { E_xx, E_yy, E_xy, E_yx };
468 std::vector<int> macroBeamIDs = { E_xx, E_zx, K_xx };
469 std::vector<int> macroPlateIDs = { E_xx, E_yy, E_zy, E_zx, E_xy, E_yx, K_xx, K_yy, K_xy, K_yx };
470 std::vector<int> macro3DVoigtIDs = { E_xx, E_yy, E_zz, G_yz, G_xz, G_xy };
471 std::vector<int> macro3DIDs = { E_xx, E_yy, E_zz, E_yz, E_zy, E_xz, E_zx, E_xy, E_yx };
472 std::vector<int> macro2DIDs = { E_xx, E_yy, G_xy };
473
474 //Get unit cell size
475 const auto unitCellSize = controlNode->giveCoordinates();
476
477 for ( int i = 1, n = primaryVarsToExport.giveSize(); i <= n; i++ ) {
479
480 for ( int inode = 1; inode <= mapL2G.giveSize(); inode++ ) {
481 if ( inode <= nnodes && mapL2G.at(inode) <= nnodes && mapL2G.at(inode) != 0 ) { //no special treatment for master nodes
482 DofManager *dman = d->giveNode(mapL2G.at(inode) );
483
484 this->getNodalVariableFromPrimaryField(valueArray, dman, tStep, type, region, smoother);
485 vtkPiece.setPrimaryVarInNode(type, inode, std :: move(valueArray) );
486 } else { //special treatment for image nodes
487 //find the periodic node, enough to find the first occurrence
488 int pos = 0;
489 if ( mapL2G.at(inode) != 0 ) {
490 pos = regionToUniqueMap.findFirstIndexOf(mapL2G.at(inode) );
491 }
492 if ( pos ) {
493 DofManager *dman = d->giveNode(periodicMap.at(pos) );
494 IntArray switches;
495 giveSwitches(switches, locationMap.at(pos) );
496 //get the master unknown
497 FloatArray helpArray;
498 this->getNodalVariableFromPrimaryField(helpArray, dman, tStep, type, region, smoother);
499 //recalculate the image unknown
500 if ( type == DisplacementVector ) {
501 if ( dofIDVector == macro3DIDs ) { //Macroscale: 3D SOLID, LTRSpaceBoundary
502 valueArray.resize(helpArray.giveSize() );
503 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) +
504 unitCellSize.at(2) * switches.at(2) * macroField.at(8) + unitCellSize.at(3) * switches.at(3) * macroField.at(6);
505 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(1) * switches.at(1) * macroField.at(9) +
506 unitCellSize.at(2) * switches.at(2) * macroField.at(2) + unitCellSize.at(3) * switches.at(3) * macroField.at(4);
507 valueArray.at(3) = helpArray.at(3) + unitCellSize.at(1) * switches.at(1) * macroField.at(7) +
508 unitCellSize.at(2) * switches.at(2) * macroField.at(5) + unitCellSize.at(3) * switches.at(3) * macroField.at(3);
509 } else if ( dofIDVector == macroTrussIDs ) { //Macroscale: TRUSS
510 valueArray.resize(helpArray.giveSize() );
511 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1);
512 valueArray.at(2) = helpArray.at(2);
513 valueArray.at(3) = helpArray.at(3);
514 } else if ( dofIDVector == macroMembraneIDs ) { //Macroscale: 2D MEMBRANE, LTRSpaceBoundaryMembrane
515 valueArray.resize(helpArray.giveSize() );
516 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) +
517 unitCellSize.at(2) * switches.at(2) * macroField.at(3);
518 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(1) * switches.at(1) * macroField.at(4) +
519 unitCellSize.at(2) * switches.at(2) * macroField.at(2);
520 valueArray.at(3) = helpArray.at(3);
521 } else if ( dofIDVector == macro2DIDs ) { //Macroscale: 2D plane stress
522 valueArray.resize(helpArray.giveSize() );
523 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1);
524 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(2) * switches.at(2) * macroField.at(2) + unitCellSize.at(1) * switches.at(1) * macroField.at(3);
525 valueArray.at(3) = helpArray.at(3);
526 } else if ( dofIDVector == macroBeamIDs ) { //Macroscale: 2D BEAM, LTRSpaceBoundaryBeam
527 valueArray.resize(helpArray.giveSize() );
528 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) -
529 dman->giveCoordinate(3) * unitCellSize.at(1) * switches.at(1) * macroField.at(3);
530 valueArray.at(2) = helpArray.at(2);
531 valueArray.at(3) = helpArray.at(3) + unitCellSize.at(1) * switches.at(1) * macroField.at(2);
532 } else if ( dofIDVector == macroPlateIDs ) { //Macroscale: 2D PLATE, LTRSpaceBoundaryPlate
533 valueArray.resize(helpArray.giveSize() );
534 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) +
535 unitCellSize.at(2) * switches.at(2) * macroField.at(5) -
536 dman->giveCoordinate(3) * unitCellSize.at(1) * switches.at(1) * macroField.at(7) -
537 dman->giveCoordinate(3) * unitCellSize.at(2) * switches.at(2) * macroField.at(9);
538 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(1) * switches.at(1) * macroField.at(6) +
539 unitCellSize.at(2) * switches.at(2) * macroField.at(2) -
540 dman->giveCoordinate(3) * unitCellSize.at(2) * switches.at(2) * macroField.at(8) -
541 dman->giveCoordinate(3) * unitCellSize.at(1) * switches.at(1) * macroField.at(10);
542 valueArray.at(3) = helpArray.at(3) + unitCellSize.at(1) * switches.at(1) * macroField.at(4) +
543 unitCellSize.at(2) * switches.at(2) * macroField.at(3);
544 } else if ( dofIDVector == macro3DVoigtIDs ) { //Macroscale: 3D SOLID, LTRSpaceBoundaryVoigt, Lattice3dBoundary
545 valueArray.resize(helpArray.giveSize() );
546 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) +
547 unitCellSize.at(3) * switches.at(3) * macroField.at(5) + unitCellSize.at(2) * switches.at(2) * macroField.at(6);
548 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(2) * switches.at(2) * macroField.at(2) +
549 unitCellSize.at(3) * switches.at(3) * macroField.at(4);
550 valueArray.at(3) = helpArray.at(3) + unitCellSize.at(3) * switches.at(3) * macroField.at(3);
551 } else {
552 OOFEM_ERROR("Unknown element type\n");
553 }
554 }
555 } else {
556 valueArray.resize(3);
557 }
558
559 vtkPiece.setPrimaryVarInNode(type, inode, std :: move(valueArray) );
560 }
561 }
562 }
563}
564
565void
566VTKXMLPeriodicExportModule :: exportIntVars(ExportRegion &vtkPiece, Set& region, IntArray& internalVarsToExport, NodalRecoveryModel& smoother, TimeStep *tStep)
567{
568 Domain *d = emodel->giveDomain(1);
569 int nnodes = d->giveNumberOfDofManagers();
570 InternalStateType isType;
571 FloatArray answer;
572
573 smoother.clear(); // Makes sure smoother is up-to-date with potentially new mesh.
574 //const IntArray& mapG2L = vtkPiece.getMapG2L();
575 const IntArray& mapL2G = vtkPiece.getMapL2G();
576
577 // Export of Internal State Type fields
579 for ( int field = 1; field <= internalVarsToExport.giveSize(); field++ ) {
580 isType = ( InternalStateType ) internalVarsToExport.at(field);
581
582 for ( int nodeNum = 1; nodeNum <= mapL2G.giveSize(); nodeNum++ ) {
583 if ( nodeNum <= nnodes && mapL2G.at(nodeNum) <= nnodes && mapL2G.at(nodeNum) != 0 ) { //no special treatment for master nodes
584 Node *node = d->giveNode(mapL2G.at(nodeNum) );
585 this->getNodalVariableFromIS(answer, node, tStep, isType, region, smoother);
586 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
587 } else { //special treatment for image nodes
588 //find the periodic node, enough to find the first occurrence
589 int pos = 0;
590 if ( mapL2G.at(nodeNum) != 0 ) {
591 pos = regionToUniqueMap.findFirstIndexOf(mapL2G.at(nodeNum) );
592 }
593
594 if ( pos ) {
595 Node *node = d->giveNode(periodicMap.at(pos) );
596 this->getNodalVariableFromIS(answer, node, tStep, isType, region, smoother);
597 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
598 } else { //fill with zeroes
600 int ncomponents = giveInternalStateTypeSize(valType);
601 answer.resize(ncomponents);
602
603 if ( isType == IST_BeamForceMomentTensor ) {
604 answer.resize(6);
605 }
606
607 answer.zero();
608 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
609 }
610 }
611 }
612 }
613}
614} // end namespace oofem
#define REGISTER_ExportModule(class)
int giveNumberOfDofs() const
Definition dofmanager.C:287
void giveCompleteMasterDofIDArray(IntArray &dofIDArray) const
Definition dofmanager.C:257
double giveCoordinate(int i) const
Definition dofmanager.h:383
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
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
Node * giveNode(int i) const
Definition element.h:629
virtual const IntArray giveLocation()
Definition element.h:1223
virtual bool isActivated(TimeStep *tStep)
Definition element.C:838
virtual int giveNumberOfNodes() const
Definition element.h:703
elementParallelMode giveParallelMode() const
Definition element.h:1139
virtual void recalculateCoordinates(int nodeNumber, FloatArray &coords)
Definition element.h:1224
EngngModel * emodel
Problem pointer.
Stores all neccessary data (of a region) in a VTKPiece so it can be exported later.
IntArray & getMapL2G()
void setInternalVarInNode(InternalStateType type, int nodeNum, FloatArray valueArray)
void setCellType(int cellNum, int type)
void setNumberOfInternalVarsToExport(const IntArray &ists, int numNodes)
void setNumberOfPrimaryVarsToExport(const IntArray &primVars, int numNodes)
void setConnectivity(int cellNum, IntArray &nodes)
void setPrimaryVarInNode(UnknownType type, int nodeNum, FloatArray valueArray)
IntArray & getMapG2L()
void setOffset(int cellNum, int offset)
void setNumberOfCells(int numCells)
void setNodeCoords(int nodeNum, const FloatArray &coords)
void setNumberOfNodes(int numNodes)
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
std::vector< int >::iterator end()
Definition intarray.h:72
void resizeWithValues(int n, int allocChunk=0)
Definition intarray.C:64
void resize(int n)
Definition intarray.C:73
std::vector< int >::iterator begin()
Definition intarray.h:71
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
const IntArray & giveElementList()
Definition set.C:158
bool isElementComposite(Element *elem)
void exportCellVars(ExportRegion &piece, Set &region, IntArray &cellVarsToExport, TimeStep *tStep)
Exports cell variables (typically internal variables).
void giveElementCell(IntArray &answer, Element *elem)
void getNodalVariableFromIS(FloatArray &answer, Node *node, TimeStep *tStep, InternalStateType type, Set &region, NodalRecoveryModel &smoother)
int giveCellType(Element *element)
void getNodalVariableFromPrimaryField(FloatArray &answer, DofManager *dman, TimeStep *tStep, UnknownType type, Set &region, NodalRecoveryModel &smoother)
IntArray internalVarsToExport
List of InternalStateType values, identifying the selected vars for export.
std::unique_ptr< NodalRecoveryModel > smoother
Smoother.
IntArray primaryVarsToExport
List of primary unknowns to export.
IntArray cellVarsToExport
List of cell data to export.
NodalRecoveryModel * giveSmoother()
Returns the internal smoother.
std::unique_ptr< NodalRecoveryModel > primVarSmoother
Smoother for primary variables.
void giveSwitches(IntArray &answer, int location)
void exportPrimaryVars(ExportRegion &vtkPiece, Set &region, IntArray &primaryVarsToExport, NodalRecoveryModel &smoother, TimeStep *tStep) override
void exportIntVars(ExportRegion &vtkPiece, Set &region, IntArray &internalVarsToExport, NodalRecoveryModel &smoother, TimeStep *tStep) override
int initRegionNodeNumbering(ExportRegion &piece, Domain *domain, TimeStep *tStep, Set &region) override
#define OOFEM_ERROR(...)
Definition error.h:79
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
int giveInternalStateTypeSize(InternalStateValueType valType)
Definition cltypes.C:229
InternalStateValueType
Determines the type of internal variable.
InternalStateValueType giveInternalStateValueType(InternalStateType type)
Definition cltypes.C:75

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