muMECH  1.0
mesh.cpp
Go to the documentation of this file.
1 //********************************************************************************************************
2 // code: ### ### ##### #### ## ##
3 // ## ## ######## ## ## ## ## ##
4 // ## ## ## ## ## ### ## ######
5 // ## ## ## ## ## ## ## ## ##
6 // ##### ## ## ##### #### ## ##
7 // ##
8 //
9 // name: mesh.cpp
10 // author(s): Ladislav Svoboda
11 // language: C, C++
12 // license: This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 //********************************************************************************************************
26 
27 // toto je kvuli WIN32_LEAN_AND_MEAN
28 #include "types.h"
29 
30 //included libraries
31 #include "mesh.h"
32 
33 #include "problem.h"
34 #include "mnode.h"
35 #include "melement.h"
36 #include "vtk.h"
37 #include "esuf.h"
38 #include "matrixOperations.h"
39 
40 #include "librw.h"
41 #include "gelib.h"
42 
43 #include <string.h>
44 
45 
46 namespace mumech {
47 
49 Mesh :: Mesh (long i, const Problems *p)
50 {
51  // ASSIGNED PROBLEMS
52  id = i;
53  npa = 5;
54  np = 0;
55  P = new const Problems*[npa]; memset (P, 0, npa*sizeof(Problem*));
56 
57  // MESH GEOMETRY
58  coll = -1;
59 
60  md = 0;
61  mtA = MT_VOID;
62 
63  volume = -1;
64 
65  // MESH COMPONENTS
66  nNodes = nElems = 0;
67  Nodes = NULL;
68  Elems = NULL;
69 
70  // MESH RESULTS
71  nLC = -77;
72  no_dspl_rf = no_strn_rf = no_strs_rf = NULL;
73  el_dspl_rf = el_strn_rf = el_strs_rf = NULL;
74 
75  //displc = strain = stress = NULL;
76 
77  //
78  if (p)
79  this->add_problem(p);
80 
81 }
83 Mesh :: Mesh (long i, const Problems *p, const Mesh *src)
84 {
85  // ASSIGNED PROBLEMS
86  id = i;
87  npa = 5;
88  np = 0;
89  P = new const Problems*[npa]; memset (P, 0, npa*sizeof(Problems*));
90 
91  // MESH GEOMETRY
92  coll = src->coll;
93 
94  md = src->md;
95  mtA = src->mtA; if(mtA != MT_GENERAL) _errorr("only general mesh supported in copy constructor");
96 
97  volume = -1;
98 
99  // MESH COMPONENTS
100  nNodes = src->nNodes;
101  Nodes = new mNode*[nNodes];
102  for (long i=0; i<nNodes; i++)
103  Nodes[i] = new mNode(i, this, src->Nodes[i]);
104 
105  nElems = src->nElems;
106  Elems = new mElement*[nElems];
107  for (long i=0; i<nElems; i++)
108  Elems[i] = new mElement(i, this, src->Elems[i]);
109 
110  // MESH RESULTS
111  nLC = -77; if (src->nLC != -77) errol;
112  no_dspl_rf = no_strn_rf = no_strs_rf = NULL; if (src->no_dspl_rf != NULL || src->no_strn_rf != NULL || src->no_strs_rf != NULL) _errorr("results data not supported in copy constructor");
113  el_dspl_rf = el_strn_rf = el_strs_rf = NULL; if (src->el_dspl_rf != NULL || src->el_strn_rf != NULL || src->el_strs_rf != NULL) _errorr("results data not supported in copy constructor");
114 
115  //displc = strain = stress = NULL;
116 
117  //
118  if (p)
119  this->add_problem(p);
120 
121 }
122 
125 {
126  memset (P, 0, npa*sizeof(Problem*));
127  delete [] P;
128 
129  if (Nodes) for (int i=0; i<nNodes; i++) delete Nodes[i];
130  if (Elems) for (int i=0; i<nElems; i++) delete Elems[i];
131 
132  delete [] Nodes;
133  delete [] Elems;
134 
141 
142  // if (displc) { for (int i=0; i<nLC; i++) delete [] displc[i]; delete [] displc; }
143  // if (strain) { for (int i=0; i<nLC; i++) delete [] strain[i]; delete [] strain; }
144  // if (stress) { for (int i=0; i<nLC; i++) delete [] stress[i]; delete [] stress; }
145 }
146 
149 {
150  if (p->is_converted_to_equivalent() == false) errol;
151 
152  // number of load cases
153  if (this->nLC == -77)
154  this->nLC = p->give_nLC();
155  else
156  if (this->nLC != p->give_nLC())
157  errol;
158 
159 
160  //
161  P[np++] = p;
162  return np-1;
163 }
164 
165 //
166 void Mesh :: set_coll (int val)
167 {
168  if (coll != -1) errol;
169  coll = val;
170 
171  if (md != 0) errol;
172  if (coll == 3) md = 2;
173  else if (coll == 0) md = 3;
174  else errol;
175 }
176 
177 
178 
180 bool Mesh :: equal_dimensions (int pid) const
181 {
182  return this->md == this->P[pid]->give_dimension();
183 }
184 
185 
187 bool Mesh :: is_unset (void)
188 {
189  return ! ( coll != -1 || mtA != MT_VOID ||
190  volume != -1.0 ||
191  nNodes != 0 || nElems != 0 ||
192  Nodes != NULL || Elems != NULL ||
193  no_dspl_rf != NULL || no_strn_rf != NULL || no_strs_rf != NULL ||
194  el_dspl_rf != NULL || el_strn_rf != NULL || el_strs_rf != NULL
195  );
196 }
197 
199 void Mesh :: scale (const double *s)
200 {
201  bool twd = this->md == 2;
202 
203  for (long i=0; i<nNodes; i++) {
204  Nodes[i]->coords.x *= s[0];
205  Nodes[i]->coords.y *= s[1];
206  if (twd) Nodes[i]->coords.z = 0.0;
207  else Nodes[i]->coords.z *= s[2];
208  }
209 }
210 
212 void Mesh :: local2global (const double *origin, const double *TInv)
213 {
214  bool twd = this->md == 2;
215 
216  for (long i=0; i<nNodes; i++) {
217  // rotating of the coordinate system
218  if (twd) Nodes[i]->coords.beRotatedBy2d(TInv);
219  else Nodes[i]->coords.beRotatedBy(TInv);
220 
221  // swap of coordinate systems
222  Nodes[i]->coords.add(origin);
223  }
224 }
225 
228 {
229  nNodes = nn;
230  if (Nodes) errol;
231  Nodes = new mNode*[nNodes];
232  for (long i=0; i<nNodes; i++)
233  Nodes[i] = new mNode(i, this);
234 }
237 {
238  nElems = ne;
239  if (Elems) errol;
240  Elems = new mElement*[nElems];
241  for (long i=0; i<nElems; i++)
242  Elems[i] = new mElement(i, this);
243 }
244 
246 void Mesh :: shift_id (long snn, long sne)
247 {
248  for (long i=0; i<nNodes; i++)
249  Nodes[i]->id += snn;
250 
251  for (long i=0; i<nElems; i++) {
252  Elems[i]->id += sne;
253  AddScalarToVector(snn, Elems[i]->nodes, Elems[i]->nnodes);
254  }
255 }
256 
257 
260 void Mesh :: generate_regular_mesh (const double *p1, const double *p2, const long *n)
261 {
262  if (this->geom_is_readed()) _errorr("mesh data already given");
263  mtA = MT_REGULAR;
264 
265  ; if ( n[0] && n[1] && n[2]) this->set_coll(0);
266  else if (!n[0] && n[1] && n[2]) this->set_coll(1);
267  else if ( n[0] && !n[1] && n[2]) this->set_coll(2);
268  else if ( n[0] && n[1] && !n[2]) this->set_coll(3);
269  else _errorr("");
270 
271  long i, j, k, l;
272 
273  //
274  CopyVector (p1, point1, 3);
275  CopyVector (p2, point2, 3);
276  CopyVector (n, nsegs, 3);
277  if (coll == 1) delta[0] = 0.0; else delta[0] = (p2[0] - p1[0]) / n[0];
278  if (coll == 2) delta[1] = 0.0; else delta[1] = (p2[1] - p1[1]) / n[1];
279  if (coll == 3) delta[2] = 0.0; else delta[2] = (p2[2] - p1[2]) / n[2];
280 
281 
282  // NODES
283  this->set_and_alloc_nNodes ( (n[0] + 1) * (n[1] + 1) * (n[2] + 1) );
284 
285  //
286  l = 0;
287  for (k=0; k<n[2]+1; k++)
288  for (j=0; j<n[1]+1; j++)
289  for (i=0; i<n[0]+1; i++) {
290  Nodes[l]->coords[0] = p1[0] + i * delta[0];
291  Nodes[l]->coords[1] = p1[1] + j * delta[1];
292  Nodes[l]->coords[2] = p1[2] + k * delta[2];
293  l++;
294  }
295 
296 
297  // ELEMENTS
298  this->set_and_alloc_nElems( (n[0] ? n[0] : 1) * (n[1] ? n[1] : 1) * (n[2] ? n[2] : 1) );
299 
300  // element type
301  int et;
302  if (coll) et = 9; // 2D - 9 - quad (8 - pixel, ma otoceny cislovani uzlu!!)
303  else et = 12; // 3D - 12 - hexahedron (11 - voxel, ma otoceny cislovani uzlu!!)
304  //
305  for (i=0; i<nElems; i++)
306  Elems[i]->set_type(et);
307 
308  // element nodes
309  l = 0;
310  if (coll == 0) {
311  for (i=0; i<n[0]; i++)
312  for (j=0; j<n[1]; j++)
313  for (k=0; k<n[2]; k++) {
314  Elems[l]->nodes[0] = i + j *(n[0]+1) + k *(n[0]+1)*(n[1]+1) ;
315  Elems[l]->nodes[1] = i+1 + j *(n[0]+1) + k *(n[0]+1)*(n[1]+1) ;
316  Elems[l]->nodes[2] = i+1 + (j+1)*(n[0]+1) + k *(n[0]+1)*(n[1]+1) ;
317  Elems[l]->nodes[3] = i + (j+1)*(n[0]+1) + k *(n[0]+1)*(n[1]+1) ;
318 
319  Elems[l]->nodes[4] = i + j *(n[0]+1) + (k+1)*(n[0]+1)*(n[1]+1) ;
320  Elems[l]->nodes[5] = i+1 + j *(n[0]+1) + (k+1)*(n[0]+1)*(n[1]+1) ;
321  Elems[l]->nodes[6] = i+1 + (j+1)*(n[0]+1) + (k+1)*(n[0]+1)*(n[1]+1) ;
322  Elems[l]->nodes[7] = i + (j+1)*(n[0]+1) + (k+1)*(n[0]+1)*(n[1]+1) ;
323  l++;
324  }
325  }
326  else if (coll == 3) {
327  for (i=0; i<n[0]; i++)
328  for (j=0; j<n[1]; j++) {
329  Elems[l]->nodes[0] = i + j *(n[0]+1) ;
330  Elems[l]->nodes[1] = i+1 + j *(n[0]+1) ;
331  Elems[l]->nodes[2] = i+1 + (j+1)*(n[0]+1) ;
332  Elems[l]->nodes[3] = i + (j+1)*(n[0]+1) ;
333  l++;
334  }
335  }
336  else _errorr("");
337 
338 }
339 
341 int Mesh :: file_type_s2e (const char *s)
342 {
343  if (_STRCMP(s, "2D" ) == 0) return 3;
344  else if (_STRCMP(s, "3D" ) == 0) return 0;
345  else _errorr2 ("Invalid structure of the given VTK file, the key word %s at the second line is not supported", s);
346  return -1;
347 }
348 
349 
350 
353 
355 void Mesh :: read_geometry_file_vtk (const char *vtkMeshFile, int pid, int lc, bool add)
356 {
357  if (this->geom_is_readed()) {
358  if (!add) _errorr("mesh data already readed");
359  }
360  else {
361  if (add) _errorr("mesh data not readed");
362  else mtA = MT_GENERAL;
363  }
364 
365  // reading type
366  MeshTypeRead mtr = MTR_VOID;
367  if (pid == -1 && lc == -1 && add == false)
368  mtr = MTR_geom;
369  else if (pid != -1 && lc != -1 && add == false)
370  mtr = MTR_fem;
371  else if (pid != -1 && lc != -1 && add == true)
372  mtr = MTR_femadd;
373  else
374  errol;
375 
376 
377  //if (PP[0]->give_verbose() > 0)
378  // printf( "Reading of VTK file of points, please wait ...\n" );
379 
380  // open stream with automatic detection VTK legaci/XML file format
381  char *filename = new char[255];
382  strcpy(filename, vtkMeshFile);
383  Stream *stream = new Stream();
384  stream->open(STRM_void, "r", (const char*&)filename); // do not delete filename, it is deleted inside of the function
385 
386  //
387  char *WORD=NULL;
388  const XMLElement *xnel = NULL;
389 
390  bool lgc = stream->isFile();
391 
392  if (lgc) WORD = new char[255];
393 
394 
395  // HEAD OD FILE
396  if (lgc) {
397  // 1. line
398  FP_skip_line (stream->file());
399 
400  // 2. line
401  // Only strictly 2d or 3d meshes are supported. So I want to know it in advance by keyword in comment line.
402  FP_scan_word (stream->file(), WORD);
403  FP_skip_line (stream->file());
404 
405  int cll = this->file_type_s2e (WORD);
406  if (!add)
407  this->set_coll (cll);
408  else
409  if (cll != this->coll) errol;
410 
411  // 3. line
412  FP_scan_expected_word_exit (stream->file(), "ASCII", "Invalid structure of the given VTK file", true);
413  FP_skip_line (stream->file());
414  // 4. line
415  FP_scan_expected_word_exit (stream->file(), "DATASET UNSTRUCTURED_GRID", "Invalid structure of the given VTK file", true);
416  FP_skip_line (stream->file());
417  }
418  else {
419  // check head of xml file and read possible ctrl section
420  // return XMLElement "Piece"
421  const XMLNode *parent = stream->tixnod();
422 
423  //* declaration - delete if present
424  if (parent->FirstChild()->ToDeclaration() != NULL) stream->tixnod()->DeleteChild( stream->tixnod()->FirstChild() );
425 
426  //* comment - delete if present
427  while (true)
428  if (parent->FirstChild()->ToComment() != NULL) stream->tixnod()->DeleteChild( stream->tixnod()->FirstChild() );
429  else break;
430 
431  //
432  parent = XP_give_unique_expected_elem (parent, "VTKFile");
433  stream->relink_downF();
434 
436  XP_check_expected_attribute (parent, "type", "UnstructuredGrid");
437  XP_check_expected_attribute (parent, "version", "0.1");
438  XP_check_expected_attribute (parent, "byte_order", "LittleEndian");
439 
440  //
441  parent = XP_give_unique_expected_elem (parent, "UnstructuredGrid", false);
442  stream->relink_downF();
443 
444  // read AppendedData section
445  parent = parent->NextSibling();
446  if (! parent)
447  _errorr("No AppendedData section");
448 
449  if (_STRCMP(parent->Value(), "AppendedData") != 0) _errorr ("name of xelement is not \"AppendedData\"");
450 
451  if (! (parent = parent->FirstChild ())) _errorr("No child in AppendedData");
452  if ( parent->Value()[0] != '_' ) _errorr("There is no character \'_\' at the start of section AppendedData");
453  parent = parent->NextSibling();
454 
455  if (_STRCMP(parent->Value(), "Input_Type") != 0) _errorr("name of xelement is not Input_Type");
456 
457  int cll = this->file_type_s2e (parent->ToElement()->GetText());
458  if (!add)
459  this->set_coll (cll);
460  else
461  if (cll != this->coll) errol;
462 
463  while (parent->NextSibling()) {
464  errol;
465  }
466 
467  // go to Piece
468  XP_give_unique_expected_elem (stream->tixnod(), "Piece");
469  stream->relink_downF();
470  xnel = stream->tixel();
471  }
472 
473 
474  // variable declaration
475  Stream auxstrm;
476  //
477  bool status = true, prnt;
478  int auxi;
479  long i, j, nn, noel, cno, offset, auxl;
480  char ed='-';
481  const char *data=NULL, *offs=NULL, *typs, *str;
482  char LINE[1023];
483  int lLINE=1023;
484  VTKrange range = VTKR_void;
485 
486  cno = 0;
487  prnt = true;
488  while (true) {
489  //* key WORD
490  if (lgc) {
491  if (fgets (LINE, lLINE, stream->file()) == NULL) break;
492  str = LINE;
493  SP_scan_word (str, WORD);
494  }
495  else {
496  if (prnt) { if (! stream->relink_downF()) errol; else prnt = false; }
497  else { if (! stream->relink_next()) break; }
498  WORD = (char *)stream->tixel()->Value();
499  }
500 
501  //* ******************
502  //* *** POINTS ***
503  //* ******************
504  if (_STRCMP(WORD, "Points") == 0) {
505  if (range == VTKR_void) range = VTKR_points; else errol;
506 
507  // number of nodes
508  if (lgc) {
509  SP_scan_number (str, noel);
510  SP_scan_expected_word2_exit (str, "double", "float", "Invalid structure of the given VTK file, unsupported datatype of POINTS", CASE);
511  }
512  else {
513  xnel->ToElement()->QueryLongAttribute("NumberOfPoints", &noel);
514  data = XP_giveDAtext (stream->tixel(), 1, true, "ascii", "Float32", NULL, &(auxi=3));
515  }
516 
517  if (!add) {
518  // number of points
519  this->set_and_alloc_nNodes (noel);
520 
521  // coords
522  nNodes = 0;
523  if (coll) { // 2d
524  while (noel) { noel--;
525  if (lgc) { status += Nodes[nNodes]->coords.scan_xyz (stream->file()); if (Nodes[nNodes]->coords[2] != 0.0) _errorr("3. coordinates is not 0.0"); }
526  else { status += Nodes[nNodes]->coords.scan_xyz (data); if (Nodes[nNodes]->coords[2] != 0.0) _errorr("3. coordinates is not 0.0"); }
527  nNodes ++;
528  }
529  }
530  else {
531  while (noel) { noel--;
532  if (lgc) { status += Nodes[nNodes]->coords.scan_xyz (stream->file()); }
533  else { status += Nodes[nNodes]->coords.scan_xyz (data); status += (SP_skip_word(data) && SP_skip_word(data) && SP_skip_word(data)); }
534  nNodes ++;
535  }
536  }
537  }
538  else {
539  if (this->nNodes != noel) errol;
540  if (lgc) errol; // pokud legacy, tak tady musim preskocit radky asi noel radku
541  else data = NULL;
542  }
543 
544  if (lgc) FP_skip_line (stream->file());
545  }
546  //* *************************************
547  //* *** UNSTRUCTURED GRID - CELLS ***
548  //* *************************************
549  else if (_STRCMP(WORD, "CELLS") == 0) {
550  if (range == VTKR_points) range = VTKR_cells; else errol;
551 
552  // number of cells
553  if (lgc) {
554  SP_scan_number (str, noel);
555  SP_scan_number (str, cno);
556  }
557  else {
558  xnel->ToElement()->QueryLongAttribute("NumberOfCells" , &noel);
559  data = XP_giveDAtext (stream->tixel(), 1, false, "ascii", "Int32", "connectivity", NULL);
560  offs = XP_giveDAtext (stream->tixel(), 2, false, "ascii", "Int32", "offsets", NULL);
561  typs = XP_giveDAtext (stream->tixel(), 3, true, "ascii", "UInt8", "types", NULL);
562  }
563 
564  if (!add) {
565  this->set_and_alloc_nElems (noel);
566 
567  if (!lgc) offset = 0;
568  // elem nodes
569  for (i=0; i<noel; i++) {
570  // nn
571  if (lgc) { fscanf (stream->file(),"%ld",&nn); cno = cno - nn - 1; }
572  else { nn = offset; status += SP_scan_number (offs, offset); nn = offset - nn; }
573 
574  // Only strictly 2d or 3d meshes are supported.
575  // So, the element type can be determined from number of nodes.
576  int et;
577  if (coll) { // 2D
578  if (nn == 3) et = 5;
579  else errol;
580  }
581  else { // 3D
582  if (nn == 8) et = 12;
583  else errol;
584  }
585 
586  Elems[i]->set_type(et);
587 
588  //
589  for (j=0; j<nn; j++)
590  if (lgc) status += ( fscanf (stream->file(), "%ld", Elems[i]->nodes+j) == 1 );
591  else status += SP_scan_number (data, Elems[i]->nodes[j]);
592 
593  }
594 
595  if (lgc) FP_skip_line (stream->file(), 1);
596 
597  // types of elems
598  if (lgc) {
599  fgets (LINE, lLINE, stream->file()); str=LINE;
600  SP_scan_expected_word_exit (str, "CELL_TYPES", "Invalid structure of the given VTK file", CASE);
601  SP_scan_expected_number_exit (str, noel, "Invalid structure of the given VTK file, the number following CELL_TYPES");
602  }
603 
604  for (i=0; i<noel; i++) {
605  if (lgc) status += ( fscanf (stream->file(), "%ld", &auxl) == 1);
606  else status += SP_scan_number (typs, auxl);
607  if (auxl != Elems[i]->give_type()) errol;
608  }
609  }
610  else {
611  if (this->nElems != noel) errol;
612  if (lgc) errol; // pokud legacy, tak tady musim preskocit radky asi noel radku
613  else { data = NULL; offs = NULL; }
614  }
615 
616  if (lgc) FP_skip_line (stream->file(), 1);
617  }
618  //* *******************************
619  //* *** POLYDATA - ELEMENTS ***
620  //* *******************************
621  else if (_STRCMP(WORD, "LINES") == 0 || _STRCMP(WORD, "POLYGONS" ) == 0 || _STRCMP(WORD, "POLYS") == 0 || _STRCMP(WORD, "Vertices") == 0 || _STRCMP(WORD, "Verts") == 0 || _STRCMP(WORD, "Strips") == 0) {
622  _errorr2("Invalid structure of the given VTK file, the key word %s is not supported", WORD);
623  }
624  //* **********************
625  //* *** POINT_DATA ***
626  //* **********************
627  else if (_STRCMP(WORD, "POINT_DATA") == 0 || _STRCMP(WORD, "PointData") == 0) {
628  if (range == VTKR_cells || range == VTKR_fields) range = VTKR_pd; else errol;
629  ed = 'p';
630  // head
631  if (lgc) { SP_scan_expected_number_exit (str, nNodes, "The number following POINT_DATA is not equal to number of inclusions"); }
632  else { prnt = true; }
633  }
634  //* *********************
635  //* *** CELL_DATA ***
636  //* *********************
637  else if (_STRCMP(WORD, "CELL_DATA") == 0 || _STRCMP(WORD, "CellData") == 0) {
638  if (range == VTKR_cells || range == VTKR_data) range = VTKR_cd; else errol;
639  ed = 'c';
640  // head
641  if (lgc) { SP_scan_expected_number_exit (str, nElems, "The number following CELL_DATA is not equal to number of inclusions"); }
642  else { prnt = true; }
643  }
644  //* **************************
645  //* *** DATA - SCALARS ***
646  //* **************************
647  else if (_STRCMP(WORD, "SCALARS") == 0 || _STRCMP(WORD, "VECTORS") == 0 || _STRCMP(WORD, "TENSORS") == 0 || _STRCMP(WORD, "DataArray") == 0 || _STRCMP(WORD, "FIELD") == 0) {
648  if (range == VTKR_pd || range == VTKR_cd || range == VTKR_data) range = VTKR_data; else errol;
649 
650  // blok dat se nacita jen pro FEM sit, proto zde kontroluju zda to neni mumech reseni
651  //if (mtr != MTR_fem && mtr != MTR_femadd) continue;
652 
653  char type = WORD[0]; // save type of data - Scalar, Vector, Tensor, DataArray
654  // head
655  if (lgc) SP_scan_word (str, WORD);
656  else { WORD = (char *)stream->tixel()->ToElement()->Attribute("Name"); if (!WORD) _errorr ("there is no attribute \"Name\""); }
657 
658  if (type != 'F') {
659  //* *** DATA for CELLS ***
660  if (ed == 'c') {
661  // bacic
662  if (_STRCMP(WORD, "INCLUSION_ID") == 0) { auxl = 1; scan_DATA_field_head (stream, &auxstrm, str, type, auxl, 'i', WORD); for (j=0; j<nElems; j++) { if (ST_scan_number (&auxstrm, Elems[j]->region) == false) _errorr2 ("There is few numbers in section %s", WORD); Elems[j]->region--; } }
663  else if (_STRCMP(WORD, "MATERIALS") == 0) { auxl = 1; scan_DATA_field_head (stream, &auxstrm, str, type, auxl, 'i', WORD); for (j=0; j<nElems; j++) if (ST_scan_number (&auxstrm, auxl ) == false) _errorr2 ("There is few numbers in section %s", WORD); }
664  else if (_STRCMP(WORD, "strain_planestrain") == 0) {
665  stream->tixel()->ToElement()->QueryLongAttribute("NumberOfComponents", &auxl);
666  this->set_elem_rslt_flags (false, true, false, pid, lc, 1);
667  scan_DATA_field_head (stream, &auxstrm, str, type, auxl, 'f', WORD);
668  for (j=0; j<nElems; j++) {
669  Elems[j]->allocate_fields(pid);
670  if (ST_scan_array(&auxstrm, auxl, Elems[j]->strain[pid][lc]) == false) _errorr2 ("There is few numbers in section %s", WORD);
671  // termitovo: zde predpokladam voightovu notaci, proto delim dvojkou
672  // zatim to je jen pro 2d, pro 3d bych prvne musel zkontrolovat, zda je dodrzena FEEP notace poradi clenu ve 3d, ve 2d je to jedno
673  if (auxl != 3) errol; // now only 2d
674  Elems[j]->strain[pid][lc][2] /= 2.0;
675  if (auxl != P[pid]->nstrain_one()) {
676  if(auxl == 3 && P[pid]->nstrain_one()==6) {
677  Elems[j]->strain[pid][lc][3] = Elems[j]->strain[pid][lc][2];
678  Elems[j]->strain[pid][lc][2] = Elems[j]->strain[pid][lc][4] = Elems[j]->strain[pid][lc][5] = 0.0;
679  }
680  else errol;
681  }
682  }
683  }
684  else if (_STRCMP(WORD, "stress_planestrain") == 0) {
685  stream->tixel()->ToElement()->QueryLongAttribute("NumberOfComponents", &auxl);
686  this->set_elem_rslt_flags (false, false, true, pid, lc, 1);
687  scan_DATA_field_head (stream, &auxstrm, str, type, auxl, 'f', WORD);
688  for (j=0; j<nElems; j++) {
689  Elems[j]->allocate_fields(pid);
690  if (ST_scan_array(&auxstrm, auxl, Elems[j]->stress[pid][lc]) == false) _errorr2 ("There is few numbers in section %s", WORD);
691  if (auxl != P[pid]->nstrain_one()) {
692  if(auxl == 3 && P[pid]->nstrain_one()==6) {
693  Elems[j]->stress[pid][lc][3] = Elems[j]->stress[pid][lc][2];
694  Elems[j]->stress[pid][lc][2] = Elems[j]->stress[pid][lc][4] = Elems[j]->stress[pid][lc][5] = 0.0;
695  }
696  else errol;
697  }
698  }
699  }
700  else
701  _errorr2 ("Invalid name of SCALARS/DataArray for CELL_DATA/PointData \"%s\"", WORD);
702 
703  }
704  //* *** DATA for POINTS ***
705  else if (ed == 'p') {
706  if (_STRCMP(WORD, "uknw_displacement") == 0) {
707  stream->tixel()->ToElement()->QueryLongAttribute("NumberOfComponents", &auxl);
708  bool thzero = false;
709  double auxd;
710 
711  if (auxl != P[pid]->ndisplc_one()) {
712  if (auxl != 3 && P[pid]->ndisplc_one() != 2)
713  errol;
714  else
715  thzero = true;
716  }
717 
718  this->set_node_rslt_flags (true, false, false, pid, lc, 1);
719  scan_DATA_field_head (stream, &auxstrm, str, type, auxl, 'f', WORD);
720  if (thzero) auxl = 2;
721  for (j=0; j<nNodes; j++) {
722  Nodes[j]->allocate_fields(pid);
723  if (ST_scan_array(&auxstrm, auxl, Nodes[j]->displc[pid][lc]) == false) _errorr2 ("There is few numbers in section %s", WORD);
724  if (thzero) {
725  ST_scan_number(&auxstrm,auxd);
726  if (auxd != 0.0)
727  errol;
728  }
729  }
730  }
731  else if (_STRCMP(WORD, "uknw_rotation") == 0) {
732  if (lgc) _errorr("have to skip values");
733 
734  }
735  else
736  _errorr2 ("Invalid name of SCALARS/DataArray for POINT_DATA/PointData \"%s\"", WORD);
737  }
738  else errol;
739  }
740  else errol;
741 
742  if (lgc) FP_skip_line (stream->file(), 1);
743  else { if (stream->tixel()->NextSibling() == NULL) stream->relink_up(); }
744  }
745  else if (_STRCMP(WORD, "") == 0) {;}
746  else _errorr2 ("Invalid structure of the given VTK file, unexpected key word \"%s\"", WORD);
747 
748  if (lgc) { if (cno) _errorr2 ("cno(%ld) is not zero", cno); }
749  else {
750  if (data && data[0] != '\0') _errorr2("CellData of name \"%s\" has too many numbers", WORD);
751  if (offs && offs[0] != '\0') _errorr("error");
752  }
753  }
754 
755  if (lgc) delete [] WORD;
756  if (status == false) _errorr("error");
757 
758  //* close
759  stream->close();
760  delete stream;
761 
762 }
763 
767 void Mesh :: generate_regularSphereMesh_2d (int n, const double *a)
768 {
769  if (!this->is_unset()) _errorr("Mesh in the function give_unitSphereMesh_3d is not empty/unset");
770  if (n < 3 || n > 20)
771  _errorr1 ("Number of segments must be between 3 and 20!");
772 
773  //
774  this->set_coll(3);
775  this->mtA = MT_GENERAL;
776 
777  // ALOCATING NODES
778  this->set_and_alloc_nNodes (n * 4 + 1); // n nodes for each quater of inclusion * 4 quaters + 1 center point
779 
780  // SETTING RADIAL COORDS FOR NODES
781  // >> Nodes[i = 0] = center of inclusion, already set to 0.0 in constructor
782  // >> r = 1.0, no need to multiply by 'r'
783  double phi = ((90.0 / n) * PI) / 180.0; // angle between two adjacent nodes (in radians)
784  for (long i = 1, j = i - 1; i < this->nNodes; i++, j++) {
785  this->Nodes[i]->coords.x = cos (phi * j);
786  this->Nodes[i]->coords.y = sin (phi * j);
787  // z not used and already set to 0.0 in constructor
788  }
789 
790  // ALOCATING ELEMENTS
791  this->set_and_alloc_nElems (n * 4); // n elements for each quater of inclusion * 4 quaters
792 
793  // SETTING CORRECT NODES FOR EACH ELEMENT
794  int startNode = 1, node = startNode;
795  for (long i = 0; i < this->nElems; i++) {
796  this->Elems[i]->set_type (5); // = VTK_TRIANGLE
797  this->Elems[i]->nodes[0] = 0; // all elements are connected with the Node[0] in center of inclusion
798  this->Elems[i]->nodes[1] = node++; // nodes[1] = node, then node is incremented by 1
799  this->Elems[i]->nodes[2] = (i == (this->nElems - 1)) ? startNode : node; // if last element then need co connect with startNode on first element
800  }
801 
802  return;
803 }
804 
808 void Mesh :: generate_regularSphereMesh_3d (int n, const double *a)
809 {
810  if (!this->is_unset()) _errorr("Mesh in the function give_unitSphereMesh_3d is not empty/unset");
811  if (n < 3 || n > 20)
812  _errorr1 ("Number of segments must be between 3 and 20!");
813 
814  //
815  this->set_coll(0);
816  this->mtA = MT_GENERAL;
817 
818  // ALOCATING NODES
819  int nNodesOnLayer = (n * 4); // n nodes for quater circle * 4 quaters
820  int nLayersOfNodes = (n * 2 - 1); // n layers of nodes for hemisphere * 2 hemispheres - 1 duplicit center layer (top and bottom single nodes are not counted as layer)
821 
822  this->set_and_alloc_nNodes (nNodesOnLayer * nLayersOfNodes + 3); // + 3 nodes (top, bottom and center)
823 
824  // SETTING SPHERICAL COORDS FOR NODES
825  // r = 1.0, no need to multiply by 'r'
826 
827  // Nodes[0] = center of inclusion, already set to 0.0 in constructor
828  this->Nodes[1]->coords.x = 1.0; // top node
829  this->Nodes[this->nNodes - 1]->coords.x = -1.0; // bottom node
830 
831  double *phi = new double[2*n];
832  // uniform distribution of angles
833  if (a == NULL) {
834  double ph = ((90.0 / n) * PI) / 180.0;
835  for (long i = 0; i < 2*n; i++)
836  phi[i] = ph;
837  }
838  else {
839  phi[0] = PI/2.0 / n;
840  double sum = PI/2.0 * a[1]/a[0];
841  double k;
842 
843  do {
844  phi[0] = phi[0] * 0.5 * PI / sum;
845  k = phi[0] / give_curvature (0.5 * PI - 0, a[0], a[1]);
846  sum = phi[0];
847  for (long i = 1; i < n; i++) {
848  phi[0+i] = k * give_curvature (0.5 * PI - sum, a[0], a[1]);
849  sum += phi[0+i];
850  }
851  } while (fabs(sum - 0.5 * PI) > 0.01*PI);
852 
853  for (long i = 0; i < n; i++) phi[n+i] = phi[i];
854  for (long i = 0; i < n; i++) phi[n-1-i] = phi[n+i];
855 
856  sum = 0.;
857  }
858 
859  int nodeID = 2;
860  double theta = ((90.0 / n) * PI) / 180.0; // angle between positive x-axis and node (in radians)
861 
862  double PHI = 0.0;
863  for (long i = 0; i < nLayersOfNodes; i++) {
864  PHI += phi[i];
865  for (long j = 0; j < nNodesOnLayer; j++) {
866  this->Nodes[nodeID]->coords.y = sin (PHI) * cos (theta * j);
867  this->Nodes[nodeID]->coords.z = sin (PHI) * sin (theta * j);
868  this->Nodes[nodeID]->coords.x = cos (PHI);
869  nodeID++;
870  }
871  }
872 
873  delete [] phi;
874 
875  // ALOCATING ELEMENTS
876  int nElemsInTopOrBottomLayers = n * 4; // n elements for each quater * 4 quaters
877  int nElemsInMiddleLayer = n * 2 * 4; // n segments for each quater * 2 elements for segment (two tetrahedrons on top of each other) * 4 quaters
878  int nMiddleLayers = (n - 1) * 2; // (n layers for hemisphere - top/bottom layer) * 2 hemispheres
879 
880  this->set_and_alloc_nElems (nElemsInTopOrBottomLayers * 2 + nElemsInMiddleLayer * nMiddleLayers);
881 
882  // SETTING CORRECT NODES FOR EACH ELEMENT
883  int elemID = 0;
884 
885  // top layer
886  int startNode = 2;
887  nodeID = startNode;
888  for (long i = 0; i < nElemsInTopOrBottomLayers; i++) {
889  this->Elems[elemID]->set_type (10); // = VTK_TETRA
890  this->Elems[elemID]->nodes[0] = 1; // all elements are connected with top node
891  this->Elems[elemID]->nodes[1] = nodeID++; // nodes[1] = nodeID, then nodeID is incremented by 1
892  this->Elems[elemID]->nodes[2] = (i == nElemsInTopOrBottomLayers - 1) ? startNode : nodeID; // if last element of layer then need co connect with startNode on first element
893  this->Elems[elemID]->nodes[3] = 0; // all elements are connected with center node
894  elemID++;
895  }
896 
897  // middle layers
898  int nextLayerNodeID, nextLayerStartNode;
899  for (long i = 0; i < nMiddleLayers; i++) {
900  startNode = nNodesOnLayer * i + 2; // n nodes on layer * number of previous layers + 2 (center and top)
901  nodeID = startNode;
902  nextLayerStartNode = startNode + nNodesOnLayer; // start node + n nodes on one layer
903  nextLayerNodeID = nextLayerStartNode;
904  for (long j = 0; j < nElemsInMiddleLayer; j += 2) { // step is two because two elems are set at the same time
905  if (j % 4 == 0) { // first and all odd segments (to create zigzag pattern)
906  this->Elems[elemID]->set_type (10); // = VTK_TETRA
907  this->Elems[elemID]->nodes[0] = nodeID++;
908  this->Elems[elemID]->nodes[1] = nextLayerNodeID;
909  this->Elems[elemID]->nodes[2] = nodeID;
910  this->Elems[elemID]->nodes[3] = 0; // center node
911  elemID++;
912 
913  this->Elems[elemID]->set_type (10); // = VTK_TETRA
914  this->Elems[elemID]->nodes[0] = nodeID;
915  this->Elems[elemID]->nodes[1] = nextLayerNodeID++;
916  this->Elems[elemID]->nodes[2] = nextLayerNodeID;
917  this->Elems[elemID]->nodes[3] = 0; // center node
918  elemID++;
919  }
920  else { // second and all even segments (to create zigzag pattern)
921  this->Elems[elemID]->set_type (10); // = VTK_TETRA
922  this->Elems[elemID]->nodes[0] = nodeID;
923  this->Elems[elemID]->nodes[1] = nextLayerNodeID++;
924  this->Elems[elemID]->nodes[2] = (j == (nElemsInMiddleLayer - 2)) ? nextLayerStartNode : nextLayerNodeID; // if last segment of layer then need co connect with nextLayerstartNode
925  this->Elems[elemID]->nodes[3] = 0; // center node
926  elemID++;
927 
928  this->Elems[elemID]->set_type (10); // = VTK_TETRA
929  this->Elems[elemID]->nodes[0] = nodeID++;
930  this->Elems[elemID]->nodes[1] = (j == (nElemsInMiddleLayer - 2)) ? nextLayerStartNode : nextLayerNodeID; // if last segment of layer then need co connect with nextLayerstartNode
931  this->Elems[elemID]->nodes[2] = (j == (nElemsInMiddleLayer - 2)) ? startNode : nodeID; // if last segment of layer then need co connect with startNode
932  this->Elems[elemID]->nodes[3] = 0; // center node
933  elemID++;
934  }
935  }
936  }
937 
938  // bottom layer
939  startNode = this->nNodes - 1 - nNodesOnLayer; // all nodes - 1 (human vs computer numbering) - n nodes on one layer
940  nodeID = startNode;
941  for (long i = 0; i < nNodesOnLayer; i++) {
942  this->Elems[elemID]->set_type (10); // = VTK_TETRA
943  this->Elems[elemID]->nodes[0] = nodeID++;
944  this->Elems[elemID]->nodes[1] = this->nNodes - 1; // last node
945  this->Elems[elemID]->nodes[2] = (i == nNodesOnLayer - 1) ? startNode : nodeID;
946  this->Elems[elemID]->nodes[3] = 0; // center node
947  elemID++;
948  }
949 
950  return;
951 }
952 
953 
954 
955 //
956 void Mesh :: print_geometry_file_vtk (const char *rsltFileName, int pid, int lc, int nlc)
957 {
958  if (nlc == 0) nlc = this->nLC;
959 
960  // Recursive call this function for separate load cases.
961  if (nlc != 1) {
962  // Loop over all load cases.
963  for (int i=lc; i<lc+nlc; i++)
964  this->print_geometry_file_vtk (rsltFileName, pid, i, 1);
965 
966  return;
967  }
968 
969 
970  long i, j, auxl;
971  XMLElement *da;
972  Stream *stream;
973  bool lgc = true;
974  bool twodim = P[pid]->give_twodim();
975  char auxs[20001]; auxs[20000] = '\0';
976 
977  // allocate stream
978  if (lgc) stream = new Stream(STRM_file);
979  else stream = new Stream(STRM_tixel);
980 
981  //* START
982  char *filename = new char[255];
983  sprintf (filename, "%s.%02d.vtk", rsltFileName, lc); // do not delete filename, it is deleted inside of the function
984 
985  //
986  print_VTK_START (stream, filename);
987 
988  //* HEAD
989  char type[7];
990  if (twodim) sprintf (type,"2Drec");
991  else sprintf (type,"3Drec");
992 
993  if (lgc)
994  print_VTK_head (stream->file(), type);
995 
996  //* NODES
997  da = print_VTK_nodes_head (stream, nNodes);
998 
999  for (i=0; i<nNodes; i++) {
1000  sprintf (auxs, "%15.8e %15.8e %15.8e", Nodes[i]->coords[0], Nodes[i]->coords[1], Nodes[i]->coords[2]);
1001 
1002  if (lgc) fprintf (stream->file(), "%s\n", auxs);
1003  else da->InsertEndChild( stream->tix_doc()->NewText(auxs) );
1004  }
1005 
1006  // ELEMENTS
1007  if (lgc) {
1008  auxl = nElems;
1009  for (i=0; i<nElems; i++) auxl += Elems[i]->nnodes;
1010 
1011  fprintf (stream->file(), "CELLS %ld %ld\n", nElems, auxl);
1012  for (i=0; i<nElems; i++) {
1013  fprintf (stream->file(), "%ld", Elems[i]->nnodes);
1014  for (j=0; j<Elems[i]->nnodes; j++)
1015  fprintf (stream->file(), " %ld", Elems[i]->nodes[j]);
1016 
1017  fprintf (stream->file(), "\n");
1018  }
1019 
1020  fprintf (stream->file(), "CELL_TYPES %ld\n", nElems);
1021  for (i=0; i<nElems; i++)
1022  fprintf (stream->file(), "%ld\n", Elems[i]->give_type());
1023 
1024  }
1025  else {
1026  _errorr("not implemented");
1027  // stream->tixel()->SetAttribute("NumberOfCells", (int)Elems());
1028  //
1029  // XMLElement *cells = stream->tix_doc()->NewElement("Cells"); stream->tixel()->InsertEndChild(cells);
1030  //
1031  // XMLElement *dac = stream->tix_doc()->NewElement("DataArray"); cells->InsertEndChild(dac);
1032  // dac->SetAttribute("format", "ascii");
1033  // dac->SetAttribute("type", "Int32");
1034  // dac->SetAttribute("Name", "connectivity");
1035  //
1036  // XMLElement *dao = (XMLElement*)dac->ShallowClone(NULL); cells->InsertEndChild(dao);
1037  // dao->SetAttribute("Name", "offsets");
1038  //
1039  // XMLElement *dat = (XMLElement*)dac->ShallowClone(NULL); cells->InsertEndChild(dat);
1040  // dat->SetAttribute("type", "UInt8");
1041  // dat->SetAttribute("Name", "types");
1042  //
1043  // char auxs[255];
1044  // long off=0;
1045  // for (long i=0; i<Elems(); i++) {
1046  // Elems[i]->print_row_VTX (auxs); dac->InsertEndChild(stream->tix_doc()->NewText(auxs));
1047  // sprintf (auxs," %ld", off += Elems[i]->give_nno()); dao->InsertEndChild(stream->tix_doc()->NewText(auxs));
1048  // sprintf (auxs," %d", CellGeometry_e2i_VTK(Elems[i]->give_cellGeom())); dat->InsertEndChild(stream->tix_doc()->NewText(auxs));
1049  // }
1050  }
1051 
1052  // POINT DATA
1053  print_VTK_init_point_data (stream, this->nNodes);
1054 
1055  if (no_dspl_rf && no_dspl_rf[pid] && no_dspl_rf[pid][lc]) { da = print_VTK_data_head (stream, "Displacemet", 'v', 'f', 0); for (i=0; i<this->nNodes; i++) { print_values_Vector (auxs, this->Nodes[i]->displc[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1056  if (no_strn_rf && no_strn_rf[pid] && no_strn_rf[pid][lc]) { da = print_VTK_data_head (stream, "Strain", 't', 'f', 0); for (i=0; i<this->nNodes; i++) { print_values_Tensor (auxs, this->Nodes[i]->strain[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1057  if (no_strs_rf && no_strs_rf[pid] && no_strs_rf[pid][lc]) { da = print_VTK_data_head (stream, "Stress", 't', 'f', 0); for (i=0; i<this->nNodes; i++) { print_values_Tensor (auxs, this->Nodes[i]->stress[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1058 
1059 
1060  // CELL DATA
1061  print_VTK_init_cell_data (stream, this->nElems);
1062 
1063  if (el_dspl_rf && el_dspl_rf[pid] && el_dspl_rf[pid][lc]) { da = print_VTK_data_head (stream, "Displacemet", 'v', 'f', 0); for (i=0; i<this->nElems; i++) { print_values_Vector (auxs, this->Elems[i]->displc[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1064  if (el_strn_rf && el_strn_rf[pid] && el_strn_rf[pid][lc]) { da = print_VTK_data_head (stream, "Strain", 't', 'f', 0); for (i=0; i<this->nElems; i++) { print_values_Tensor (auxs, this->Elems[i]->strain[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1065  if (el_strs_rf && el_strs_rf[pid] && el_strs_rf[pid][lc]) { da = print_VTK_data_head (stream, "Stress", 't', 'f', 0); for (i=0; i<this->nElems; i++) { print_values_Tensor (auxs, this->Elems[i]->stress[pid][lc], twodim, 5); print_auxs (lgc, stream, da, auxs); } }
1066 
1067  // termitovo tento if predelat na flag, a vubec tento radek je hrozne zbastlenej, udelat print_value_Scalar ....
1068  if (Elems[0]->error && Elems[0]->error[pid]) { auxl = 1; da = print_VTK_data_head (stream, "Error_elem", 's', 'f', auxl); for (i=0; i<this->nElems; i++) { print_values_Scalar (auxs, this->Elems[i]->error[pid]+lc, auxl, 5); print_auxs (lgc, stream, da, auxs); } }
1069 
1070 
1071  // END
1072  print_VTK_FINISH (stream);
1073  delete stream;
1074 
1075 }//end of function: ()
1076 
1078 void Mesh :: set_node_rslt_flags (bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nlc)
1079 {
1080  if (this->geom_is_readed() == false) _errorr("problem geometry data not readed");
1081  if (nlc == 0) _errorr("nlc == 0");
1082 
1083  if (displc_flag) { if (!no_dspl_rf) no_dspl_rf = Allocate1Dbp(this->npa); if (!no_dspl_rf[pid]) no_dspl_rf[pid] = Allocate1Dbz(nLC); }
1084  if (strain_flag) { if (!no_strn_rf) no_strn_rf = Allocate1Dbp(this->npa); if (!no_strn_rf[pid]) no_strn_rf[pid] = Allocate1Dbz(nLC); }
1085  if (stress_flag) { if (!no_strs_rf) no_strs_rf = Allocate1Dbp(this->npa); if (!no_strs_rf[pid]) no_strs_rf[pid] = Allocate1Dbz(nLC); }
1086 
1087  for (int i=lc; i<lc+nlc; i++) {
1088  if (displc_flag) { if (no_dspl_rf[pid][i] == false) no_dspl_rf[pid][i] = true; else _errorr("Mesh: displacement at nodes already computed for given load case"); }
1089  if (strain_flag) { if (no_strn_rf[pid][i] == false) no_strn_rf[pid][i] = true; else _errorr("Mesh: strain at nodes already computed for given load case"); }
1090  if (stress_flag) { if (no_strs_rf[pid][i] == false) no_strs_rf[pid][i] = true; else _errorr("Mesh: stress at nodes already computed for given load case"); }
1091  }
1092 }
1094 void Mesh :: set_elem_rslt_flags (bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nlc)
1095 {
1096  if (this->geom_is_readed() == false) _errorr("problem geometry data not readed");
1097  if (nlc == 0) _errorr("nlc == 0");
1098 
1099  if (displc_flag) { if (!el_dspl_rf) el_dspl_rf = Allocate1Dbp(this->npa); if (!el_dspl_rf[pid]) el_dspl_rf[pid] = Allocate1Dbz(nLC); }
1100  if (strain_flag) { if (!el_strn_rf) el_strn_rf = Allocate1Dbp(this->npa); if (!el_strn_rf[pid]) el_strn_rf[pid] = Allocate1Dbz(nLC); }
1101  if (stress_flag) { if (!el_strs_rf) el_strs_rf = Allocate1Dbp(this->npa); if (!el_strs_rf[pid]) el_strs_rf[pid] = Allocate1Dbz(nLC); }
1102 
1103  for (int i=lc; i<lc+nlc; i++) {
1104  if (displc_flag) { if (el_dspl_rf[pid][i] == false) el_dspl_rf[pid][i] = true; else _errorr("Mesh: displacement at elems already computed for given load case"); }
1105  if (strain_flag) { if (el_strn_rf[pid][i] == false) el_strn_rf[pid][i] = true; else _errorr("Mesh: strain at elems already computed for given load case"); }
1106  if (stress_flag) { if (el_strs_rf[pid][i] == false) el_strs_rf[pid][i] = true; else _errorr("Mesh: stress at elems already computed for given load case"); }
1107  }
1108 }
1109 
1111 void Mesh :: compute_node_fields (char flag, bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nlc, PFCmode pfcMode)
1112 {
1113  const Problem *prob = dynamic_cast <const Problem*>(P[pid]);
1114  if (prob == NULL) errol;
1115 
1116  nlc = Problem::check_lc_nlc(lc, nlc, nLC);
1117  this->set_node_rslt_flags (displc_flag, strain_flag, stress_flag, pid, lc, nlc);
1118 
1119  // this->allocare_fields_at_nodes
1120  for (int i=0; i<nNodes; i++)
1121  Nodes[i]->allocate_fields(pid);
1122 
1123  double coords[3];
1124  double **displc, **strain, **stress;
1125 
1126  for (int i=0; i<nNodes; i++) {
1127  Nodes[i]->coords.copy_to(coords);
1128 
1129  displc = displc_flag ? Nodes[i]->displc[pid]+lc : NULL;
1130  strain = strain_flag ? Nodes[i]->strain[pid]+lc : NULL;
1131  stress = stress_flag ? Nodes[i]->stress[pid]+lc : NULL;
1132 
1133  prob->giveFieldsOfPoint(displc, strain, stress, coords, flag, lc, nlc, pfcMode, -3 , STRN_THEORETICAL_FEEP);
1134  }
1135 }
1136 
1138 void Mesh :: compute_element_fields (char flag, bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nlc, PFCmode pfcMode)
1139 {
1140  const Problem *prob = dynamic_cast <const Problem*>(P[pid]);
1141  if (prob == NULL) errol;
1142 
1143  nlc = Problem::check_lc_nlc(lc, nlc, nLC);
1144  this->set_elem_rslt_flags (displc_flag, strain_flag, stress_flag, pid, lc, nlc);
1145 
1146  //
1147  for (int i=0; i<nElems; i++)
1148  Elems[i]->allocate_fields(pid);
1149 
1150  for (int i=0; i<nElems; i++)
1151  Elems[i]->compute_centroids();
1152 
1153  double **displc, **strain, **stress;
1154 
1155  for (int i=0; i<nElems; i++) {
1156  displc = displc_flag ? Elems[i]->displc[pid]+lc : NULL;
1157  strain = strain_flag ? Elems[i]->strain[pid]+lc : NULL;
1158  stress = stress_flag ? Elems[i]->stress[pid]+lc : NULL;
1159 
1160  Elems[i]->region = prob->giveFieldsOfPoint(displc, strain, stress, Elems[i]->centroids, flag, lc, nlc, pfcMode, Elems[i]->region, STRN_THEORETICAL_FEEP);
1161  }
1162 }
1163 
1165 double Mesh :: give_total_volume (void) const
1166 {
1167  if (volume < 0.0) {
1168  double vol = 0.0;
1169 
1170  switch (this-> mtA) {
1171  case MT_REGULAR:
1172  if (this->coll) vol = (point2[0]-point1[0])*(point2[1]-point1[1]);
1173  else vol = (point2[0]-point1[0])*(point2[1]-point1[1])*(point2[2]-point1[2]);
1174  break;
1175  case MT_GENERAL:
1176  for (long i=0; i<nElems; i++)
1177  vol += this->Elems[i]->give_volume();
1178  break;
1179  default: _errorr( "Unknown mesh type");
1180  }
1181 
1182  ((Mesh*)this)->volume = vol;
1183  }
1184 
1185  return volume;
1186 }
1187 
1188 
1191 {
1192  switch (this-> mtA) {
1193  case MT_REGULAR: return this->give_total_volume() / nElems; break;
1194  case MT_GENERAL: return 0.0; break;
1195  default: _errorr( "Unknown mesh type");
1196  }
1197 
1198  return 0.0;
1199 }
1200 
1201 // ///
1202 // void Mesh :: average_fields (bool displc_flag, bool strain_flag, bool stress_flag, int lc, int nlc)
1203 // {
1204 // if (displc == NULL) { displc = new double*[nLC]; memset (displc, 0, nLC*sizeof(double*)); }
1205 // if (strain == NULL) { strain = new double*[nLC]; memset (strain, 0, nLC*sizeof(double*)); }
1206 // if (stress == NULL) { stress = new double*[nLC]; memset (stress, 0, nLC*sizeof(double*)); }
1207 //
1208 // double vol;
1209 // int ndisplc = P[0]->give_VECT_RANGE();
1210 // int nstrain = P[0]->give_VM_TENS_RANGE();
1211 // int nstress = P[0]->give_VM_TENS_RANGE();
1212 //
1213 // for (int i=lc; i<lc+nlc; i++) {
1214 // if (displc_flag && elem_displc_rslt_flag[i] == false) _errorr2("displc for lc %ld is not computed", i+1);
1215 // if (strain_flag && elem_strain_rslt_flag[i] == false) _errorr2("strain for lc %ld is not computed", i+1);
1216 // if (stress_flag && elem_stress_rslt_flag[i] == false) _errorr2("stress for lc %ld is not computed", i+1);
1217 //
1218 // if (displc_flag && this->displc[i] == NULL) displc[i] = new double[ndisplc];
1219 // if (strain_flag && this->strain[i] == NULL) strain[i] = new double[nstrain];
1220 // if (stress_flag && this->stress[i] == NULL) stress[i] = new double[nstress];
1221 //
1222 // if (displc_flag) memset (displc[i], 0, ndisplc * sizeof(double));
1223 // if (strain_flag) memset (strain[i], 0, nstrain * sizeof(double));
1224 // if (stress_flag) memset (stress[i], 0, nstress * sizeof(double));
1225 //
1226 // for (long j=0; j<this->nElems; j++) {
1227 // vol = this->Elems[j]->give_volume();
1228 //
1229 // if (displc_flag) AddVectorMultipledBy (vol, this->Elems[j]->displc[i], displc[i], ndisplc);
1230 // if (strain_flag) AddVectorMultipledBy (vol, this->Elems[j]->strain[i], strain[i], nstrain);
1231 // if (stress_flag) AddVectorMultipledBy (vol, this->Elems[j]->stress[i], stress[i], nstress);
1232 // }
1233 // }
1234 // }
1235 
1236 
1238 double Mesh :: give_homog_energy (int pid, int lc)
1239 {
1240  const Problem *p = dynamic_cast <const Problem*>(P[pid]);
1241  if (p == NULL) errol;
1242 
1243  const double *hstrain = p->give_matrix()->give_globHomog_Strain(lc);
1244  const double *hstress = p->give_matrix()->give_globHomog_Stress(lc);
1245 
1246 
1247  double E;
1248  bool twodim = p->give_twodim();
1249 
1250  if (this->md == p->give_dimension()) {
1251  if (twodim) E = MatrixOperations::giveTTproduct_1is2x2to3and2x2to3_SS (hstress, hstrain);
1252  else errol;
1253  }
1254  // mesh is 2d => planestrain is supposed
1255  else if ((this->coll == 3 && this->P[pid]->give_dimension() == 3)) {
1256  errol;
1257  //double strain2d[3], stress2d[3];
1258  //copy3Dto2Dtensors_FEEPreduced (hstrain, strain2d);
1259  //copy3Dto2Dtensors_FEEPreduced (hstress, stress2d);
1260  //
1261  //E = give_VectorVectorProduct (strain2d, stress2d, 3);
1262  }
1263  else errol;
1264 
1265  return E * this->give_total_volume();
1266 }
1267 
1269 double Mesh :: give_total_energy (int pid, int lc)
1270 {
1271  if (el_strn_rf[pid][lc] == false || el_strs_rf[pid][lc] == false)
1272  _errorr2("strain and stress for lc %ld is not computed", lc+1);
1273 
1274  double E = 0.0;
1275 
1276  for (long i=0; i<nElems; i++)
1277  E += Elems[i]->give_energy(pid, lc);
1278 
1279  return E;
1280 }
1281 
1282 
1284 double Mesh :: give_error (int pid1, int pid2, int lc)
1285 {
1286  //double e2eA,e2eM, e2o;
1287  double strain11[3], stress11[3];
1288  double strain22[3], stress22[3];
1289 
1290  double vol, Eei,Eei2, Ee, Eai, Ea, Err_i;
1291  Ee = Ea = 0.0;
1292 
1293  for (long i=0; i<this->nElems; i++) {
1294  // e2eA = thisAS->Elems[i]->energy[lc];
1295  // e2eM = thisMM->Elems[i]->energy[lc];
1296 
1297 
1298  vol = this->Elems[i]->give_volume();
1299 
1300  this->Elems[i]->give_strain(strain11, pid1,lc);
1301  this->Elems[i]->give_strain(strain22, pid2,lc);
1302 
1303  this->Elems[i]->give_stress(stress11, pid1,lc);
1304  this->Elems[i]->give_stress(stress22, pid2,lc);
1305 
1306  // DEBUG
1307  // // stressM a stressA by mel byt stejny jako stresMM a stressAS
1308  // double stressM[3], stressA[3];
1309  // MatrixOperations::giveTVproduct_3is3x3to5and3(stressM, C, strainMM);
1310  // MatrixOperations::giveTVproduct_3is3x3to5and3(stressA, C, strainAS);
1311  // DEBUG
1312 
1313  SubtractVector(strain22, strain11, 3);
1314  SubtractVector(stress22, stress11, 3);
1315 
1316  // Energy error
1317  Eei = vol * give_VectorVectorProduct(strain11, stress11, 3);
1318  Ee += Eei;
1319 
1320  // Energy whole
1321  Eai = vol * give_VectorVectorProduct(strain22, stress22, 3);
1322  Ea += Eai;
1323 
1324  //
1325  Err_i = 100 * sqrt(Eei / Eai);
1326  this->Elems[i]->save_error(Err_i, 0, lc);
1327 
1328 
1329  // DEBUG
1330  if (Eai < 0.0) errol;
1331  if (Eei/Eai < -1.0e-2) _errorr2("Eei = %e < 0.0", Eei/Eai);
1332 
1333  double C[5];
1334  this->Elems[i]->giveReducedStiffMatrix(C, pid1);
1335  Eei2 = vol * MatrixOperations :: giveVTVproduct_1is3and3x3to5and3(C, strain11);
1336  if (Eei2 < 0.0) errol;
1337 
1338  //if (abs((Eei2-Eei)/Eei) > 0.0001) {
1339  // _warningg2("Eei = %e < 0.0", Eei);
1340  // _warningg2("Eei2 = %e < 0.0", Eei2);
1341  // _warningg2("Eai = %e < 0.0", Eai);
1342  // //errol;
1343  //}
1344 
1345  // DEBUG
1346  }
1347 
1348  return 100 * sqrt(Ee / Ea);
1349 }
1350 
1351 
1352 
1353 } // end of namespace mumech
1354 
1355 /*end of file*/
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1130
XMLText * NewText(const char *text)
Create a new Text associated with this Document.
Definition: tinyxml2.cpp:1573
double give_curvature(double x, double a, double b)
MatrixRecord * give_matrix(void) const
Definition: problem.h:509
void print_geometry_file_vtk(const char *rsltFileName, int pid, int lc, int nLC)
Print output file with mesh geometry with results to vtk file.
Definition: mesh.cpp:956
Class eshelbySoluUniformField.
void generate_regular_mesh(const double *p1, const double *p2, const long *n)
Generate regular mesh geometry of rectangular cuboid shape compound of rectangular cuboid shape eleme...
Definition: mesh.cpp:260
void shift_id(long snn, long sne)
Definition: mesh.cpp:246
int give_dimension(void) const
Definition: problem.h:86
double giveTTproduct_1is2x2to3and2x2to3_SS(const double *T1, const double *T2)
Function gives scalar left-right product of tensor and tensor.
file of various types and symbolic constant definitions
const double * give_globHomog_Stress(int lc)
Definition: matrix.cpp:250
const double * give_globHomog_Strain(int lc)
Definition: matrix.cpp:239
void generate_regularSphereMesh_2d(int n, const double *a)
Function generates uniform mesh on an unit circle.
Definition: mesh.cpp:767
void allocate_fields(int pid)
Definition: mnode.cpp:68
long nsegs[3]
Definition: mesh.h:77
bool FP_skip_line(FILE *stream, int n)
move file descriptor to the start of the n-th new line //[former read_line]
Definition: librw.cpp:178
double volume
Volume/Area.
Definition: mesh.h:79
void local2global(const double *origin, const double *TInv)
Local to global transformation of all nodes.
Definition: mesh.cpp:212
void set_coll(int val)
Definition: mesh.cpp:166
Problem description.
Definition: problem.h:154
void print_values_Scalar(char *auxs, const double *values, long len, int precision)
len = pocet scalar cisel
Definition: vtk.cpp:175
double *** strain
computed fields - strain in TVRN_THEORETICAL_FEEP notation
Definition: melement.h:60
General functions.
void XP_check_expected_attribute(const XMLNode *xelem, const char *name, const char *value)
Definition: tixy2.cpp:134
bool ** no_strn_rf
Definition: mesh.h:95
long * nodes
Element nodes.
Definition: melement.h:49
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:603
#define SP_scan_expected_word_exit(_1, _2, _3, _4)
Definition: librw.h:223
Namespace MatrixOperations.
int check_lc_nlc(int lc, int nlc) const
Definition: problem.h:539
Input / output function.
const XMLElement * XP_give_unique_expected_elem(const XMLNode *xelem, const char *name, bool uniq)
Definition: tixy2.cpp:125
Class mNode contains and handles all mesh node data.
Definition: mnode.h:43
XMLDocument * tix_doc(void)
Definition: tixy2.h:144
Mesh(long i, const Problems *p)
Constructor.
Definition: mesh.cpp:49
#define PI
Definition: macros.h:71
void generate_regularSphereMesh_3d(int n, const double *a)
Function generates uniform mesh on an unit sphere.
Definition: mesh.cpp:808
Class Mesh.
#define SP_scan_expected_number_exit(_1, _2, _3)
Definition: librw.h:249
XMLNode * tixnod(void)
Definition: tixy2.h:141
void print_values_Tensor(char *auxs, const double *values, bool twodim, int precision)
dim == dimenze vstupnich dat - 2d ano nebo ne; values musi byt v notaci STRN_THEORETICAL_FEEP ...
Definition: vtk.cpp:197
long nNodes
Number of nodes.
Definition: mesh.h:83
void CopyVector(const double *src, double *dest, long n)
Function copy given number of components from vector, &#39;a&#39; to vector &#39;b&#39;.
double giveVTVproduct_1is3and3x3to5and3(const double *T, const double *vect)
Function gives scalar left-right product of tensor and vector - &#39;result = vect^T * T * vect&#39;...
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:671
virtual int give_nLC(void) const =0
Give number of load cases, e.i. number of load cases, i.e. number of Remote_strain fields...
long SP_scan_word(const char *&src, char *dest)
... word; return value is length of the word
Definition: librw.cpp:647
XMLElement * tixel(void)
Definition: tixy2.h:142
The element is a container class.
Definition: tinyxml2.h:1116
void open(Stream_type t, const char *rw, const char *&fn, XMLNode *node=NULL)
*** SET ***
Definition: tixy2.h:75
#define SP_scan_expected_word2_exit(_1, _2, _3, _4, _5)
Definition: librw.h:224
Class mElement, mesh element.
double *** displc
computed fields - displacement
Definition: melement.h:59
void beRotatedBy2d(const double *r)
Receiver will be rotated by 2d matrix &#39;rot&#39;. this = rot . this.
Definition: arrays.cpp:82
void give_stress(double *stress, int pid, int lc) const
Definition: melement.cpp:262
void beRotatedBy(const double *r)
Receiver will be rotated by matrix &#39;rot&#39;. this = rot . this.
Definition: arrays.cpp:72
mNode ** Nodes
1d array of pointers to Node.
Definition: mesh.h:84
PFCmode
Algorithm type of a point fields calculation.
Definition: types.h:97
void AddScalarToVector(long s, long *v, long n)
Function add given number of components from vector &#39;a&#39; to vector &#39;b&#39;.
bool is_unset(void)
Returns true, if the receiver is unset, only constructor was called.
Definition: mesh.cpp:187
#define errol
Definition: gelib.h:151
void set_type(long t)
Definition: melement.cpp:101
void give_strain(double *strain, int pid, int lc) const
Definition: melement.cpp:246
Notation used in the Brdecko&#39;s book or Jan Zeman&#39;s PhD thesis (generally used CTU&#39;s notation)...
Definition: types.h:140
#define _errorr2(_1, _2)
Definition: gelib.h:154
int np
number of pointers to problems
Definition: mesh.h:58
FILE * file(void)
*** GET ***
Definition: tixy2.h:140
long region
-2 - not set, -1 - matrix, <0;nIncl) id of inclusion
Definition: melement.h:55
bool ST_scan_number(Stream *src, int &dest)
*** *** *** *** TINYXML FCE *** *** *** ***
Definition: tixy2.cpp:36
MeshTypeRead
Type of mesh.
Definition: mesh.cpp:352
VTKrange
Definition: tixy2.h:29
void scan_DATA_field_head(Stream *stream, Stream *strm, const char *str, char type, int nexc, char format, const char *name)
scan_DATA_field_head
Definition: vtk.cpp:241
double *** stress
computed fields - stress in TVRN_THEORETICAL_FEEP notation
Definition: melement.h:61
void print_VTK_FINISH(Stream *stream)
Definition: vtk.cpp:224
int nLC
number of load cases
Definition: mesh.h:92
virtual ~Mesh()
Destructor.
Definition: mesh.cpp:124
PoinT coords
coordinates
Definition: mnode.h:49
void print_VTK_head(FILE *stream, const char *type)
Definition: vtk.cpp:63
int md
mesh dimension
Definition: mesh.h:70
bool ** el_strs_rf
Definition: mesh.h:100
void compute_node_fields(char flag, bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nLC, PFCmode pfcMode)
Definition: mesh.cpp:1111
void read_geometry_file_vtk(const char *vtkMeshFile, int pid, int lc, bool add)
Read input file with mesh geometry from vtk file.
Definition: mesh.cpp:355
long nElems
Number of elements.
Definition: mesh.h:85
double give_homog_energy(int lc, int pid=0)
Definition: mesh.cpp:1238
int npa
number of allocated pointers
Definition: mesh.h:57
void copy_to(double *dest) const
Definition: arrays.h:77
bool SP_scan_number(const char *&src, int &dest)
... number of type int/long/double
Definition: librw.cpp:714
void print_auxs(bool lgc, Stream *stream, XMLElement *da, const char *auxs)
Definition: vtk.cpp:214
#define _STRCMP
Definition: macros.h:57
XMLNode is a base class for every object that is in the XML Document Object Model (DOM)...
Definition: tinyxml2.h:579
double give_error(int pid1, int pid2, int lc)
Definition: mesh.cpp:1284
MeshType mtA
type of mesh, structured grid or unstructured
Definition: mesh.h:72
double point1[3]
Definition: mesh.h:74
void SubtractVector(const double *a, double *b, long n)
Function subtracts given number of components vector &#39;a&#39; from vector &#39;b&#39;; b -= a. ...
const char * Value() const
The meaning of &#39;value&#39; changes for the specific type.
Definition: tinyxml2.h:647
bool relink_downF(void)
Definition: tixy2.h:155
const char * Attribute(const char *name, const char *value=0) const
Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists.
Definition: tinyxml2.cpp:1226
long id
identification number
Definition: melement.h:45
bool ** no_strs_rf
Definition: mesh.h:96
double *** strain
computed fields - strain
Definition: mnode.h:52
void compute_element_fields(char flag, bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nLC, PFCmode pfcMode)
predpokladame trojuhelnikove nebo tetrahedron prvky, tj. na elementu budeme drzet jednu hodnotu ...
Definition: mesh.cpp:1138
bool scan_xyz(FILE *stream)
Definition: arrays.h:72
bool ** no_dspl_rf
Definition: mesh.h:94
const char * GetText() const
Convenience function for easy access to the text inside an element.
Definition: tinyxml2.cpp:1239
void set_and_alloc_nElems(long ne)
Set nElems and allocate array Elems.
Definition: mesh.cpp:236
bool equal_dimensions(int pid) const
Returns true when mesh and problem dimensions are same.
Definition: mesh.cpp:180
void set_node_rslt_flags(bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nLC)
Definition: mesh.cpp:1078
XMLError QueryLongAttribute(const char *name, long *value) const
Given an attribute name, QueryIntAttribute() returns XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the co...
Definition: tinyxml2.h:1212
void set_and_alloc_nNodes(long nn)
Set nNodes and allocate array Nodes.
Definition: mesh.cpp:227
bool ** el_dspl_rf
pid x nlc
Definition: mesh.h:98
int coll
Definition: mesh.h:68
void print_VTK_init_cell_data(Stream *stream, long n)
Definition: vtk.cpp:113
double give_volume(void)
Definition: melement.cpp:160
I/O VTK functions.
void print_VTK_init_point_data(Stream *stream, long n)
Definition: vtk.cpp:105
double *** displc
computed fields - displacement
Definition: mnode.h:51
#define _errorr(_1)
Definition: gelib.h:160
Class mNode, mesh node.
void giveReducedStiffMatrix(double *C, int pid) const
Definition: melement.cpp:234
int file_type_s2e(const char *s)
Definition: mesh.cpp:341
void print_VTK_START(Stream *stream, const char *filename)
Print head of vtk file.
Definition: vtk.cpp:41
double delta[3]
Definition: mesh.h:76
void close(void)
Definition: tixy2.h:113
#define CASE
Definition: macros.h:56
XMLElement * print_VTK_nodes_head(Stream *stream, long n)
Definition: vtk.cpp:82
int give_twodim(void) const
Definition: problem.h:84
bool ** Allocate1Dbp(long d1)
Function allocates (&#39;new&#39; command) a 1d array of bool* pointers set to NULL.
bool relink_next(void)
Definition: tixy2.h:158
double *** stress
computed fields - stress
Definition: mnode.h:53
long give_type(void) const
Definition: melement.h:84
void DeleteArray2D(bool **array, long d1)
Function deletes a 2D &#39;bool&#39; array of dimension d1 x ??, allocated by new.
bool * Allocate1Dbz(long d1)
Function allocates (&#39;new&#39; command) a 1d array of bool set to zero.
const char * XP_giveDAtext(const XMLNode *xelem, int n, bool last, const char *format, const char *type, const char *name, int *noc)
Definition: tixy2.cpp:145
void DeleteChild(XMLNode *node)
Delete a child of this node.
Definition: tinyxml2.cpp:651
#define _errorr1(_1)
Definition: gelib.h:153
void set_elem_rslt_flags(bool displc_flag, bool strain_flag, bool stress_flag, int pid, int lc, int nLC)
Definition: mesh.cpp:1094
const Problems ** P
set of pointers to solved problems
Definition: mesh.h:59
bool isFile(void)
Definition: tixy2.h:151
bool relink_up(void)
Definition: tixy2.h:157
void save_error(double val, int pid, int lc)
Definition: melement.cpp:225
#define FP_scan_expected_word_exit(_1, _2, _3, _4)
Definition: librw.h:137
void print_values_Vector(char *auxs, const double *values, bool twodim, int precision)
dim == dimenze vstupnich dat - 2d ano nebo ne
Definition: vtk.cpp:185
double give_total_energy(int pid, int lc)
Definition: mesh.cpp:1269
bool geom_is_readed(void)
Definition: mesh.h:126
Elem3D * add(const Elem3D *p)
Definition: arrays.h:61
Class Mesh contains and handles all mesh data.
Definition: mesh.h:52
bool ST_scan_array(Stream *src, int n, int *dest)
scan/copy array of numbers from src to dest, src pointer is shifted over the field ...
Definition: tixy2.cpp:55
int FP_scan_word(FILE *src, char *dest)
... word; return value is length of the word
Definition: librw.cpp:455
double give_VectorVectorProduct(const double *v1, const double *v2, long n)
Operations with 1d arrays of various length.
bool SP_skip_word(const char *&src, int n)
... word and space before
Definition: librw.cpp:591
int add_problem(const Problems *p)
Definition: mesh.cpp:148
long nnodes
Number of nodes at elements.
Definition: melement.h:48
long giveFieldsOfPoint(double **displc, double **strain, double **stress, const double *coords, char ptFlag, int rs, int nrs, PFCmode pfcMode=PFCM_OPTIMIZED, long reqIncl=-3, STRNotation tn=STRN_THEORETICAL_ROW) const
Function gives the analytical solution of the perturbation or total fields (displacements, strains and stresses) of a point for given set of remote strains.
Definition: problem.cpp:1706
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:611
double point2[3]
Definition: mesh.h:75
mElement ** Elems
1d array of pointers to Element.
Definition: mesh.h:86
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:595
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:723
double give_regular_element_volume(void) const
Definition: mesh.cpp:1190
void scale(const double *s)
Scale all nodes coordinates by vector s.
Definition: mesh.cpp:199
Class Problem.
Class mElement contains and handles all mesh element data.
Definition: melement.h:42
double give_total_volume(void) const
Definition: mesh.cpp:1165
virtual bool is_converted_to_equivalent(void) const =0
Give type of ...
XMLElement * print_VTK_data_head(Stream *stream, const char *name, char type, char format, int slen)
Definition: vtk.cpp:125
void allocate_fields(int pid)
Definition: melement.cpp:150
void e(int i)
bool ** el_strn_rf
Definition: mesh.h:99