MEER  0.1
 Vše Třídy Prostory jmen Soubory Funkce Proměnné Výčty Hodnoty výčtu Definice maker
meer.cpp
Zobrazit dokumentaci tohoto souboru.
1 #include "meer.h"
2 
3 #ifdef DEVEL
4 #include "arrays.h"
5 #include "gpa.h"
6 #else
7 #include "arrays.h"
8 #include "gpa.h"
9 #endif
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 
16 namespace meerspace {
17 
20 {
21  // private
24 
25  // protected
27  h_max_ratio = 2.0; // max zvetsit na X-nasobek
28  h_min_ratio = 0.25; // max zmensit na X-nasobek
30 
31  normal_at_nodes = false;
32 
33  nREGIONs = 0; REGIONs = NULL;
34  nNODEs = 0; NODEs = NULL;
35  nELEMs = 0; ELEMs = NULL;
36 }
37 
40 {
41  // private
42  long i, j;
44  for (i=0; i<nREGIONs; i++) {
45  for (j=0; j<nNODEs; j++)
46  delete refined_node_values_1[i][j];
47 
48  delete [] refined_node_values_1[i];
49  }
50  delete [] refined_node_values_1;
51  }
52 
54  for (i=0; i<nREGIONs; i++) {
55  for (j=0; j<nNODEs; j++)
56  delete refined_node_values_2[i][j];
57 
58  delete [] refined_node_values_2[i];
59  }
60  delete [] refined_node_values_2;
61  }
62 
63  // protected
64  for (i=0; i<nNODEs; i++) {
65  if (NODEs[i].normal == NULL)
66  errol;
67  for (j=0; j<nREGIONs; j++)
68  delete NODEs[i].normal[j];
69  }
70 
71  delete [] REGIONs;
72  delete [] NODEs;
73  delete [] ELEMs;
74 }
75 
76 
78 void MEER :: set_alloc_REGIONs (long n) { nREGIONs = n; REGIONs = new REGION [nREGIONs]; for (long i=0; i<nREGIONs; i++) REGIONs[i].id = i; }
79 void MEER :: set_alloc_NODEs (long n) { nNODEs = n; NODEs = new NODE [nNODEs]; for (long i=0; i<nNODEs; i++) NODEs[i].id = i; }
80 void MEER :: set_alloc_ELEMs (long n) { nELEMs = n; ELEMs = new ELEMENT[nELEMs]; for (long i=0; i<nELEMs; i++) ELEMs[i].id = i; }
81 
82 
83 //* main function
84 double MEER :: solve (double rerror)
85 {
86  // boundary nodes
87  this->set_boundary_nodes();
88 
89  //
90  switch (enorm) {
93  default: _errorr ("Unknown enorm");
94  }
95 
96  // nodal recovery of values - z IP interpoluje do uzlu slozky zvolene veliciny => vysledkem je vylepsena/recovered velicina v uzlech
98 
99  // error computation
100  this->MEER_error_estimatior ();
101 
102  // mesh refinement
103  return this->MEER_mesh_refinement (rerror);
104 }
105 
108 {
109  ;
110 }
111 
114 {
115  long j, k, l, regid, nip, nvalcomps, nno;
116  long *nodes;
117  double w, dV, V;
118  long elem;
119  Dvctr n(4), IPvalsR_1, IPvalsR_2, IPvalsF_1, IPvalsF_2;
120  GPA<const Dvctr> recovered_nodal_values_1;
121  GPA<const Dvctr> recovered_nodal_values_2;
122 
125 
127  for (elem=0; elem<nELEMs; elem++) {
128  nno = ELEMs[elem].nnodes;
129  nodes = ELEMs[elem].nodes;
130  regid = ELEMs[elem].regid;
131  nvalcomps = REGIONs[regid].nvals;
132 
133  nip = this->give_number_of_IPs2(elem);
134 
135  if (nno == 3 && nip < 3) _errorr("low number of int points");
136  if (nno == 4 && nip < 4) _errorr("low number of int points");
137 
138  // assemble recovered/refined values at element nodes
139  if (valtype_1) {
140  recovered_nodal_values_1.resize_zero();
141  for (j=0; j<nno; j++)
142  recovered_nodal_values_1.add(refined_node_values_1[regid][nodes[j]]);
143  }
144  if (valtype_2) {
145  recovered_nodal_values_2.resize_zero();
146  for (j=0; j<nno; j++)
147  recovered_nodal_values_2.add(refined_node_values_2[regid][nodes[j]]);
148  }
149 
150  IPvalsR_1.resize_ignore_vals(nvalcomps);
151  IPvalsR_2.resize_ignore_vals(nvalcomps);
152 
153  // element volume reduced
154  V = this->give_element_area(elem) * this->give_element_thickness_reduced(elem);
155 
156  // error estimation at element - numericky, tj. smyce pres IPs
157  for (j=0; j<nip; j++) {
158  // IPvalsR - Refined values - ziskaji se interpolaci z uzlu do IP
159  w = this->eval_interpol_fces_at_IPs2 (elem, j, n.give_ptr2val());
160 
161  if (valtype_1) {
162  IPvalsR_1.zero();
163  for (k=0; k<nvalcomps; k++)
164  for (l=0; l<nno; l++)
165  IPvalsR_1[k] += n[l] * recovered_nodal_values_1[l][0][k];
166  }
167  if (valtype_2) {
168  IPvalsR_2.zero();
169  for (k=0; k<nvalcomps; k++)
170  for (l=0; l<nno; l++)
171  IPvalsR_2[k] += n[l] * recovered_nodal_values_2[l][0][k];
172  }
173 
174  // IPvalsF - FEM values - ziskane z FEM vypoctu v IP
175  if (valtype_1) IPvalsF_1.assign_array(this->give_IPs2_values(elem, j, valtype_1), nvalcomps);
176  if (valtype_2) IPvalsF_2.assign_array(this->give_IPs2_values(elem, j, valtype_2), nvalcomps);
177 
178  // error = IPvalsR - IPvalsF
179  if (valtype_1) IPvalsR_1.sbt(IPvalsF_1);
180  if (valtype_2) IPvalsR_2.sbt(IPvalsF_2);
181 
182  dV = w * V;
183  //dV = w * this->give_element_volume(elem);
184 
185  switch (enorm) {
187  e2i[elem] += dV * IPvalsR_1.give_dotproduct(IPvalsR_2);
188  u2i[elem] += dV * IPvalsF_1.give_dotproduct(IPvalsF_2);
189  break;
191  e2i[elem] += dV * IPvalsR_1.give_dotproduct(IPvalsR_1);
192  u2i[elem] += dV * IPvalsF_1.give_dotproduct(IPvalsF_1);
193  break;
194  default: _errorr ("Unsupported enorm");
195  }
196 
197  if (valtype_1) IPvalsF_1.free();
198  if (valtype_2) IPvalsF_2.free();
199  }
200  }
201 }
202 
204 double MEER :: MEER_mesh_refinement (double rerror)
205 {
206  // zaporna energie
207  if (1) {
208  long i,j,k,n;
209  long nsuperelems, superelems[64];
210  double sum;
211 
212  for (i=0; i<nELEMs; i++) {
213  if (e2i[i] >= 0.0) continue;
214  sum = 0.0;
215  n = 0;
216  for (j=0; j<ELEMs[i].nnodes; j++) {
217  this->give_superelems_to_node(NODEs[ELEMs[i].nodes[j]].id, nsuperelems, superelems);
218  for (k=0; k<nsuperelems; k++) {
219  if (e2i[superelems[k]] >= 0.0) {
220  sum += e2i[superelems[k]];
221  n++;
222  }
223  }
224  }
225  e2i[i] = sum / n;
226  }
227  }
228 
229  double e2 = e2i.give_sum();
230  double u2 = u2i.give_sum();
231 
232  double pe = sqrt( e2 / ( e2 + u2 ) );
233 
234  //if (true || pe > rerror) {
235  long i;
236  double uaver, em, coeff, ksi;
237 
238  // em = limit error at element
239  coeff = 1.0; // nevim proc to tady borek ma, ma tam 2.0
240  em = coeff * rerror * sqrt( ( u2 + e2 ) / nELEMs );
241  uaver = sqrt( ( u2 + e2 ) / nELEMs );
242 
243  //hnewi_node.resize_ignore_vals(nNODEs); hnewi_node.zero();
246 
249 
250  for (i=0; i<nELEMs; i++) {
251  // percentual error per element
252  errori_loc [i] = sqrt( e2i[i] / ( u2i[i] + e2i[i] ) ) * 100;
253  errori_glob[i] = sqrt( e2i[i] ) / uaver * 100;
254 
255  ksi = sqrt(e2i[i]) / em;
256 
257  //
258  if ( ksi < 1.0/h_max_ratio ) ksi = 1.0/h_max_ratio; // prvek se zvetsi maximalne h_max krat
259  if ( ksi > 1.0/h_min_ratio ) ksi = 1.0/h_min_ratio; // prvek se zmensi maximalne h_min krat
260 
261  h_old[i] = this->give_element_characteristic_size(i); // stara char. velikost prvku
262  // tady bych mel zkontrolovat stupen aproximace, pokud to neni 1, tak se vzorecek zmeni na hnew = hold / pow(ksi, 1.0 / ord);
263  h_new[i] = h_old[i] / ksi;
264  }
265 
266  // zatim docasne, pro risovo hezky obrazek
267  ei_aver.resize_ignore_vals(nELEMs);
268  for (i=0; i<nELEMs; i++) {
269  ei_aver[i] = e2i[i] / this->give_element_area(i) / this->give_element_thickness(i);
270  }
271 
272  return pe;
273 }
274 
275 // ******************************************************************************************
276 // - SPR_nodal_recovery == metoda, ktera z IP interpoluje do uzlu slozky zvolene veliciny
277 // => vysledkem je vylepsena/recovered velicina v uzlech
278 // - do uzlu se interpoluje pomoci patche=zaplaty tvorene nekolika elementu k uzle prilehajich
279 //
280 // bp_appli == basic patch applicability
281 // =====================================
282 // - basic patch je zaplata z elementu, ktere uzel obsahuji (a jsou v danem regionu)
283 // - bp_appli nabyva hodnot:
284 // 0 - out of region == patch je nulovy - vylepsena velicina v uzlu se NEPOCITA
285 // 1 - directly recovered == patch je dostatecny - vylepsena velicina v uzlu se pocita ze zakladni patche
286 // 2 - in-directly recovered == patch je maly - vylepsena velicina v uzlu se pocita nejak jinak, treba z patche sousedniho uzlu s bpa==1
287 // x - uz vic cisel nepridavej, pocita se s tim v kodu
288 // - bp_elems - pole ID elementu patrici do bp
289 //
290 // A) predpokladam, ze kazdy 2 lezi aspon v jedne patchi 1, pak se pri vypoctu 1 vycisli hodnota i na 2 [AKTUALNI RESENI]
291 // 2 muze patrit do vice patchi 1
292 // a) muzu je vzit vsechny a zprumerovat [AKTUALNI RESENI}
293 // b) muzu vzit 1, v ktere lezi vsechny superelems pro 2
294 // - toto je asi presnejsi, ale ja na to zatim prdim, celkova nepresnost vypoctu je tak velka ze se mi s tim nechce delat
295 // ale kdyz bude cas tak to udelam
296 // B) pro kazdy 2 vezmu superelemns plus jeste elementy, ktere se hranou dotykaji superelems
297 // to by melo stacit pro dostatecnej pocet nsp
298 // C) oofem ma jeste variantu metody A), kdy vsechny boundary uzly jsou 2 a stavaji se 1 jen kdyz se znich ma pocitat jina 2
299 // to uz mi prijde zbytecne slozity
300 // Qvadraticke prvky
301 // uzly co nejsou ve vertexech (jsou na hranach) se pocitaji jen kdyz jsou uvnitr patche, vede to na slozitejsi algoritmus, viz napr. oofem
303 {
304  long i, j, regid;
305  NODE *node;
306 
307  GPA<const NODE> bp_recovered_nodes;
308 
309  // refined_node_values allocation
310  if (valtype_1) {
312  for (i=0; i<nREGIONs; i++) {
314  for(j=0; j<nNODEs; j++) {
315  refined_node_values_1[i][j] = NULL;
316  }
317  }
318  }
319  if (valtype_2) {
321  for (i=0; i<nREGIONs; i++) {
323  for(j=0; j<nNODEs; j++) {
324  refined_node_values_2[i][j] = NULL;
325  }
326  }
327  }
328 
329  Lvctr cavalues_1(nNODEs); // count added values == pocet pricteni hodnot do promenne refined_node_values_1; tou se pak refined_node_values_1 musi podelit
330  Lvctr cavalues_2(nNODEs); // count added values == pocet pricteni hodnot do promenne refined_node_values_1; tou se pak refined_node_values_1 musi podelit
331 
333  for (regid=0; regid<this->nREGIONs; regid++) {
334  // continue pokud v regionu neni zadny prvek
335  if (REGIONs[regid].nvals <= 0)
336  continue;
337 
338  // detekce basic patch a jeji applicability
339  this->MEER_SPR_basic_patch_detection(regid);
340 
341  // loop over nodes with bp_appli[i] == 1 - basic patch recovery
342  for (i=0; i<nNODEs; i++) {
343  node = NODEs+i;
344 
345  this->MEER_SPR_bp_recovered_nodes_detection (node, bp_recovered_nodes);
346 
347  if (bp_recovered_nodes.give_size() == 0) continue;
348 
349  if (valtype_1) this->MEER_SPR_patch_recovered_nodes_compute(regid, bp_recovered_nodes, valtype_1, refined_node_values_1[regid], cavalues_1);
350  if (valtype_2) this->MEER_SPR_patch_recovered_nodes_compute(regid, bp_recovered_nodes, valtype_2, refined_node_values_2[regid], cavalues_2);
351  }
352 
353  // interpolovane hodnoty v uzlech zprumeruje
354  for (i=0; i<nNODEs; i++) {
355  if (NODEs[i].bp_appli) {
356  if (valtype_1 && refined_node_values_1[regid][i] == NULL) _errorr2("values at node %ld not approximated", i+1);
357  if (valtype_2 && refined_node_values_2[regid][i] == NULL) _errorr2("values at node %ld not approximated", i+1);
358 
359  // prumerovani
360  if (valtype_1 && cavalues_1[i] > 1) refined_node_values_1[regid][i]->dvdby(cavalues_1[i]);
361  if (valtype_2 && cavalues_2[i] > 1) refined_node_values_2[regid][i]->dvdby(cavalues_2[i]);
362 
363  }
364  }
365  }
366 }
367 
370 {
371  VectoR v1, v2;
372  ELEMENT *elem;
373 
374  // normaly na elementech
375  for (long i=0; i<nELEMs; i++) {
376  elem = ELEMs+i;
377 
378  // continue if computed already
379  if (elem->normal) continue;
380 
381  // allocate
382  elem->normal = new VectoR;
383 
384  if (elem->nnodes == 3) {
385  v1.beP2P(&NODEs[elem->nodes[1]].coords, &NODEs[elem->nodes[0]].coords); // vector from node[1] to node[0]
386  v2.beP2P(&NODEs[elem->nodes[1]].coords, &NODEs[elem->nodes[2]].coords); // vector from node[1] to node[2]
387 
388  elem->normal->beVectProduct(&v1, &v2);
389  }
390  else if (elem->nnodes == 4) {
391  v1.beP2P(&NODEs[elem->nodes[2]].coords, &NODEs[elem->nodes[0]].coords); // vector from node[2] to node[0]
392  v2.beP2P(&NODEs[elem->nodes[1]].coords, &NODEs[elem->nodes[3]].coords); // vector from node[1] to node[3]
393 
394  elem->normal->beVectProduct(&v1, &v2);
395  }
396  else _errorr("Unsupported number of nodes at element");
397  }
398 }
399 
400 
401 // detekce basic patch a jeji applicability pro kazdy uzel
403 {
404  long i, j, k, ncoeff;
405  long nsp;
406  long nsuperelems, superelems[64];
407  //const FElement *felem;
408  NODE *node;
409  const ELEMENT *patchelem;
410  VectoR *normal;
411 
412  int snode;
413  Dvctr snodes;
414  bool boundarytest;
415 
416  switch (SPR_boundary) {
417  case MEER_SPRbpt_basic: boundarytest = false; break;
418  case MEER_SPRbpt_nobnd: boundarytest = true; break;
419  default: errol;
420  }
421 
422  if (boundarytest)
423  snodes.resize_ignore_vals(nNODEs);
424 
426  ncoeff = this->MEER_SPR_give_number_coefficients((MEER_SPRpatchType)REGIONs[regid].sprtype);
427 
428  //* compute normals at elements
429  if (this->normal_at_nodes == false)
431 
432  // smyce pres uzly a detekce patche
433  for (i=0; i<nNODEs; i++) {
434  node = NODEs+i;
435  nsp = 0; // number sampling/integration points
436  this->give_superelems_to_node(i, nsuperelems, superelems); // elements superior to node[i]
437 
438  // nulovani, alokace
439  node->bp_appli = 0; // vynuluju
440  node->bp_elems.realloc(nsuperelems); // alokuju max velikost == pocet superelems, ale nektery vypadnou anzto nelezi v regionu
441  node->bp_elems.resize_ignore_vals(0); // resize na 0, z predchoziho regionu
442 
443  for (j=0; j<nsuperelems; j++) {
444 
445  if (regid == ELEMs[superelems[j]].regid) {
446  node->bp_elems.add(superelems[j]);
447 
448  nsp += ELEMs[superelems[j]].nIPs1;
449  }
450  }
451 
452  if (nsp) {
453  if (nsp >= ncoeff) node->bp_appli = 1;
454  else node->bp_appli = 2;
455  }
456 
457  // detekce uzlu na hranici/boundary
458  if (boundarytest && nsp) {
459  if (node->bp_elems.give_size() == 1) {
460  int nnodes = (ELEMs+node->bp_elems[0])->nnodes;
461  if (nnodes == 3) node->boundary = 3;
462  else if (nnodes == 4) node->boundary = 2;
463  else errol;
464  }
465  else {
466  snodes.zero();
467 
468  // loop over bp_elems
469  for (j=0; j<node->bp_elems.give_size(); j++) {
470  patchelem = ELEMs+node->bp_elems[j];
471 
472  for (k=0; k<patchelem->nnodes; k++)
473  snodes[patchelem->nodes[k]]++;
474  }
475 
476  snodes[i] = 0;
477 
478  // loop over bp_elems
479  for (j=0; j<node->bp_elems.give_size(); j++) {
480  patchelem = ELEMs+node->bp_elems[j];
481 
482  snode = 0;
483  for (k=0; k<patchelem->nnodes; k++)
484  snode = snode + snodes[patchelem->nodes[k]];
485 
486  if (snode != patchelem->nnodes-1+2) break;
487  }
488 
489  if (j != node->bp_elems.give_size())
490  node->boundary = 1;
491  }
492  }
493  }
494 
495 
496  //
497  for (i=0; i<nNODEs; i++) {
498  node = NODEs+i;
499 
500  // pocitani normaly
501  if (this->normal_at_nodes == false) {
502  if (node->normal == NULL) {
503  node->normal = new VectoR*[nREGIONs];
504  memset(node->normal, 0, nREGIONs*sizeof(VectoR*));
505  }
506 
507  if (node->bp_elems.give_size()) {
508  normal = new VectoR;
509 
510  // loop over bp_elems
511  for (j=0; j<node->bp_elems.give_size(); j++)
512  normal->add(ELEMs[node->bp_elems[j]].normal);
513 
514  node->normal[regid] = normal;
515  }
516  }
517 
518  // pocitani rotation matrix
519  if (node->normal[regid] != NULL) {
520  double limit = 0.001;
521  normal = node->normal[regid];
522  VectoR v1, v2;
523  bool normalize = false;
524 
525  double xa = normal->x < 0.0 ? -normal->x : normal->x;
526  double ya = normal->y < 0.0 ? -normal->y : normal->y;
527  double za = normal->z < 0.0 ? -normal->z : normal->z;
528 
529  // X
530  if (xa >= ya && xa >= za) {
531  if (normal->x == 0.0) _errorr("collapsed normal");
532 
533  // normal == (1,0,0)
534  if (ya/xa < limit && za/xa < limit) {
535  node->rotmat(0,0) = 0; node->rotmat(0,1) = 1; node->rotmat(0,2) = 0;
536  node->rotmat(1,0) = 0; node->rotmat(1,1) = 0; node->rotmat(1,2) = 1;
537  node->rotmat(2,0) = 1; node->rotmat(2,1) = 0; node->rotmat(2,2) = 0;
538  }
539  else {
540  v1.x = 0.0;
541  v1.y = normal->z;
542  v1.z = -normal->y;
543  normalize = true;
544  }
545  }
546  // Y
547  else if (ya >= za && ya >= xa) {
548  if (normal->y == 0.0) _errorr("collapsed normal");
549 
550  // normal == (0,1,0)
551  if (xa/ya < limit && za/ya < limit) {
552  node->rotmat(0,0) = 0; node->rotmat(0,1) = 0; node->rotmat(0,2) = 1;
553  node->rotmat(1,0) = 1; node->rotmat(1,1) = 0; node->rotmat(1,2) = 0;
554  node->rotmat(2,0) = 0; node->rotmat(2,1) = 1; node->rotmat(2,2) = 0;
555  }
556  else {
557  v1.x = -normal->z;
558  v1.y = 0.0;
559  v1.z = normal->x;
560  normalize = true;
561  }
562  }
563  // Z
564  else {
565  if (normal->z == 0.0) _errorr("collapsed normal");
566 
567  // normal == (0,0,1)
568  if (xa/za < limit && ya/za < limit) {
569  delete node->normal[regid];
570  node->normal[regid] = NULL;
571 
572  // docasne, pak to smaz
573  node->rotmat(0,0) = 1; node->rotmat(0,1) = 0; node->rotmat(0,2) = 0;
574  node->rotmat(1,0) = 0; node->rotmat(1,1) = 1; node->rotmat(1,2) = 0;
575  node->rotmat(2,0) = 0; node->rotmat(2,1) = 0; node->rotmat(2,2) = 1;
576  }
577  else {
578  v1.x = normal->y;
579  v1.y = -normal->x;
580  v1.z = 0.0;
581  normalize = true;
582  }
583  }
584 
585  if (normalize) {
586  v2.beVectProduct( normal, &v1 );
587 
588  v1.normalize();
589  v2.normalize();
590  normal->normalize();
591 
592  node->rotmat.copy_row(0,&v1);
593  node->rotmat.copy_row(1,&v2);
594  node->rotmat.copy_row(2,normal);
595  }
596  }
597  } // loop over nodes
598 }
599 
600 
603 {
604  long i, j, elemid;
605  bool supernode = false;
606  bool cornertria = false;
607  const NODE *patchnode;
608 
609  bp_recovered_nodes.resize_zero();
610 
611  // patch nejde vubec sestavit
612  if (node->bp_appli != 1) return;
613 
614  bool boundarytest;
615 
616  switch (SPR_boundary) {
617  case MEER_SPRbpt_basic: boundarytest = false; break;
618  case MEER_SPRbpt_nobnd: boundarytest = true; break;
619  default: errol;
620  }
621 
622  // uzel kolem ktereho je patch vytvorena se bude pocitat vzdy
623  bp_recovered_nodes.add(node);
624 
625  // loop over bp_elems
626  for (i=0; i<node->bp_elems.give_size(); i++) {
627  elemid = node->bp_elems[i];
628 
629  // loop over element nodes
630  for (j=0; j<ELEMs[elemid].nnodes; j++) {
631  patchnode = NODEs+ELEMs[elemid].nodes[j];
632 
633  // bp_appli == 2 - add nodes
634  if (patchnode->bp_appli == 2)
635  bp_recovered_nodes.add_unique(patchnode);
636  // bp_appli == 1
637  else if (boundarytest) {
638  // add node at boundary
639  if (patchnode->boundary) {
640  bp_recovered_nodes.add_unique(patchnode);
641  if (patchnode->boundary == 3) cornertria = true;
642  }
643  // z patchnode se da spocitat tento node
644  else {
645  // pokud je tento node na boundary, tak se vyuzije moznost spocitat se z patchnode
646  if (node->boundary) supernode = true;
647  }
648  }
649  }
650  }
651 
652  if (boundarytest && node->boundary && supernode && !cornertria) {
653  bp_recovered_nodes.resize_zero();
654  }
655 }
656 
657 // na patchi z elementu "bp_elems" se spocitaji koeficienty polynomicke approximace zvolene veliciny
658 void MEER :: MEER_SPR_patch_recovered_nodes_compute (long regid, GPA<const NODE> &bp_recovered_nodes, MEER_IPValues valtype, Dvctr **values, Lvctr &cavalues)
659 {
660  long e, i, j, k, n, elemid;
661  Dvctr *rhs, pol;
662  Dmtrx eqs;
663  const double *IP_values;
664 
665  long sprtype = REGIONs[regid].sprtype;
666  long nvalcomps = REGIONs[regid].nvals;
667  long ncoeff = this->MEER_SPR_give_number_coefficients(sprtype);
668 
669  //* main node
670  const NODE *mnode = bp_recovered_nodes[0];
671 
672  //* rotation
673  const Dmtrx *rotmat = &mnode->rotmat;
674  const PoinT *coords;
675  PoinT mnode_loc_coords, ip_loc_coords, node_loc_coords;
676  bool mnormal = mnode->normal[regid] ? true : false;
677  if (mnormal) {
678  mnode_loc_coords.beRotatedPoint(rotmat, &mnode->coords);
679  }
680 
681 
682  //* eqs[ncoeff,ncoeff] * coeffs = rhs - hledame "nvalcomps" sad koeficientu
683 
684  eqs.resize_ignore_vals(ncoeff, ncoeff);
685  eqs.zero();
686 
687  rhs = new Dvctr[nvalcomps];
688  for (i=0; i<nvalcomps; i++) {
689  rhs[i].resize_ignore_vals(ncoeff);
690  rhs[i].zero();
691  }
692 
693  // loop over patch element
694  for (e=0; e<mnode->bp_elems.give_size(); e++) {
695  elemid = mnode->bp_elems[e];
696 
697  for (i=0; i<ELEMs[elemid].nIPs1; i++) {
698  IP_values = this->give_IPs1_values(elemid, i, valtype);
699 
700  if (mnormal) {
701  ip_loc_coords.beRotatedPoint(rotmat, ELEMs[elemid].IPs1_coords+i);
702  ip_loc_coords.sub(&mnode_loc_coords);
703  coords = &ip_loc_coords;
704  }
705  else
706  coords = ELEMs[elemid].IPs1_coords+i;
707 
708  this->MEER_SPR_give_polynom(sprtype, coords, pol);
709 
710  // compute ip contribution
711  for (j=0; j<ncoeff; j++) {
712  for (k=0; k<nvalcomps; k++)
713  rhs[k][j] += pol[j] * IP_values[k];
714 
715  for (k=0; k<ncoeff; k++)
716  eqs(j,k) += pol[j] * pol[k];
717  }
718  }
719  }
720 
721  Dvctr *coeffs = new Dvctr[nvalcomps];
722 
723  if (! eqs.GaussSolve (coeffs, rhs, nvalcomps))
724  errol;
725 
726  delete [] rhs;
727 
728  // spocitaji se hodnoty approximace v bp_recovered_nodes
729  Dvctr vals(nvalcomps);
730 
731  const NODE *node;
732  for (n=0; n<bp_recovered_nodes.give_size(); n++) {
733  node = bp_recovered_nodes[n];
734 
735  if (mnormal) {
736  if (n) {
737  node_loc_coords.beRotatedPoint(rotmat, &node->coords);
738  node_loc_coords.sub(&mnode_loc_coords);
739  }
740  coords = &node_loc_coords;
741  }
742  else
743  coords = &node->coords;
744 
745  this->MEER_SPR_give_polynom(sprtype, coords, pol);
746 
747  vals.zero();
748 
749  for (i=0; i<nvalcomps; i++)
750  for (j=0; j<ncoeff; j++)
751  vals[i] += pol[j] * coeffs[i][j];
752 
753 
754  // add vals to values
755  if (values[node->id] == NULL) {
756  values[node->id] = new Dvctr(nvalcomps);
757  values[node->id]->zero();
758  cavalues[node->id] = 0;
759  }
760 
761  values[node->id]->add(&vals);
762  cavalues[node->id]++;
763  }
764 
765  delete [] coeffs;
766 }
767 
769 {
770  switch ((MEER_SPRpatchType)sprtype) {
771  case MEER_SPRPT_2d: return 3;
772  default: _errorr("Unknown SPR patch type");
773  }
774  return -1;
775 }
776 
777 void MEER :: MEER_SPR_give_polynom (long sprtype, const PoinT *coords, Dvctr &pol)
778 {
779  switch ((MEER_SPRpatchType)sprtype) {
780  case MEER_SPRPT_2d:
781  pol.resize_ignore_vals(3);
782  pol[0] = 1.0;
783  pol[1] = coords[0].x;
784  pol[2] = coords[0].y;
785  break;
786  default: _errorr("Unknown SPR patch type");
787  }
788 }
789 
790 
792 double MEER :: eval_interpol_fces_at_IPs2 (long elementID, int ipID, double *answer) const
793 {
795  double ncoords[3];
796  double w;
797 
798  edi = this->give_element_EDI (elementID);
799 
800  w = this->give_IPs2_coords_natural (elementID, ipID, ncoords);
801 
803  switch (edi) {
805  w = 2 * w;
806  answer[0] = ncoords[0];
807  answer[1] = ncoords[1];
808  answer[2] = ncoords[2];
809  break;
811  w = 0.25 * w;
812  answer[0] = 0.25 * (1 + ncoords[0]) * (1 + ncoords[1]);
813  answer[1] = 0.25 * (1 - ncoords[0]) * (1 + ncoords[1]);
814  answer[2] = 0.25 * (1 - ncoords[0]) * (1 - ncoords[1]);
815  answer[3] = 0.25 * (1 + ncoords[0]) * (1 - ncoords[1]);
816  break;
818  w = 0.25 * w;
819  answer[0] = 0.25 * (1 - ncoords[0]) * (1 - ncoords[1]);
820  answer[1] = 0.25 * (1 + ncoords[0]) * (1 - ncoords[1]);
821  answer[2] = 0.25 * (1 + ncoords[0]) * (1 + ncoords[1]);
822  answer[3] = 0.25 * (1 - ncoords[0]) * (1 + ncoords[1]);
823  break;
824  default: _errorr ("Unknown edi");
825  }
826 
827  return w;
828 }
829 
832 {
833  MEER_ElemDisplInterpol edi = this->give_element_EDI (elementID);
834  double size = this->give_element_area (elementID);
835 
837  switch (edi) {
838  case MEER_EDI_2d_3n_linear: size = sqrt(2.0 * size); break;
840  case MEER_EDI_2d_4n_bilinear_2: size = sqrt( size); break;
841  default: _errorr ("Unknown edi");
842  }
843 
844  return size;
845 }
846 
847 } // namespace meerspace
#define errol
Definition: obecne.h:142
Dvctr errori_loc
Definition: meer.h:313
2 dimensions; 4 nodes; bilinear interpolation // takto to ma nastavene OOFEM pro ctyruhelniky cisla u...
Definition: meer.h:111
long nIPs1
number of integration points for integration set 1, i.e. integration of stiffness matrix ...
Definition: meer.h:188
int boundary
node at boundary
Definition: meer.h:165
VectoR * beP2P(const PoinT *p1, const PoinT *p2)
Receiver is set to vector from p1 to p2, i.e. 'this = p2 - p1'.
Definition: arrays.h:153
Plošné elementy.
Definition: meer.h:65
MEER_SPRboundaryPatchType SPR_boundary
Použitá strategie vytváření patchí na okraji regionu.
Definition: meer.h:366
long regid
identifikační číslo (ID) regionu (číslováno od nuly) do kterého příslušný element patří...
Definition: meer.h:184
VectoR ** normal
normala k plose v bode; 2d pole [nREGIONs, 1] predpoklad - v ramci jednoho regionu muze byt jen jedna...
Definition: meer.h:158
2 dimensions; 3 nodes; linear interpolation // l1,l2,l3 (0;1) ...
Definition: meer.h:100
long * nodes
pole délky nnodes s identifikačními čísly (číslováno od nuly) uzlů
Definition: meer.h:186
double give_sum(void) const
Definition: arrays.cpp:304
Dvctr *** refined_node_values_1
Pole hodnot.
Definition: meer.h:309
virtual void give_superelems_to_node(long nodeID, long &nsuperelems, long *superelems) const =0
NODES.
GPA - Generic Pointer Array, template class manages 1d array of pointers to objects of type T...
Definition: gpa.h:23
MEER_IPValues valtype_2
Definition: meer.h:304
long nELEMs
počet konečných prvků (elementů) sítě.
Definition: meer.h:379
double MEER_mesh_refinement(double rerror)
rerror == required error
Definition: meer.cpp:204
Dvctr h_old
Definition: meer.h:315
MEER(void)
CONSTRUCTOR.
Definition: meer.cpp:19
void zero(void)
Definition: arrays.h:799
double give_dotproduct(const Dvctr &v)
Definition: arrays.cpp:369
Class GPA.
Dvctr ei_aver
Definition: meer.h:313
long nREGIONs
počet regionů v konstrukci
Definition: meer.h:371
double eval_interpol_fces_at_IPs2(long elementID, int ipid, double *answer) const
evaluate interpolation functions at element at IP with coordinates
Definition: meer.cpp:792
void MEER_SPR_bp_recovered_nodes_detection(const NODE *node, GPA< const NODE > &bp_recovered_nodes)
vytvori seznam uzlu "bp_recovered_nodes", ktere se budou pocitat z dane patche == patche kolem uzlu "...
Definition: meer.cpp:602
T * add(T *val)
add (assign) new pointer to the end; enlarge the receiver if too small
Definition: gpa.h:157
double give_element_characteristic_size(long elementID)
compute characteristic size of element = length of equidistant edge
Definition: meer.cpp:831
void beRotatedPoint(const Dmtrx *rot, const PoinT *point)
Receiver will be point 'point' rotated by matrix 'rot'. this = rot . point.
Definition: arrays.cpp:60
energy norm - error^2 = strain_T * stress
Definition: meer.h:50
PoinT coords
souradnice uzlu == global coordinates
Definition: meer.h:152
void resize_ignore_vals(long r, long c)
print yourself
Definition: arrays.cpp:711
#define _errorr(_1)
Definition: obecne.h:151
void MEER_SPR_compute_normals_at_elements(void)
Funkce spocita normaly na elementech, pokud jsou neinicializovane, tj. pokud nejsou predem spocteny e...
Definition: meer.cpp:369
2 dimensions; 4 nodes; bilinear interpolation // takto to ma nastavene brnensky FEM pro prvek MITC4 c...
Definition: meer.h:122
data spojena s regionem
Definition: meer.h:132
double h_min_ratio
minimalni povolene zmenseni elementu; je vhodne zadat asi 0.5 a mene
Definition: meer.h:365
void set_alloc_REGIONs(long n)
allocate arrays
Definition: meer.cpp:78
long give_size(void) const
Definition: gpa.h:241
void MEER_SPR_patch_recovered_nodes_compute(long regid, GPA< const NODE > &bp_recovered_nodes, MEER_IPValues valtype, Dvctr **values, Lvctr &cavalues)
Definition: meer.cpp:658
void resize_zero(void)
Definition: gpa.h:101
void set_alloc_ELEMs(long n)
Definition: meer.cpp:80
double solve(double req_error)
Funkce solve je hlavní, a jediná, výkonná funkce knihovny MEER.
Definition: meer.cpp:84
void add(const Dvctr &src)
Definition: arrays.cpp:380
Structs Elem3D, PoinT and VectoR; classes Array, Array1d, Xscal, Dscal, Xvctr, Lvctr, Dvctr, Xmtrx, Lmtrx and Dmtrx.
void MEER_error_estimatior(void)
Definition: meer.cpp:113
virtual long give_number_of_IPs2(long elementID) const =0
give number of integration points for integration set 1, i.e. integration of stiffness matrix ...
void MEER_SPR_basic_patch_detection(long regid)
Definition: meer.cpp:402
bool GaussSolve(Dvctr &x, const Dvctr &rhs)
gaussian eliminatio
Definition: arrays.cpp:811
#define _errorr2(_1, _2)
Definition: obecne.h:145
Patch se dělá v každém P1 bodě a interpoluje se navíc do všech P2 bodů na patchi. ...
Definition: meer.h:81
void set_boundary_nodes(void)
Definition: meer.cpp:107
PoinT * IPs1_coords
global coordinates of integration points for integration set 1
Definition: meer.h:189
MEER_IPValues
Hodnoty v integracnich bodech, ktere budou vylepsovany a bude se z nich pocitat chyba.
Definition: meer.h:56
virtual const double * give_IPs2_values(long elementID, int ipID, MEER_IPValues valtype) const =0
give values at integration points of IP set 2 spocte napeti z FEM v IP s coordinatama ...
long nNODEs
počet uzlů sítě konečných prvků v konstrukci
Definition: meer.h:375
data spojena s elementem
Definition: meer.h:179
empty enum
Definition: meer.h:48
void dvdby(double val)
Definition: arrays.cpp:384
Dvctr *** refined_node_values_2
Definition: meer.h:310
Dmtrx rotmat
rotation matrix, bude jen jedna, pri pocitani dalsiho regionu se prepise u normaly to tak nemuze byt...
Definition: meer.h:162
MEER_ErrorNorm enorm
Typ použitého integrálního meřítka chyby.
Definition: meer.h:363
bool normal_at_nodes
normaly v uzlech jsou zname/spoctene
Definition: meer.h:368
virtual const double * give_IPs1_values(long elementID, int ipID, MEER_IPValues valtype) const =0
aby se ty cisla nemusely kopirovat sem tam, tak to mam zatim udelany tak, ze se posila const ukazatel...
void MEER_SPR_give_polynom(long sprtype, const PoinT *coords, Dvctr &pol)
Definition: meer.cpp:777
void zero(void)
Definition: arrays.h:630
void sbt(const Dvctr &src)
Definition: arrays.cpp:382
virtual double give_element_area(long elementID) const =0
give element area => u 1d prvku to ale asi bude delka, tak pak to budu muset predelat ...
virtual MEER_ElemDisplInterpol give_element_EDI(long elementID) const =0
ELEMENTS.
double h_max_ratio
maximalni povolene zvetseni elementu; je vhodne zadat asi 2.0 a vice
Definition: meer.h:364
virtual double give_IPs2_coords_natural(long elementID, int ipID, double *ncoords) const =0
give weight as return value, and natural coordinates of node-th IP
Dvctr * free(void)
Definition: arrays.cpp:283
Dvctr * assign_array(double *array, long s)
Definition: arrays.cpp:262
virtual ~MEER(void)
DESTRUCTOR.
Definition: meer.cpp:39
Dvctr e2i
Definition: meer.h:313
Dvctr h_new
Definition: meer.h:316
virtual double give_element_thickness(long elementID) const =0
give element thickness
Lvctr bp_elems
Definition: meer.h:169
void set_alloc_NODEs(long n)
Definition: meer.cpp:79
L2 norm - error^2 = stress_T * stress.
Definition: meer.h:52
Dvctr errori_glob
Definition: meer.h:313
VectoR * beVectProduct(const VectoR *v1, const VectoR *v2)
vector product v1 x v2 (cross product)
Definition: arrays.h:160
void copy_row(long r, const Dvctr &v)
Definition: arrays.h:802
long nnodes
počet uzlů na elementu
Definition: meer.h:185
void add(long val)
add value to size++ position
Definition: arrays.h:460
a) Patch se dělá v každém P1 bodě který není PB a interpoluje se navíc do všech PB a P2 bodů na patch...
Definition: meer.h:84
long id
identification number
Definition: meer.h:149
long sprtype
Definition: meer.h:138
ELEMENT * ELEMs
pole delky 'nELEMs' struktur ELEMENT, v kterych jsou uchovany informace o prvcich ...
Definition: meer.h:380
Dvctr * resize_ignore_vals(long newsize)
Definition: arrays.h:595
VectoR * normalize(void)
Definition: arrays.h:185
void MEER_SPR_nodal_recovery(void)
SPR nodal recovery.
Definition: meer.cpp:302
Elem3D * add(const Elem3D *p)
Definition: arrays.h:61
void add_unique(T *src)
add new pointer "src" if unique
Definition: gpa.h:191
VectoR * normal
normala (vektor kolmy k plose prvku) delky 2*A (2 x plocha prvku), pro (zborceny) 4uhelnik staci spoc...
Definition: meer.h:192
virtual long give_size(void) const
Definition: arrays.h:387
Dvctr u2i
Definition: meer.h:313
MEER_ElemDisplInterpol
pomoci tohoto enumu se predava nekolik informaci:
Definition: meer.h:91
int bp_appli
Definition: meer.h:168
virtual double give_element_thickness_reduced(long elementID) const =0
give element thickness, !!! reduced, pro shelly to bude vzdy 1, protoze tam jsou integralni veliciny ...
int MEER_SPR_give_number_coefficients(long sprtype)
Definition: meer.cpp:768
MEER_SPRpatchType
Typ spr patche, závisí na typu/geometrii elementů.
Definition: meer.h:63
data spojena s uzlem
Definition: meer.h:147
NODE * NODEs
pole delky 'nNODEs' struktur NODE, v kterych jsou uchovany informace o uzlu
Definition: meer.h:376
Elem3D * sub(const Elem3D *p)
Definition: arrays.h:62
void realloc(long newsize)
reallocate up receiver
Definition: arrays.cpp:97
MEER_IPValues valtype_1
Hodnoty interpolovane do uzlu.
Definition: meer.h:304
Lvctr * resize_ignore_vals(long newsize)
resize, ignore values
Definition: arrays.h:472
REGION * REGIONs
pole delky 'nREGIONs' struktur REGION, v kterych jsou uchovany informace o regionu ...
Definition: meer.h:372