OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
solutionbasedshapefunction.C
Go to the documentation of this file.
1 /*
2  * solutionbasedshapefunction.C
3  *
4  * Created on: May 27, 2013
5  * Author: carl
6  */
7 
9 #include "oofemtxtdatareader.h"
10 #include "activebc.h"
11 #include "activedof.h"
12 #include "inputrecord.h"
13 #include "element.h"
14 #include "node.h"
15 #include "masterdof.h"
16 #include "sparsemtrx.h"
17 #include "gausspoint.h"
18 #include "gaussintegrationrule.h"
19 #include "mathfem.h"
20 #include "fei2dtrlin.h"
21 #include "fei2dtrquad.h"
22 #include "classfactory.h"
23 #include "set.h"
24 #include "util.h"
25 #include "inputrecord.h"
26 #include "engngm.h"
27 #include "spatiallocalizer.h"
28 #include "dynamicinputrecord.h"
29 #include "bodyload.h"
30 #include "boundarycondition.h"
31 //#include "stokesflow.h"
32 //#include "classfactory.h"
33 
34 #include <vector>
35 
36 namespace oofem {
37 template< class T >
38 void logData(T myArray) {
39  for ( int xyz = 1; xyz <= myArray.giveSize(); xyz++ ) {
40  if ( dynamic_cast< IntArray * >(& myArray) ) {
41  printf( "%u ", myArray.at(xyz) );
42  } else {
43  printf( "%f ", myArray.at(xyz) );
44  }
45  }
46 }
47 
48 template< class T >
49 void logDataMsg(const char *c, T myArray) {
50  printf("%s ", c);
51  logData(myArray);
52  printf("\n");
53 }
54 
55 template< class T >
56 void logDataMsg(const char *c, T myArray, const char *c2) {
57  printf("%s ", c);
58  logData(myArray);
59  printf("%s\n", c2);
60 }
61 
63 
65 {
66  isLoaded = false;
67  order = 8;
68  TOL = 1e-5;
69  bigNorm = 0.0;
70 
71  // TODO Auto-generated constructor stub
72 }
73 
75 {
76  // TODO Auto-generated destructor stub
77 }
78 
81 {
82  IRResultType result;
83 
84  // Load problem file
85  this->filename = "";
87  useConstantBase = ( this->filename == "" ) ? true : false;
88 
89  externalSet = -1;
91 
92  // use correction factors to ensure incompressibility
95 
96  dumpSnapshot = false;
98 
99 
100  // Set up master dofs
102  myNode = new Node( 1, this->giveDomain() );
103 
104  for (int i = 1; i <= this->giveDomain()->giveNumberOfSpatialDimensions(); i++) {
105  int DofID = this->domain->giveNextFreeDofID();
106  MasterDof *newDof = new MasterDof( myNode, (DofIDItem) DofID );
107  myNode->appendDof( newDof );
108  }
109 
110  init();
111 
113 }
114 
115 DofManager *
117 {
118  return myNode;
119 }
120 
121 bool
123 {
124  for ( Dof *myDof: *myNode ) {
125  if ( dof == myDof ) {
126  return true;
127  }
128  }
129  return false;
130 }
131 
132 void
134 {
135  Node *n1 = this->giveDomain()->giveNode(1);
136 
137  maxCoord = * n1->giveCoordinates();
138  minCoord = * n1->giveCoordinates();
139 
140  for ( auto &n :this->giveDomain()->giveDofManagers() ) {
141  for ( int j = 1; j <= maxCoord.giveSize(); j++ ) {
142  maxCoord.at(j) = max( n->giveCoordinate(j), maxCoord.at(j) );
143  minCoord.at(j) = min( n->giveCoordinate(j), minCoord.at(j) );
144  }
145  }
146 }
147 
148 void
150 {
151  /*
152  * *Compute c0, cp, cm, Bp, Bm, Ap and Am
153  */
154 
155  double A0p = 0.0, App = 0.0, A0m = 0.0, Amm = 0.0, Bp = 0.0, Bm = 0.0, c0 = 0.0, cp = 0.0, cm = 0.0;
156 
157  EngngModel *model = myMode.myEngngModel;
158  Set *mySet = model->giveDomain(1)->giveSet(externalSet);
159 
160  IntArray BoundaryList = mySet->giveBoundaryList();
161 
162  for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) {
163  int ElementID = BoundaryList(2 * i);
164  int Boundary = BoundaryList(2 * i + 1);
165 
166  Element *thisElement = model->giveDomain(1)->giveElement(ElementID);
167  FEInterpolation *geoInterpolation = thisElement->giveInterpolation();
168  IntArray bnodes, zNodes, pNodes, mNodes;
169  FloatMatrix nodeValues;
170 
171  geoInterpolation->boundaryGiveNodes(bnodes, Boundary);
172 
173  nodeValues.resize( this->dofs.giveSize(), bnodes.giveSize() );
174  nodeValues.zero();
175 
176  // Change to global ID for bnodes and identify the intersection of bnodes and the zero boundary
177  splitBoundaryNodeIDs(myMode, * thisElement, bnodes, pNodes, mNodes, zNodes, nodeValues);
178 
179  std :: unique_ptr< IntegrationRule >iRule(geoInterpolation->giveBoundaryIntegrationRule(order, Boundary));
180 
181  for ( GaussPoint *gp: *iRule ) {
182  const FloatArray &lcoords = gp->giveNaturalCoordinates();
183  FloatArray gcoords, normal, N;
184  FloatArray Phi;
185 
186  double detJ = fabs( geoInterpolation->boundaryGiveTransformationJacobian( Boundary, lcoords, FEIElementGeometryWrapper(thisElement) ) ) * gp->giveWeight();
187 
188  geoInterpolation->boundaryEvalNormal( normal, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );
189  geoInterpolation->boundaryEvalN( N, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );
190  geoInterpolation->boundaryLocal2Global( gcoords, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );
191 
192  FloatArray pPhi, mPhi, zPhi;
193  pPhi.resize( Dofs->giveSize() );
194  pPhi.zero();
195  mPhi.resize( Dofs->giveSize() );
196  mPhi.zero();
197  zPhi.resize( Dofs->giveSize() );
198  zPhi.zero();
199 
200  // Build phi (analytical averaging, not projected onto the mesh)
201  computeBaseFunctionValueAt(Phi, gcoords, * Dofs, * myMode.myEngngModel);
202 
203  // Build zPhi for this DofID
204  for ( int l = 1; l <= zNodes.giveSize(); l++ ) {
205  int nodeID = zNodes.at(l);
206  for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
207  zPhi.at(m) = zPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
208  }
209  }
210 
211 
212  // Build pPhi for this DofID
213  for ( int l = 1; l <= pNodes.giveSize(); l++ ) {
214  int nodeID = pNodes.at(l);
215  for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
216  pPhi.at(m) = pPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
217  }
218  }
219 
220  // Build mPhi for this DofID
221  for ( int l = 1; l <= mNodes.giveSize(); l++ ) {
222  int nodeID = mNodes.at(l);
223  for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
224  mPhi.at(m) = mPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
225  }
226  }
227 
228  c0 = c0 + zPhi.dotProduct(normal, 3) * detJ;
229  cp = cp + pPhi.dotProduct(normal, 3) * detJ;
230  cm = cm + mPhi.dotProduct(normal, 3) * detJ;
231 
232  App = App + pPhi.dotProduct(pPhi, 3) * detJ;
233  Amm = Amm + mPhi.dotProduct(mPhi, 3) * detJ;
234  A0p = A0p + zPhi.dotProduct(pPhi, 3) * detJ;
235  A0m = A0m + zPhi.dotProduct(mPhi, 3) * detJ;
236 
237  Bp = Bp + Phi.dotProduct(pPhi, 3) * detJ;
238  Bm = Bm + Phi.dotProduct(mPhi, 3) * detJ;
239  }
240  }
241 
242  * am = -( A0m * cp * cp - Bm * cp * cp - A0p * cm * cp + App * c0 * cm + Bp * cm * cp ) / ( App * cm * cm + Amm * cp * cp );
243  * ap = -( A0p * cm * cm - Bp * cm * cm - A0m * cm * cp + Amm * c0 * cp + Bm * cm * cp ) / ( App * cm * cm + Amm * cp * cp );
244 }
245 
246 void
248 {
249  pList.clear();
250  mList.clear();
251  zList.clear();
252 
253  for ( int j = 1; j <= bnodes.giveSize(); j++ ) {
254  DofManager *dman = e.giveDofManager( bnodes.at(j) );
255 
256  bool isZero = false;
257  bool isPlus = false;
258  bool isMinus = false;
259 
260  whichBoundary(* dman->giveCoordinates(), isPlus, isMinus, isZero);
261 
262  if ( isZero ) {
263  zList.insertSorted(j);
264  } else if ( isPlus ) {
265  pList.insertSorted(j);
266  } else if ( isMinus ) {
267  mList.insertSorted(j);
268  }
269 
270  // Find global DofManager and fetch nodal values
271  for ( size_t k = 0; k < mode.SurfaceData.size(); k++ ) {
272  if ( mode.SurfaceData.at(k)->DofMan == dman ) {
273  int IndexOfDofIDItem = 0;
274  for ( int l = 1; l <= dofs.giveSize(); l++ ) {
275  if ( dofs.at(l) == mode.SurfaceData.at(k)->DofID ) {
276  IndexOfDofIDItem = l;
277  break;
278  }
279  }
280  nodeValues.at(IndexOfDofIDItem, j) = mode.SurfaceData.at(k)->value;
281  }
282  }
283  }
284 }
285 
286 double
288 {
289  return this->giveUnknown(mode, tStep, dof);
290 }
291 
292 double
294 {
295  // Return value of pertinent quantity in coordinate given by dof
296 
297  FloatArray shapeFunctionValues;
298  computeDofTransformation(dof, shapeFunctionValues);
299 
300  FloatArray gamma;
301  myNode->giveUnknownVector(gamma, myDofIDs, mode, tStep); // alpha1, alpha2,...
302 
303  double out = shapeFunctionValues.dotProduct(gamma);
304 
305  return out;
306 }
307 
308 void
310 {
311  if ( !isLoaded ) {
312  loadProblem();
313  }
314 
315  FloatArray values, masterContribs2, d, values2;
316 
317  masterContribs.resize( this->giveDomain()->giveNumberOfSpatialDimensions() );
318  masterContribs2.resize( this->giveDomain()->giveNumberOfSpatialDimensions() );
319 
320  IntArray dofIDs = {dof->giveDofID()};
321 
322  bool isPlus, isMinus, isZero, found;
323  whichBoundary(* dof->giveDofManager()->giveCoordinates(), isPlus, isMinus, isZero);
324 
325  for ( int i = 1; i <= this->giveDomain()->giveNumberOfSpatialDimensions(); i++ ) {
326  double factor = 1.0;
327  found = false;
328 
329  modeStruct *ms = modes.at(i - 1);
330  for ( size_t j = 0; j < ms->SurfaceData.size(); j++ ) {
331  SurfaceDataStruct *sd = ms->SurfaceData.at(j);
332  if ( sd->DofMan->giveNumber() == dof->giveDofManager()->giveNumber() ) {
333  if ( sd->DofID == dof->giveDofID() ) {
334  values.resize(1);
335  values.at(1) = sd->value;
336  found = true;
337  break;
338  }
339  }
340  }
341 
342  if ( !found ) {
343  printf( "%u\n", dof->giveDofManager()->giveNumber() );
344  OOFEM_ERROR("Node not found");
345  }
346 
347  //giveValueAtPoint(values2, *dof->giveDofManager()->giveCoordinates(), dofIDs, *modes.at(i-1)->myEngngModel);
348  //printf ("Mode %u, DofManager: %u, DofIDItem %u, value %10.10f\n", i, dof->giveDofManager()->giveNumber(), dof->giveDofID(), values.at(1));
349 
350  factor = isPlus ? modes.at(i - 1)->ap : factor;
351  factor = isMinus ? modes.at(i - 1)->am : factor;
352  factor = isZero ? 1.0 : factor;
353 
354  masterContribs.at(i) = factor * values.at(1);
355  }
356 }
357 
358 int
360 {
361  return this->giveDomain()->giveNumberOfSpatialDimensions();
362 }
363 
364 Dof *
366 {
367  return myNode->giveDofWithID(myDofIDs.at(mdof));
368 }
369 
370 void
372 {
373  for ( int i = 0; i < this->domain->giveNumberOfSpatialDimensions(); i++ ) {
374  OOFEM_LOG_INFO("************************** Instanciating microproblem from file %s for dimension %u\n", filename.c_str(), i);
375 
376  // Set up and solve problem
377  OOFEMTXTDataReader drMicro( filename.c_str() );
378  EngngModel *myEngngModel = InstanciateProblem(drMicro, _processor, 0, NULL, false);
379  drMicro.finish();
380  myEngngModel->checkProblemConsistency();
381  myEngngModel->initMetaStepAttributes( myEngngModel->giveMetaStep(1) );
382  thisTimestep = myEngngModel->giveNextStep();
383  myEngngModel->init();
384  this->setLoads(myEngngModel, i + 1);
385 
386  // Check
387  for ( auto &elem : myEngngModel->giveDomain(1)->giveElements() ) {
388  FloatArray centerCoord;
389  int vlockCount = 0;
390  centerCoord.resize(3);
391  centerCoord.zero();
392 
393  for ( int k = 1; k <= elem->giveNumberOfDofManagers(); k++ ) {
394  DofManager *dman = elem->giveDofManager(k);
395  centerCoord.add( * dman->giveCoordinates() );
396  for ( Dof *dof: *dman ) {
397  if ( dof->giveBcId() != 0 ) {
398  vlockCount++;
399  }
400  }
401  }
402  if ( vlockCount == 30 ) {
403  OOFEM_WARNING("Element over-constrained (%u)! Center coordinate: %f, %f, %f\n", elem->giveNumber(), centerCoord.at(1) / 10, centerCoord.at(2) / 10, centerCoord.at(3) / 10);
404  }
405  }
406 
407  myEngngModel->solveYourselfAt(thisTimestep);
408  isLoaded = true;
409 
410  // Set correct export filename
411  std :: string originalFilename;
412  originalFilename = myEngngModel->giveOutputBaseFileName();
413 
414  if (i==0) originalFilename = originalFilename + "_X";
415  if (i==1) originalFilename = originalFilename + "_Y";
416  if (i==2) originalFilename = originalFilename + "_Z";
417  if (dumpSnapshot) {
418  myEngngModel->letOutputBaseFileNameBe(originalFilename + "_1_Base");
419  myEngngModel->doStepOutput(thisTimestep);
420  }
421 
422  modeStruct *mode = new(modeStruct);
423  mode->myEngngModel = myEngngModel;
424 
425  // Check elements
426 
427  // Set unknowns to the mean value of opposite sides of the domain.
428  // Loop thru all nodes and compute phi for all degrees of freedom on the boundary. Save phi in a list for later use.
429 
430  initializeSurfaceData(mode);
431  // Update with factor
432  double am=1.0, ap=1.0;
433 
434  if (useCorrectionFactors) {
435  computeCorrectionFactors(*mode, &dofs, &am, &ap );
436  }
437 
438  OOFEM_LOG_INFO("Correction factors: am=%f, ap=%f\n", am, ap);
439 
440  mode->ap = ap;
441  mode->am = am;
442 
444 
445  if (dumpSnapshot) {
446  myEngngModel->letOutputBaseFileNameBe(originalFilename + "_2_Updated");
447  myEngngModel->doStepOutput(thisTimestep);
448  }
449 
450  modes.push_back(mode);
451 
452  OOFEM_LOG_INFO("************************** Microproblem at %p instanciated \n", myEngngModel);
453  }
454 }
455 
456 void
458 {
459  //Update values with correction factors
460  for ( size_t j = 0; j < m->SurfaceData.size(); j++ ) {
461  SurfaceDataStruct *sd = m->SurfaceData.at(j);
462  DofManager *dman = sd->DofMan;
463  Dof *d = dman->giveDofWithID(sd->DofID);
464 
465  double factor = 1.0;
466  factor = m->SurfaceData.at(j)->isPlus ? m->ap : factor;
467  factor = m->SurfaceData.at(j)->isMinus ? m->am : factor;
468  factor = m->SurfaceData.at(j)->isZeroBoundary ? 1.0 : factor;
469 
470  if ( dynamic_cast< MasterDof * >(d) && m->SurfaceData.at(j)->isFree ) {
471  double u = m->SurfaceData.at(j)->value;
472  this->setBoundaryConditionOnDof(dman->giveDofWithID(m->SurfaceData.at(j)->DofID), u * factor);
473  }
474  }
475 }
476 
477 void
479 {
481  FloatArray gradP;
482 
483  gradP.resize( this->giveDomain()->giveNumberOfSpatialDimensions() );
484  gradP.zero();
485  gradP.at(d) = 1.0;
486 
487  ir.setRecordKeywordField("deadweight", 1);
488  ir.setField(gradP, _IFT_Load_components);
490 
491  int bcID = myEngngModel->giveDomain(1)->giveNumberOfBoundaryConditions() + 1;
492  GeneralBoundaryCondition *myBodyLoad;
493  myBodyLoad = classFactory.createBoundaryCondition( "deadweight", bcID, myEngngModel->giveDomain(1) );
494  myBodyLoad->initializeFrom(& ir);
495  myEngngModel->giveDomain(1)->setBoundaryCondition(bcID, myBodyLoad);
496 
497  for ( auto &elem : myEngngModel->giveDomain(1)->giveElements() ) {
498  IntArray *blArray;
499  blArray = elem->giveBodyLoadArray();
500  blArray->resizeWithValues(blArray->giveSize() + 1);
501  blArray->at( blArray->giveSize() ) = bcID;
502  }
503 }
504 
505 void
507 {
508  answer.resize( dofIDs.giveSize() );
509  answer.zero();
510 
511  if ( useConstantBase ) {
512  for ( int i = 1; i <= answer.giveSize(); i++ ) {
513  answer.at(i) = 1;
514  }
515  ;
516  } else {
517  std :: vector< FloatArray >checkcoords;
518  std :: vector< int >permuteIndex;
519  int n = 0;
520 
521  if ( !isLoaded ) {
522  loadProblem();
523  }
524 
525  myEngngModel.giveDomain(1)->giveSpatialLocalizer()->init(false);
526 
527  if ( this->giveDomain()->giveNumberOfSpatialDimensions() == 2 ) {
528  coords.resize(2);
529  }
530 
531  // Determine if current coordinate is at a max or min point and if so, which type (on a surface, edge or a corner?)
532  // n is the number of dimensions at which the point is an extremum, permuteIndex tells in which dimension the coordinate is max/min
533 
534  int thisMask = 0;
535 
536  for ( int i = 1; i <= coords.giveSize(); i++ ) {
537  if ( ( fabs( maxCoord.at(i) - coords.at(i) ) < TOL ) || ( fabs( minCoord.at(i) - coords.at(i) ) < TOL ) ) {
538  permuteIndex.push_back(i);
539  n++;
540  //thisMask = thisMask + pow(2.0, i - 1); // compiler warning on conversion from double to int
541  thisMask = thisMask + ( 0x01 << ( i - 1 ) );
542  }
543  }
544  int _s = 0x01 << n;
545  for ( int i = 0; i < _s; i++ ) {
546  int mask = i, counter = 1;
547  FloatArray newCoord = coords;
548 
549  for ( int j = 1; j <= n; j++ ) {
550  double d = 0.0; //TOL;
551  if ( ( mask & 1 ) == 0 ) { // Max
552  newCoord.at( permuteIndex.at(counter - 1) ) = minCoord.at( permuteIndex.at(counter - 1) ) + d;
553  } else { // Min
554  newCoord.at( permuteIndex.at(counter - 1) ) = maxCoord.at( permuteIndex.at(counter - 1) ) - d;
555  }
556  counter++;
557  mask = mask >> 1;
558  }
559  checkcoords.emplace_back(newCoord);
560  }
561 
562  // The followind define allows for use of weakly periodic bc to be copied. This does not comply with the theory but is used to check the validity of the code.
563 #define USEWPBC 0
564 
565 #if USEWPBC == 1
566  FloatArray *tempCoord = new FloatArray;
567  * tempCoord = coords;
568  checkcoords.clear();
569  checkcoords.push_back(tempCoord);
570 #endif
571  FloatArray values;
572  for ( size_t i = 0; i < checkcoords.size(); i++ ) {
573  giveValueAtPoint(values, checkcoords[i], dofIDs, myEngngModel);
574  //printf("Values at (%f, %f, %f) are [%f, %f, %f]\n", checkcoords.at(i)->at(1), checkcoords.at(i)->at(2), checkcoords.at(i)->at(3), values.at(1), values.at(2), values.at(3));
575 #if USEWPBC == 1
576  for ( int j = 1; j <= values.giveSize(); j++ ) {
577  answer.at(j) = values.at(j);
578  }
579 #else
580  for ( int j = 1; j <= values.giveSize(); j++ ) {
581  answer.at(j) += values.at(j) / ( ( double ) pow(2.0, n) );
582  }
583 #endif
584  }
585  }
586 }
587 
588 void
590 {
591  answer.resize( dofIDs.giveSize() );
592 
593  FloatArray closest, lcoords, values;
594 
595  Element *elementAtCoords = myEngngModel.giveDomain(1)->giveSpatialLocalizer()->giveElementClosestToPoint(lcoords, closest, coords, 1);
596  if ( elementAtCoords == NULL ) {
597  OOFEM_WARNING("Cannot find element closest to point");
598  coords.pY();
599  return;
600  }
601 
602  IntArray eldofids;
603 
604  elementAtCoords->giveElementDofIDMask(eldofids);
605  elementAtCoords->computeField(VM_Total, thisTimestep, lcoords, values);
606 
607  for ( int i = 1; i <= dofIDs.giveSize(); i++ ) {
608  for ( int j = 1; j <= eldofids.giveSize(); j++ ) {
609  if ( dofIDs.at(i) == eldofids.at(j) ) {
610  answer.at(i) = values.at(j);
611  break;
612  }
613  }
614  }
615 }
616 
617 void
619 {
620  int bcID = d->giveBcId();
621 
622  if ( bcID == 0 ) {
624  ir.setRecordKeywordField("boundarycondition", 1);
627 
629 
631  myBC = classFactory.createBoundaryCondition( "boundarycondition", bcID, d->giveDofManager()->giveDomain() );
632  myBC->initializeFrom(& ir);
633  d->giveDofManager()->giveDomain()->setBoundaryCondition(bcID, myBC);
634 
635  d->setBcId(bcID);
636  } else {
637  BoundaryCondition *bc = static_cast< BoundaryCondition * >( d->giveDofManager()->giveDomain()->giveBc(bcID) );
638  bc->setPrescribedValue(value);
639  }
640 }
641 
642 void
644 {
645 
646  EngngModel *m=mode->myEngngModel;
647  double TOL2=1e-3;
648 
649  IntArray pNodes, mNodes, zNodes;
650 
651  Set *mySet = this->domain->giveSet( this->giveSetNumber() );
652  IntArray BoundaryList = mySet->giveBoundaryList();
653 
654  // First add all nodes to pNodes or nNodes respectively depending on coordinate and normal.
655  for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) {
656  int ElementID = BoundaryList(2 * i);
657  int Boundary = BoundaryList(2 * i + 1);
658 
659  Element *e = m->giveDomain(1)->giveElement(ElementID);
660  FEInterpolation *geoInterpolation = e->giveInterpolation();
661 
662  // Check all sides of element
663  IntArray bnodes;
664 
665 #define usePoints 1
666 #if usePoints == 1
667  // Check if all nodes are on the boundary
668  geoInterpolation->boundaryGiveNodes(bnodes, Boundary);
669  for ( int k = 1; k <= bnodes.giveSize(); k++ ) {
670  DofManager *dman = e->giveDofManager( bnodes.at(k) );
671  for ( int l = 1; l <= dman->giveCoordinates()->giveSize(); l++ ) {
672  if ( fabs( dman->giveCoordinates()->at(l) - maxCoord.at(l) ) < TOL2 ) {
673  pNodes.insertOnce( dman->giveNumber() );
674  }
675  if ( fabs( dman->giveCoordinates()->at(l) - minCoord.at(l) ) < TOL2 ) {
676  mNodes.insertOnce( dman->giveNumber() );
677  }
678  }
679  }
680 #else
681  // Check normal
682  FloatArray lcoords;
683  lcoords.resize(2);
684  lcoords.at(1) = 0.33333;
685  lcoords.at(2) = 0.33333;
686 
687  FloatArray normal;
688  geoInterpolation->boundaryEvalNormal( normal, j, lcoords, FEIElementGeometryWrapper(e) );
689  geoInterpolation->boundaryGiveNodes(bnodes, j);
690 
691  printf( "i=%u\tj=%u\t(%f\t%f\t%f)\n", i, j, normal.at(1), normal.at(2), normal.at(3) );
692  for ( int k = 1; k <= normal.giveSize(); k++ ) {
693  if ( fabs( ( fabs( normal.at(k) ) - 1 ) ) < 1e-4 ) { // Points in x, y or z direction
694  addTo = NULL;
695  if ( normal.at(k) > 0.5 ) {
696  addTo = & pNodes;
697  }
698  if ( normal.at(k) < -0.5 ) {
699  addTo = & mNodes;
700  }
701  if ( addTo != NULL ) {
702  for ( int l = 1; l <= bnodes.giveSize(); l++ ) {
703  bool isSurface = false;
704  DofManager *dman = e->giveDofManager( bnodes.at(l) );
705  dman->giveCoordinates()->printYourself();
706  for ( int m = 1; m <= dman->giveCoordinates()->giveSize(); m++ ) {
707  if ( ( fabs( dman->giveCoordinates()->at(m) - maxCoord.at(m) ) < TOL2 ) || ( fabs( dman->giveCoordinates()->at(m) - minCoord.at(m) ) < TOL2 ) ) {
708  isSurface = true;
709  }
710  }
711 
712  if ( isSurface ) {
713  addTo->insertOnce( e->giveDofManagerNumber( bnodes.at(l) ) );
714  }
715  }
716  }
717  }
718  }
719 #endif
720  }
721 
722 #if 0
723  printf("p=[");
724  for ( int i = 1; i < pNodes.giveSize(); i++ ) {
725  printf( "%u, ", pNodes.at(i) );
726  }
727  printf("];\n");
728  printf("m=[");
729  for ( int i = 1; i < mNodes.giveSize(); i++ ) {
730  printf( "%u, ", mNodes.at(i) );
731  }
732  printf("];\n");
733 #endif
734  //The intersection of pNodes and mNodes constitutes zNodes
735  {
736  int i = 1, j = 1;
737  while ( i <= pNodes.giveSize() ) {
738  j = 1;
739  while ( j <= mNodes.giveSize() && ( i <= pNodes.giveSize() ) ) {
740  //printf("%u == %u?\n", pNodes.at(i), mNodes.at(j));
741  if ( pNodes.at(i) == mNodes.at(j) ) {
742  zNodes.insertOnce( pNodes.at(i) );
743  pNodes.erase(i);
744  mNodes.erase(j);
745  } else {
746  j++;
747  }
748  }
749  i++;
750  }
751  }
752 
753  // Compute base function values on nodes for dofids
754  copyDofManagersToSurfaceData(mode, pNodes, true, false, false);
755  copyDofManagersToSurfaceData(mode, mNodes, false, true, false);
756  copyDofManagersToSurfaceData(mode, zNodes, false, false, true);
757 
758 #if 0
759  printf("p2=[");
760  for ( int i = 1; i <= pNodes.giveSize(); i++ ) {
761  printf( "%u, ", pNodes.at(i) );
762  }
763  printf("];\n");
764  printf("m2=[");
765  for ( int i = 1; i <= mNodes.giveSize(); i++ ) {
766  printf( "%u, ", mNodes.at(i) );
767  }
768  printf("];\n");
769  printf("z2=[");
770  for ( int i = 1; i <= zNodes.giveSize(); i++ ) {
771  printf( "%u, ", zNodes.at(i) );
772  }
773  printf("];\n");
774 
775  printf("pCoords=[");
776  for ( int i = 1; i <= pNodes.giveSize(); i++ ) {
777  FloatArray *coords = m->giveDomain(1)->giveDofManager( pNodes.at(i) )->giveCoordinates();
778  printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
779  }
780  printf("]\n");
781  printf("mCoords=[");
782  for ( int i = 1; i <= mNodes.giveSize(); i++ ) {
783  FloatArray *coords = m->giveDomain(1)->giveDofManager( mNodes.at(i) )->giveCoordinates();
784  printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
785  }
786  printf("]\n");
787  printf("zCoords=[");
788  for ( int i = 1; i <= zNodes.giveSize(); i++ ) {
789  FloatArray *coords = m->giveDomain(1)->giveDofManager( zNodes.at(i) )->giveCoordinates();
790  printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
791  }
792  printf("];\n");
793 #endif
794 }
795 
796 void
797 SolutionbasedShapeFunction :: whichBoundary(FloatArray &coord, bool &isPlus, bool &isMinus, bool &isZero)
798 {
799  isPlus = false;
800  isMinus = false;
801  isZero = false;
802 
803  for ( int k = 1; k <= coord.giveSize(); k++ ) {
804  isPlus = isPlus || ( fabs( coord.at(k) - maxCoord.at(k) ) < TOL );
805  isMinus = isMinus || ( fabs( coord.at(k) - minCoord.at(k) ) < TOL );
806  }
807 
808  isZero = isPlus && isMinus;
809 }
810 
811 void
812 SolutionbasedShapeFunction :: copyDofManagersToSurfaceData(modeStruct *mode, IntArray nodeList, bool isPlus, bool isMinus, bool isZeroBoundary)
813 {
814  for ( int i = 1; i <= nodeList.giveSize(); i++ ) {
815  FloatArray values;
816 
817  IntArray DofIDs;
818  DofManager *dman = mode->myEngngModel->giveDomain(1)->giveDofManager(nodeList.at(i));
819 
820  computeBaseFunctionValueAt(values, *dman->giveCoordinates(), this->dofs, *mode->myEngngModel );
821 
822 /* <<<<<<< HEAD
823 =======
824  for ( int j = 1; j <= this->dofs.giveSize(); j++ ) {
825  SurfaceDataStruct *surfaceData = new(SurfaceDataStruct);
826  Dof *d = dman->giveDofWithID( dofs.at(j) );
827 >>>>>>> 147f565295394adef603dae296a820af5f28d9cd
828 */
829  // Check that current node contains current DofID
830  for (int j=1; j<=this->dofs.giveSize(); j++) {
831  for (Dof *d: *dman ){ //int k=1; k<= dman->giveNumberOfDofs(); k++ ) {
832 
833  //Dof *d = dman->dofArray.at(k);// giveDof(k);
834 
835  if (d->giveDofID() == this->dofs.at(j)) {
836  SurfaceDataStruct *surfaceData = new(SurfaceDataStruct);
837  surfaceData->DofID = (DofIDItem) this->dofs.at(j);
838  surfaceData->DofMan = dman;
839  surfaceData->isPlus = isPlus;
840  surfaceData->isMinus = isMinus;
841  surfaceData->isZeroBoundary = isZeroBoundary;
842  surfaceData->isFree = d->giveBcId() == 0;
843  surfaceData->value = values.at(j);
844 
845  mode->SurfaceData.push_back(surfaceData);
846  }
847  }
848  }
849  }
850 }
851 }
void setField(int item, InputFieldType id)
REGISTER_BoundaryCondition(BoundaryCondition)
void erase(int pos)
Erase the element at given position (1-based index) Receiver will shrink accordingly, the values at positions (pos+1,...,size) will be moved to positions (pos,...,size-1)
Definition: intarray.C:163
Class and object Domain.
Definition: domain.h:115
int giveDofManagerNumber(int i) const
Translates local to global indices for dof managers.
Definition: element.h:590
void setBoundaryCondition(int i, GeneralBoundaryCondition *obj)
Sets i-th component. The component will be further managed and maintained by domain object...
Definition: domain.C:459
virtual void computeDofTransformation(ActiveDof *dof, FloatArray &masterContribs)
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: activebc.h:75
const IntArray & giveBoundaryList()
Returns list of element boundaries within set.
Definition: set.C:140
int giveNumberOfBoundaryConditions() const
Returns number of boundary conditions in domain.
Definition: domain.h:440
Abstract class representing field of primary variables (those, which are unknown and are typically as...
Definition: primaryfield.h:104
virtual double boundaryEvalNormal(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the normal on the requested boundary.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
void splitBoundaryNodeIDs(modeStruct &mode, Element &e, IntArray &boundary, IntArray &pList, IntArray &mList, IntArray &zList, FloatMatrix &nodeValues)
void setPrescribedValue(double s)
Set prescribed value at the input record string of receiver.
void whichBoundary(FloatArray &coord, bool &isPlus, bool &isMinus, bool &isZero)
virtual FloatArray * giveCoordinates()
Definition: dofmanager.h:382
void computeBaseFunctionValueAt(FloatArray &answer, FloatArray &coords, IntArray &dofIDs, EngngModel &myEngngModel)
Abstract base class for all finite elements.
Definition: element.h:145
Base class for dof managers.
Definition: dofmanager.h:113
#define _IFT_SolutionbasedShapeFunction_DumpSnapshots
GeneralBoundaryCondition * createBoundaryCondition(const char *name, int num, Domain *domain)
Creates new instance of boundary condition corresponding to given keyword.
Definition: classfactory.C:179
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition: domain.C:1067
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
virtual void setBcId(int bcId)
Overwrites the boundary condition id (0-inactive BC), intended for specific purposes such as coupling...
Definition: dof.h:382
GeneralBoundaryCondition * giveBc(int n)
Service for accessing particular domain bc.
Definition: domain.C:243
#define _IFT_GeneralBoundaryCondition_timeFunct
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
Class representing "master" degree of freedom.
Definition: masterdof.h:92
EngngModel * InstanciateProblem(DataReader &dr, problemMode mode, int contextFlag, EngngModel *_master, bool parallelFlag)
Instanciates the new problem.
Definition: util.C:45
void copyDofManagersToSurfaceData(modeStruct *mode, IntArray nodeList, bool isPlus, bool isMinus, bool isZero)
void insertSorted(int value, int allocChunk=0)
Inserts given value into a receiver, which is assumed to be sorted.
Definition: intarray.C:350
int giveSetNumber()
Gives the set number which boundary condition is applied to.
void giveUnknownVector(FloatArray &answer, const IntArray &dofMask, ValueModeType mode, TimeStep *tStep, bool padding=false)
Assembles the vector of unknowns in global c.s for given dofs of receiver.
Definition: dofmanager.C:685
virtual int giveBcId()=0
Returns the id of associated boundary condition, if there is any.
Class implementing Dirichlet boundary condition on DOF (primary boundary condition).
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
void insertOnce(int p)
Insert once (does not make any assumption about receiver state or ordering, quite inefficient)...
Definition: intarray.C:412
#define OOFEM_ERROR(...)
Definition: error.h:61
void clear()
Clears the array (zero size).
Definition: intarray.h:177
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
void setBoundaryConditionOnDof(Dof *d, double value)
virtual void boundaryLocal2Global(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Maps the local boundary coordinates to global.
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
SpatialLocalizer * giveSpatialLocalizer()
Returns receiver&#39;s associated spatial localizer.
Definition: domain.C:1184
DofIDItem giveDofID() const
Returns DofID value of receiver, which determines type of of unknown connected to receiver (e...
Definition: dof.h:276
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
void resizeWithValues(int n, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: intarray.C:115
Set * giveSet(int n)
Service for accessing particular domain set.
Definition: domain.C:363
#define _IFT_SolutionbasedShapeFunction_Externalset
virtual double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the determinant of the transformation Jacobian on the requested boundary.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
#define N(p, q)
Definition: mdm.C:367
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
Abstract base class for all active boundary conditions.
Definition: activebc.h:63
Abstract base class for all boundary conditions of problem.
virtual void giveElementDofIDMask(IntArray &answer) const
Returns element dof mask for node.
Definition: element.h:498
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
Class representing "slave" degree of freedom with an active boundary condition.
Definition: activedof.h:48
void appendDof(Dof *dof)
Adds the given Dof into the receiver.
Definition: dofmanager.C:134
virtual void boundaryGiveNodes(IntArray &answer, int boundary)=0
Gives the boundary nodes for requested boundary number.
int giveNextFreeDofID(int increment=1)
Gives the next free dof ID.
Definition: domain.C:1411
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual int init(bool force=false)
Initialize receiver data structure if not done previously If force is set to true, the initialization is enforced (useful if domain geometry has changed)
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
#define _IFT_SolutionbasedShapeFunction_UseCorrectionFactors
virtual void pY() const
Print receiver on stdout with high accuracy.
Definition: floatarray.C:787
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
virtual Element * giveElementClosestToPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &coords, int region=0)=0
Returns the element closest to a given point.
Class representing the general Input Record.
Definition: inputrecord.h:101
virtual void printYourself() const
Print receiver on stdout.
Definition: floatarray.C:747
virtual IntegrationRule * giveBoundaryIntegrationRule(int order, int boundary)
Sets up a suitable integration rule for integrating over the requested boundary.
Definition: feinterpol.C:63
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
Class representing the a dynamic Input Record.
ClassFactory & classFactory
Definition: classfactory.C:59
#define _IFT_BoundaryCondition_PrescribedValue
[rn,optional] Prescribed value of all DOFs
void logDataMsg(const char *c, T myArray)
#define _IFT_Load_components
Definition: load.h:46
virtual Dof * giveMasterDof(ActiveDof *dof, int mdof)
Give the pointer to master dof belonging to active DOF.
virtual FloatArray * giveCoordinates()
Definition: node.h:114
void setRecordKeywordField(std::string keyword, int number)
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
Domain * giveDomain() const
Definition: femcmpnn.h:100
#define _IFT_SolutionbasedShapeFunction_ShapeFunctionFile
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
std::vector< std::unique_ptr< Element > > & giveElements()
Definition: domain.h:279
void logData(T myArray)
void setLoads(EngngModel *myEngngModel, int d)
virtual DofManager * giveInternalDofManager(int i)
Gives an internal dof manager from receiver.
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
DofManager * giveDofManager() const
Definition: dof.h:123
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Class representing the implementation of plain text date reader.
virtual void computeField(ValueModeType mode, TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer)
Computes the unknown vector interpolated at the specified local coordinates.
Definition: element.h:508
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
the oofem namespace is to define a context or scope in which all oofem names are defined.
DofManager * giveDofManager(int i) const
Definition: element.C:514
void computeCorrectionFactors(modeStruct &myMode, IntArray *Dofs, double *am, double *ap)
Domain * giveDomain(int n)
Service for accessing particular problem domain.
Definition: engngm.C:1720
Class implementing node in finite element mesh.
Definition: node.h:87
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
int giveNumber() const
Definition: femcmpnn.h:107
DofManager * giveDofManager(int n)
Service for accessing particular domain dof manager.
Definition: domain.C:314
virtual int giveNumberOfMasterDofs(ActiveDof *dof)
Allows for active boundary conditions to handle their own special DOF.
virtual void boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the basis functions on the requested boundary.
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
std::vector< SurfaceDataStruct * > SurfaceData
Class representing solution step.
Definition: timestep.h:80
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
void giveValueAtPoint(FloatArray &answer, const FloatArray &coords, IntArray &dofID, EngngModel &myEngngModel)
giveValueAtPoint
virtual double giveUnknown(PrimaryField &field, ValueModeType mode, TimeStep *tStep, ActiveDof *dof)
Computes the value of the dof.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011