FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
HexBeam.cpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2005 Sandia Corporation. */
3 /* Under the terms of Contract DE-AC04-94AL85000, there is a */
4 /* non-exclusive license for use of this work by or on behalf */
5 /* of the U.S. Government. Export of this program may require */
6 /* a license from the United States Government. */
7 /*--------------------------------------------------------------------*/
8 
9 #include <fei_macros.hpp>
10 
11 #include <test_utils/HexBeam.hpp>
12 
13 #undef fei_file
14 #define fei_file "HexBeam.cpp"
15 
16 HexBeam::HexBeam(int W, int D, int DofPerNode,
17  int decomp, int numProcs, int localProc)
18  : W_(W),
19  D_(D),
20  decomp_(decomp),
21  numProcs_(numProcs),
22  localProc_(localProc),
23  firstLocalElem_(0),
24  firstLocalNode_(0),
25  inErrorState_(false),
26  nodesPerElem_(8),
27  dofPerNode_(DofPerNode)
28 {
29  totalNumElems_ = W*W*D;
30  totalNumNodes_ = (W+1)*(W+1)*(D+1);
31  numElemsPerSlice_ = W*W;
32  numNodesPerSlice_ = (W+1)*(W+1);
33 
34  numGlobalDOF_ = totalNumNodes_*dofPerNode_;
35 
36  numLocalSlices_ = D/numProcs;
37  int remainder = D%numProcs;
38 
39  switch(decomp) {
40  case HexBeam::OneD:
41  if (D < numProcs) {
42  throw std::runtime_error("HexBeam: size D must be greater or equal num-procs.");
43  }
44  if (localProc < remainder) {
45  ++numLocalSlices_;
46  }
47 
48  localNumNodes_ = numNodesPerSlice_*(numLocalSlices_+1);
49  localNumElems_ = numElemsPerSlice_*numLocalSlices_;
50  numLocalDOF_ = localNumNodes_*dofPerNode_;
51 
52  if (localProc > 0) {
53  firstLocalElem_ = localProc*numLocalSlices_*numElemsPerSlice_;
54  firstLocalNode_ = localProc*numLocalSlices_*numNodesPerSlice_;
55  if (remainder <= localProc && remainder > 0) {
56  firstLocalElem_ += remainder*numElemsPerSlice_;
57  firstLocalNode_ += remainder*numNodesPerSlice_;
58  }
59  }
60 
61  break;
62 
63  case HexBeam::TwoD:
64  case HexBeam::ThreeD:
65  default:
66  fei::console_out() << "HexBeam: invalid decomp option: " << decomp
67  <<" aborting." << FEI_ENDL;
68  std::abort();
69  }
70 }
71 
72 HexBeam::~HexBeam()
73 {
74 }
75 
76 int HexBeam::getElemConnectivity(int elemID, int* nodeIDs)
77 {
78  if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
79  return(-1);
80  }
81 
82  int whichGlobalSlice = elemID/numElemsPerSlice_;
83  int elemX = elemID%W_;
84  int elemY = (elemID%(W_*W_))/W_;
85 
86  int firstElemNode = whichGlobalSlice*numNodesPerSlice_
87  + elemY*(W_+1) + elemX;
88 
89  nodeIDs[0] = firstElemNode;
90  nodeIDs[1] = firstElemNode+1;
91  nodeIDs[2] = firstElemNode+W_+1;
92  nodeIDs[3] = nodeIDs[2]+1;
93 
94  nodeIDs[4] = nodeIDs[0]+numNodesPerSlice_;
95  nodeIDs[5] = nodeIDs[1]+numNodesPerSlice_;
96  nodeIDs[6] = nodeIDs[2]+numNodesPerSlice_;
97  nodeIDs[7] = nodeIDs[3]+numNodesPerSlice_;
98 
99  return(0);
100 }
101 
102 int HexBeam::getElemStiffnessMatrix(int elemID, double* elemMat)
103 {
104  if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
105  return(-1);
106  }
107 
108  int i, len = nodesPerElem_*dofPerNode_*nodesPerElem_*dofPerNode_;
109 
110  for(i=0; i<len; ++i) {
111  elemMat[i] = 0.0;
112  }
113 
114  //Should set up some semi-realistic stiffness-matrix coefficients here...
115  //For now just use arbitrary numbers and set it up so the matrix won't be
116  //too ill-conditioned. (This is intended for an assembly test more than
117  //a solver test.)
118 
119  //Now set the diagonal to 4.0
120  len = nodesPerElem_*dofPerNode_;
121  for(i=0; i<len; ++i) {
122  int offset = i*len+i;
123  elemMat[offset] = 4.0;
124  }
125 
126  //Now set some off-diagonals
127  for(i=0; i<len; ++i) {
128  int offset = i*len+i;
129  if (i>1) {
130  elemMat[offset-2] = -0.5;
131  }
132 
133  if (i<len-2) {
134  elemMat[offset+2] = -0.5;
135  }
136 
137  if (i>3) {
138  elemMat[offset-4] = -0.1;
139  }
140  if (i<len-4) {
141  elemMat[offset+4] = -0.1;
142  }
143  }
144 
145  return(0);
146 }
147 
148 int HexBeam::getElemLoadVector(int elemID, double* elemVec)
149 {
150  if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
151  return(-1);
152  }
153 
154  int i, len = nodesPerElem_*dofPerNode_;
155  for(i=0; i<len; ++i) {
156  elemVec[i] = 1.0;
157  }
158 
159  return(0);
160 }
161 
162 int HexBeam::getNumBCNodes()
163 {
164  int numBCNodes = (numLocalSlices_+1)*(W_+1);
165  return( numBCNodes );
166 }
167 
168 int HexBeam::getBCNodes(int numNodes, int* nodeIDs)
169 {
170  if (numNodes != getNumBCNodes()) {
171  return(-1);
172  }
173 
174  int firstBCNode = firstLocalNode_ + W_;
175 
176  for(int i=0; i<numNodes; ++i) {
177  nodeIDs[i] = firstBCNode + W_+1;
178  }
179 
180  return(0);
181 }
182 
183 int HexBeam::getBCValues(int numBCNodes, int* offsetsIntoField, double* vals)
184 {
185  if (numBCNodes != getNumBCNodes()) {
186  return(-1);
187  }
188 
189  for(int i=0; i<numBCNodes; ++i) {
190  offsetsIntoField[i] = 0;
191  vals[i] = 2.0;
192  }
193 
194  return(0);
195 }
196 
197 int HexBeam::getNumSharedNodes()
198 {
199  if (numProcs_ < 2) return(0);
200 
201  int numSharedNodes = numNodesPerSlice_;
202  if (localProc_ > 0 && localProc_ < numProcs_-1) {
203  numSharedNodes += numNodesPerSlice_;
204  }
205 
206  return(numSharedNodes);
207 }
208 
209 int HexBeam::getSharedNodes(int numSharedNodes,
210  int*& sharedNodes,
211  int*& numSharingProcsPerNode,
212  int**& sharingProcs)
213 {
214  if (numProcs_ < 2) return(0);
215 
216  if (numSharedNodes != getNumSharedNodes()) {
217  return(-1);
218  }
219 
220  sharedNodes = new int[numSharedNodes];
221  numSharingProcsPerNode = new int[numSharedNodes];
222  sharingProcs = new int*[numSharedNodes];
223  int* sharingProcVals = new int[numSharedNodes];
224  if (sharedNodes == NULL || numSharingProcsPerNode == NULL ||
225  sharingProcs == NULL || sharingProcVals == NULL) {
226  return(-1);
227  }
228 
229  int i;
230  for(i=0; i<numSharedNodes; ++i) {
231  numSharingProcsPerNode[i] = 1;
232  sharingProcs[i] = &(sharingProcVals[i]);
233  }
234 
235  int firstSharedNode = firstLocalNode_+numNodesPerSlice_*numLocalSlices_;
236  int offset = 0;
237 
238  if (localProc_ < numProcs_ - 1) {
239  for(i=0; i<numNodesPerSlice_; ++i) {
240  sharedNodes[offset] = firstSharedNode+i;
241  sharingProcs[offset++][0] = localProc_+1;
242  }
243  }
244 
245  firstSharedNode = firstLocalNode_;
246  if (localProc_ > 0) {
247  for(i=0; i<numNodesPerSlice_; ++i) {
248  sharedNodes[offset] = firstSharedNode+i;
249  sharingProcs[offset++][0] = localProc_-1;
250  }
251  }
252 
253  return(0);
254 }
255 
256 namespace HexBeam_Functions {
257 
258 int print_cube_data(HexBeam& hexcube, int numProcs, int localProc)
259 {
260  FEI_COUT << localProc << ": num elems: " << hexcube.numLocalElems() << FEI_ENDL;
261  int i;
262  int* nodeIDs = new int[hexcube.numNodesPerElem()];
263  int firstLocalElem = hexcube.firstLocalElem();
264 
265  for(i=0; i<hexcube.numLocalElems(); ++i) {
266  hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs);
267  FEI_COUT << localProc << ": elem " << firstLocalElem+i << ", nodes: ";
268  for(int j=0; j<hexcube.numNodesPerElem(); ++j) {
269  FEI_COUT << nodeIDs[j] << " ";
270  }
271  FEI_COUT << FEI_ENDL;
272  }
273 
274  delete [] nodeIDs;
275 
276  return(0);
277 }
278 
279 
280 int init_elem_connectivities(FEI* fei, HexBeam& hexcube)
281 {
282  int numLocalElems = hexcube.numLocalElems();
283  int firstLocalElem = hexcube.firstLocalElem();
284  int nodesPerElem = hexcube.numNodesPerElem();
285  int fieldID = 0;
286 
287  int** fieldIDsTable = new int*[nodesPerElem];
288  int* numFieldsPerNode = new int[nodesPerElem];
289 
290  for(int j=0; j<nodesPerElem; ++j) {
291  numFieldsPerNode[j] = 1;
292  fieldIDsTable[j] = new int[numFieldsPerNode[j]];
293  for(int k=0; k<numFieldsPerNode[j]; ++k) {
294  fieldIDsTable[j][k] = fieldID;
295  }
296  }
297 
298  int blockID = 0;
299  CHK_ERR( fei->initElemBlock(blockID,
300  numLocalElems,
301  nodesPerElem,
302  numFieldsPerNode,
303  fieldIDsTable,
304  0, // no element-centered degrees-of-freedom
305  NULL, //null list of elem-dof fieldIDs
306  FEI_NODE_MAJOR) );
307 
308 
309  int* nodeIDs = new int[nodesPerElem];
310  if (nodeIDs == NULL) return(-1);
311 
312  for(int i=0; i<numLocalElems; ++i) {
313  CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
314 
315  CHK_ERR( fei->initElem(blockID, firstLocalElem+i, nodeIDs) );
316  }
317 
318  delete [] nodeIDs;
319  delete [] numFieldsPerNode;
320  for(int jj=0; jj<nodesPerElem; ++jj) {
321  delete [] fieldIDsTable[jj];
322  }
323  delete [] fieldIDsTable;
324 
325  return(0);
326 }
327 
328 int init_shared_nodes(FEI* fei, HexBeam& hexcube)
329 {
330  int numSharedNodes = hexcube.getNumSharedNodes();
331  if (numSharedNodes == 0) {
332  return(0);
333  }
334 
335  int* sharedNodes = NULL;
336  int* numSharingProcsPerNode = NULL;
337  int** sharingProcs = NULL;
338  if (numSharedNodes > 0) {
339  CHK_ERR( hexcube.getSharedNodes(numSharedNodes,
340  sharedNodes, numSharingProcsPerNode,
341  sharingProcs) );
342  }
343 
344  CHK_ERR( fei->initSharedNodes(numSharedNodes, sharedNodes,
345  numSharingProcsPerNode, sharingProcs) );
346 
347  delete [] sharedNodes;
348  delete [] numSharingProcsPerNode;
349  delete [] sharingProcs[0];
350  delete [] sharingProcs;
351 
352  return(0);
353 }
354 
355 int init_constraints(FEI* fei, HexBeam& hexcube, int& firstLocalCRID)
356 {
357  int numCRs = hexcube.getNumCRs();
358  if (numCRs < 1) {
359  return(0);
360  }
361 
362  int numNodesPerCR = hexcube.getNumNodesPerCR();
363  int* crnodes_1d = new int[numCRs*numNodesPerCR];
364  int** crNodes = new int*[numCRs];
365  int i, offset = 0;
366  for(i=0; i<numCRs; ++i) {
367  crNodes[i] = &(crnodes_1d[offset]);
368  offset += numNodesPerCR;
369  }
370 
371  CHK_ERR( hexcube.getCRNodes(crNodes) );
372 
373  int crID;
374  int* fieldIDs = new int[numNodesPerCR];
375  for(i=0; i<numNodesPerCR; ++i) fieldIDs[i] = 0;
376 
377  for(i=0; i<numCRs; ++i) {
378  CHK_ERR( fei->initCRMult(numNodesPerCR, crNodes[i], fieldIDs, crID) );
379 // FEI_COUT << "crID: " << crID << ", nodes: ";
380 // for(int j=0; j<numNodesPerCR; ++j) {
381 // FEI_COUT << crNodes[i][j] << " ";
382 // }
383 // FEI_COUT << FEI_ENDL;
384 
385  if (i == 0) {
386  firstLocalCRID = crID;
387  }
388  }
389 
390  delete [] crnodes_1d;
391  delete [] crNodes;
392  delete [] fieldIDs;
393 
394  return(0);
395 }
396 
397 int load_constraints(FEI* fei, HexBeam& hexcube, int firstLocalCRID)
398 {
399  int numCRs = hexcube.getNumCRs();
400  if (numCRs < 1) {
401  return(0);
402  }
403 
404  int numNodesPerCR = hexcube.getNumNodesPerCR();
405  int* crnodes_1d = new int[numCRs*numNodesPerCR];
406  int** crNodes = new int*[numCRs];
407  int i, offset = 0;
408  for(i=0; i<numCRs; ++i) {
409  crNodes[i] = &(crnodes_1d[offset]);
410  offset += numNodesPerCR;
411  }
412 
413  CHK_ERR( hexcube.getCRNodes(crNodes) );
414 
415  int* fieldIDs = new int[numNodesPerCR];
416  for(i=0; i<numNodesPerCR; ++i) fieldIDs[i] = 0;
417 
418  int fieldSize = hexcube.numDofPerNode();
419  double* weights = new double[fieldSize*numNodesPerCR];
420 
421  for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
422  weights[0] = -1.0;
423  weights[fieldSize] = 1.0;
424  double rhsValue = 0.0;
425 
426  for(i=0; i<numCRs; ++i) {
427  CHK_ERR( fei->loadCRMult(firstLocalCRID+i,
428  numNodesPerCR, crNodes[i], fieldIDs,
429  weights, rhsValue) );
430  }
431 
432  delete [] crnodes_1d;
433  delete [] crNodes;
434  delete [] fieldIDs;
435  delete [] weights;
436 
437  return(0);
438 }
439 
440 int load_elem_data(FEI* fei, HexBeam& hexcube)
441 {
442  int blockID = 0;
443  int numLocalElems = hexcube.localNumElems_;
444  int firstLocalElem = hexcube.firstLocalElem_;
445  int nodesPerElem = hexcube.numNodesPerElem();
446  int fieldSize = hexcube.numDofPerNode();
447 
448  int len = nodesPerElem*fieldSize;
449  double* elemMat = new double[len*len];
450  double** elemMat2D = new double*[len];
451  double* elemVec = new double[len];
452 
453  int* nodeIDs = new int[nodesPerElem];
454 
455  if (elemMat == NULL || elemMat2D == NULL || elemVec == NULL ||
456  nodeIDs == NULL) {
457  return(-1);
458  }
459 
460  for(int j=0; j<len; ++j) {
461  elemMat2D[j] = &(elemMat[j*len]);
462  }
463 
464  CHK_ERR( hexcube.getElemStiffnessMatrix(firstLocalElem, elemMat) );
465  CHK_ERR( hexcube.getElemLoadVector(firstLocalElem, elemVec) );
466 
467  for(int i=0; i<numLocalElems; ++i) {
468  CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
469 
470  CHK_ERR( fei->sumInElemMatrix(blockID, firstLocalElem+i,
471  nodeIDs, elemMat2D, FEI_DENSE_ROW) );
472 
473  CHK_ERR( fei->sumInElemRHS(blockID, firstLocalElem+i, nodeIDs, elemVec) );
474  }
475 
476  delete [] elemMat;
477  delete [] elemMat2D;
478  delete [] elemVec;
479  delete [] nodeIDs;
480 
481  return(0);
482 }
483 
484 int load_BC_data(FEI* fei, HexBeam& hexcube)
485 {
486  int numBCNodes = hexcube.getNumBCNodes();
487  if (numBCNodes == 0) {
488  return(0);
489  }
490 
491  int* nodeIDs = new int[numBCNodes];
492 
493  int fieldID = 0;
494 
495  int* offsetsIntoField = new int[numBCNodes];
496  double* prescribed_vals = new double[numBCNodes];
497 
498  CHK_ERR( hexcube.getBCNodes(numBCNodes, nodeIDs) );
499 
500  CHK_ERR( hexcube.getBCValues(numBCNodes, offsetsIntoField, prescribed_vals) );
501 
502  CHK_ERR( fei->loadNodeBCs(numBCNodes, nodeIDs,
503  fieldID, offsetsIntoField, prescribed_vals) );
504 
505  delete [] nodeIDs;
506  delete [] offsetsIntoField;
507  delete [] prescribed_vals;
508 
509  return(0);
510 }
511 
512 int init_elem_connectivities(fei::MatrixGraph* matrixGraph, HexBeam& hexcube)
513 {
514  int numLocalElems = hexcube.localNumElems_;
515  int firstLocalElem = hexcube.firstLocalElem_;
516  int nodesPerElem = hexcube.numNodesPerElem();
517  int fieldID = 0;
518 // int fieldSize = hexcube.numDofPerNode();
519  int nodeIDType = 0;
520 
521 
522  int patternID = 0;
523 // if (fieldSize > 1) {
524  patternID = matrixGraph->definePattern(nodesPerElem,
525  nodeIDType, fieldID);
526 // }
527 // else {
528 // //if fieldSize == 1, let's not even bother associating a field with
529 // //our mesh-nodes. fei:: objects assume that identifiers without an
530 // //associated field always have exactly one degree-of-freedom.
531 // //
532 // patternID = matrixGraph->definePattern(nodesPerElem, nodeIDType);
533 // }
534 
535  int blockID = 0;
536  CHK_ERR( matrixGraph->initConnectivityBlock(blockID, numLocalElems, patternID));
537 
538  int* nodeIDs = new int[nodesPerElem];
539  if (nodeIDs == NULL) return(-1);
540 
541  for(int i=0; i<numLocalElems; ++i) {
542  CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
543 
544  CHK_ERR( matrixGraph->initConnectivity(blockID, firstLocalElem+i, nodeIDs) );
545  }
546 
547  delete [] nodeIDs;
548 
549  return(0);
550 }
551 
552 int init_shared_nodes(fei::MatrixGraph* matrixGraph, HexBeam& hexcube)
553 {
554  int numSharedNodes = hexcube.getNumSharedNodes();
555  if (numSharedNodes == 0) {
556  return(0);
557  }
558 
559  int* sharedNodes = NULL;
560  int* numSharingProcsPerNode = NULL;
561  int** sharingProcs = NULL;
562  if (numSharedNodes > 0) {
563  CHK_ERR( hexcube.getSharedNodes(numSharedNodes,
564  sharedNodes, numSharingProcsPerNode,
565  sharingProcs) );
566  }
567 
568  fei::SharedPtr<fei::VectorSpace> nodeSpace = matrixGraph->getRowSpace();
569 
570  int nodeIDType = 0;
571 
572  CHK_ERR( nodeSpace->initSharedIDs(numSharedNodes, nodeIDType,
573  sharedNodes, numSharingProcsPerNode,
574  sharingProcs) );
575 
576  delete [] sharedNodes;
577  delete [] numSharingProcsPerNode;
578  delete [] sharingProcs[0];
579  delete [] sharingProcs;
580 
581  return(0);
582 }
583 
584 int init_constraints(fei::MatrixGraph* matrixGraph, HexBeam& hexcube,
585  int localProc, int& firstLocalCRID)
586 {
587  int numCRs = hexcube.getNumCRs();
588  if (numCRs < 1) {
589  return(0);
590  }
591 
592  int numNodesPerCR = hexcube.getNumNodesPerCR();
593  int* crnodes_1d = new int[numCRs*numNodesPerCR];
594  int** crNodes = new int*[numCRs];
595  int i, offset = 0;
596  for(i=0; i<numCRs; ++i) {
597  crNodes[i] = &(crnodes_1d[offset]);
598  offset += numNodesPerCR;
599  }
600 
601  CHK_ERR( hexcube.getCRNodes(crNodes) );
602 
603  int crID = localProc*100000;
604  firstLocalCRID = crID;
605 
606  int nodeIDType = 0;
607  int crIDType = 1;
608 
609  int* fieldIDs = new int[numNodesPerCR];
610  int* idTypes = new int[numNodesPerCR];
611  for(i=0; i<numNodesPerCR; ++i) {
612  fieldIDs[i] = 0;
613  idTypes[i] = nodeIDType;
614  }
615 
616  for(i=0; i<numCRs; ++i) {
617  CHK_ERR( matrixGraph->initLagrangeConstraint(crID+i, crIDType,
618  numNodesPerCR,
619  idTypes, crNodes[i],
620  fieldIDs) );
621 // FEI_COUT << "crID: " << crID << ", nodes: ";
622 // for(int j=0; j<numNodesPerCR; ++j) {
623 // FEI_COUT << crNodes[i][j] << " ";
624 // }
625 // FEI_COUT << FEI_ENDL;
626 
627  }
628 
629  delete [] crnodes_1d;
630  delete [] crNodes;
631  delete [] fieldIDs;
632 
633  return(0);
634 }
635 
636 int init_slave_constraints(fei::MatrixGraph* matrixGraph, HexBeam& hexcube)
637 {
638  int numCRs = hexcube.getNumCRs();
639  if (numCRs < 1) {
640  return(0);
641  }
642 
643  int numNodesPerCR = hexcube.getNumNodesPerCR();
644  int* crnodes_1d = new int[numCRs*numNodesPerCR];
645  int** crNodes = new int*[numCRs];
646  int i, offset = 0;
647  for(i=0; i<numCRs; ++i) {
648  crNodes[i] = &(crnodes_1d[offset]);
649  offset += numNodesPerCR;
650  }
651 
652  CHK_ERR( hexcube.getCRNodes(crNodes) );
653 
654  int nodeIDType = 0;
655 
656  int* fieldIDs = new int[numNodesPerCR];
657  int* idTypes = new int[numNodesPerCR];
658  for(i=0; i<numNodesPerCR; ++i) {
659  fieldIDs[i] = 0;
660  idTypes[i] = nodeIDType;
661  }
662 
663  int fieldSize = hexcube.numDofPerNode();
664  double* weights = new double[fieldSize*numNodesPerCR];
665 
666  for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
667  weights[0] = -1.0;
668  weights[fieldSize] = 1.0;
669  double rhsValue = 0.0;
670  int offsetOfSlave = 0;
671  int offsetIntoSlaveField = 0;
672 
673  for(i=0; i<numCRs; ++i) {
674  CHK_ERR( matrixGraph->initSlaveConstraint(numNodesPerCR,
675  idTypes,
676  crNodes[i],
677  fieldIDs,
678  offsetOfSlave,
679  offsetIntoSlaveField,
680  weights,
681  rhsValue) );
682  }
683 
684  delete [] crnodes_1d;
685  delete [] crNodes;
686  delete [] fieldIDs;
687  delete [] weights;
688 
689  return(0);
690 }
691 
692 int load_elem_data(fei::MatrixGraph* matrixGraph,
693  fei::Matrix* mat,
694  fei::Vector* rhs,
695  HexBeam& hexcube)
696 {
697  int blockID = 0;
698  int numLocalElems = hexcube.localNumElems_;
699  int firstLocalElem = hexcube.firstLocalElem_;
700  int nodesPerElem = hexcube.numNodesPerElem();
701  int fieldSize = hexcube.numDofPerNode();
702 
703  int len = nodesPerElem*fieldSize;
704  double* elemMat = new double[len*len];
705  double** elemMat2D = new double*[len];
706  double* elemVec = new double[len];
707 
708  if (elemMat == NULL || elemMat2D == NULL || elemVec == NULL) {
709  return(-1);
710  }
711 
712  for(int j=0; j<len; ++j) {
713  elemMat2D[j] = &(elemMat[j*len]);
714  }
715 
716  CHK_ERR( hexcube.getElemStiffnessMatrix(firstLocalElem, elemMat) );
717  CHK_ERR( hexcube.getElemLoadVector(firstLocalElem, elemVec) );
718 
719  bool block_matrix = mat->usingBlockEntryStorage();
720  std::vector<int> indices(len);
721 
722  if (block_matrix) {
723  mat->getMatrixGraph()->setIndicesMode(fei::MatrixGraph::POINT_ENTRY_GRAPH);
724  }
725 
726  for(int i=0; i<numLocalElems; ++i) {
727  CHK_ERR( mat->getMatrixGraph()->getConnectivityIndices(blockID,
728  firstLocalElem+i,
729  len, &indices[0],
730  len) );
731  CHK_ERR( mat->sumIn(len, &indices[0], len, &indices[0],
732  elemMat2D, FEI_DENSE_COL) );
733  CHK_ERR( rhs->sumIn(len, &indices[0], elemVec, 0) );
734  }
735 
736  if (block_matrix) {
737  mat->getMatrixGraph()->setIndicesMode(fei::MatrixGraph::BLOCK_ENTRY_GRAPH);
738  }
739  delete [] elemMat;
740  delete [] elemMat2D;
741  delete [] elemVec;
742 
743  return(0);
744 }
745 
746 int load_constraints(fei::LinearSystem* linSys, HexBeam& hexcube,
747  int firstLocalCRID)
748 {
749  int numCRs = hexcube.getNumCRs();
750  if (numCRs < 1) {
751  return(0);
752  }
753 
754  int numNodesPerCR = hexcube.getNumNodesPerCR();
755 
756  int fieldSize = hexcube.numDofPerNode();
757  double* weights = new double[fieldSize*numNodesPerCR];
758 
759  int i;
760  for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
761  weights[0] = -1.0;
762  weights[fieldSize] = 1.0;
763  double rhsValue = 0.0;
764 
765  for(i=0; i<numCRs; ++i) {
766  CHK_ERR( linSys->loadLagrangeConstraint(firstLocalCRID+i,
767  weights, rhsValue) );
768  }
769 
770  delete [] weights;
771 
772  return(0);
773 }
774 
775 int load_BC_data(fei::LinearSystem* linSys, HexBeam& hexcube)
776 {
777  int numBCNodes = hexcube.getNumBCNodes();
778  if (numBCNodes == 0) {
779  return(0);
780  }
781 
782  int* nodeIDs = new int[numBCNodes];
783 
784  int fieldID = 0;
785  int nodeIDType = 0;
786 
787  int* offsetsIntoField = new int[numBCNodes];
788  double* prescribed_vals = new double[numBCNodes];
789 
790  CHK_ERR( hexcube.getBCNodes(numBCNodes, nodeIDs) );
791 
792  CHK_ERR( hexcube.getBCValues(numBCNodes, offsetsIntoField, prescribed_vals) );
793 
794  CHK_ERR( linSys->loadEssentialBCs(numBCNodes, nodeIDs,
795  nodeIDType, fieldID,
796  offsetsIntoField, prescribed_vals) );
797 
798  delete [] offsetsIntoField;
799  delete [] prescribed_vals;
800  delete [] nodeIDs;
801 
802  return(0);
803 }
804 
805 }//namespace HexBeam_Functions
virtual void setIndicesMode(int mode)=0
int initSharedIDs(int numShared, int idType, const int *sharedIDs, const int *numSharingProcsPerID, const int *sharingProcs)
virtual int sumInElemMatrix(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *const *elemStiffness, int elemFormat)=0
virtual int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
virtual int loadLagrangeConstraint(int constraintID, const double *weights, double rhsValue)=0
virtual bool usingBlockEntryStorage()=0
virtual int loadNodeBCs(int numNodes, const GlobalID *nodeIDs, int fieldID, const int *offsetsIntoField, const double *prescribedValues)=0
virtual int initLagrangeConstraint(int constraintID, int constraintIDType, int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs)=0
virtual int initSlaveConstraint(int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs, int offsetOfSlave, int offsetIntoSlaveField, const double *weights, double rhsValue)=0
virtual int loadCRMult(int CRMultID, int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, const double *CRWeights, double CRValue)=0
virtual int initCRMult(int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, int &CRID)=0
Definition: FEI.hpp:144
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
virtual int initConnectivity(int blockID, int connectivityID, const int *connectedIdentifiers)=0
virtual int initSharedNodes(int numSharedNodes, const GlobalID *sharedNodeIDs, const int *numProcsPerNode, const int *const *sharingProcIDs)=0
virtual int initElemBlock(GlobalID elemBlockID, int numElements, int numNodesPerElement, const int *numFieldsPerNode, const int *const *nodalFieldIDs, int numElemDofFieldsPerElement, const int *elemDOFFieldIDs, int interleaveStrategy)=0
virtual int sumIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
virtual int getConnectivityIndices(int blockID, int connectivityID, int indicesAllocLen, int *indices, int &numIndices)=0
virtual int sumIn(int numValues, const int *indices, const double *values, int vectorIndex=0)=0
virtual fei::SharedPtr< fei::MatrixGraph > getMatrixGraph() const =0
std::ostream & console_out()
virtual int sumInElemRHS(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *elemLoad)=0
virtual int definePattern(int numIDs, int idType)=0
virtual int initElem(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn)=0
virtual int initConnectivityBlock(int blockID, int numConnectivityLists, int patternID, bool diagonal=false)=0