99 #include "Intrepid_HGRAD_HEX_C1_FEM.hpp"
106 #include "Epetra_Time.h"
107 #include "Epetra_Map.h"
108 #include "Epetra_SerialComm.h"
109 #include "Epetra_FECrsMatrix.h"
110 #include "Epetra_FEVector.h"
111 #include "Epetra_Vector.h"
114 #include "Teuchos_oblackholestream.hpp"
115 #include "Teuchos_RCP.hpp"
116 #include "Teuchos_BLAS.hpp"
119 #include "Shards_CellTopology.hpp"
122 #include "EpetraExt_RowMatrixOut.h"
123 #include "EpetraExt_MultiVectorOut.h"
126 using namespace Intrepid;
129 int evalu(
double & uExact0,
double & uExact1,
double & uExact2,
double & x,
double & y,
double & z);
130 double evalDivu(
double & x,
double & y,
double & z);
131 int evalCurlu(
double & curlu0,
double & curlu1,
double & curlu2,
double & x,
double & y,
double & z);
132 int evalCurlCurlu(
double & curlCurlu0,
double & curlCurlu1,
double & curlCurlu2,
double & x,
double & y,
double & z);
134 int main(
int argc,
char *argv[]) {
138 std::cout <<
"\n>>> ERROR: Invalid number of arguments.\n\n";
139 std::cout <<
"Usage:\n\n";
140 std::cout <<
" ./Intrepid_example_Drivers_Example_02.exe NX NY NZ randomMesh mu1 mu2 mu1LX mu1RX mu1LY mu1RY mu1LZ mu1RZ verbose\n\n";
141 std::cout <<
" where \n";
142 std::cout <<
" int NX - num intervals in x direction (assumed box domain, -1,1) \n";
143 std::cout <<
" int NY - num intervals in y direction (assumed box domain, -1,1) \n";
144 std::cout <<
" int NZ - num intervals in z direction (assumed box domain, -1,1) \n";
145 std::cout <<
" int randomMesh - 1 if mesh randomizer is to be used 0 if not \n";
146 std::cout <<
" double mu1 - material property value for region 1 \n";
147 std::cout <<
" double mu2 - material property value for region 2 \n";
148 std::cout <<
" double mu1LX - left X boundary for region 1 \n";
149 std::cout <<
" double mu1RX - right X boundary for region 1 \n";
150 std::cout <<
" double mu1LY - left Y boundary for region 1 \n";
151 std::cout <<
" double mu1RY - right Y boundary for region 1 \n";
152 std::cout <<
" double mu1LZ - bottom Z boundary for region 1 \n";
153 std::cout <<
" double mu1RZ - top Z boundary for region 1 \n";
154 std::cout <<
" verbose (optional) - any character, indicates verbose output \n\n";
160 int iprint = argc - 1;
161 Teuchos::RCP<std::ostream> outStream;
162 Teuchos::oblackholestream bhs;
164 outStream = Teuchos::rcp(&std::cout,
false);
166 outStream = Teuchos::rcp(&bhs,
false);
169 Teuchos::oblackholestream oldFormatState;
170 oldFormatState.copyfmt(std::cout);
173 <<
"===============================================================================\n" \
175 <<
"| Example: Generate Mass and Stiffness Matrices and Right-Hand Side Vector |\n"
176 <<
"| for Div-Curl System on Hexahedral Mesh with Div-Conforming Elements |\n" \
178 <<
"| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" \
179 <<
"| Denis Ridzal (dridzal@sandia.gov), |\n" \
180 <<
"| Kara Peterson (kjpeter@sandia.gov). |\n" \
182 <<
"| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
183 <<
"| Trilinos website: http://trilinos.sandia.gov |\n" \
185 <<
"===============================================================================\n";
194 int NX = atoi(argv[1]);
195 int NY = atoi(argv[2]);
196 int NZ = atoi(argv[3]);
197 int randomMesh = atoi(argv[4]);
198 double mu1 = atof(argv[5]);
199 double mu2 = atof(argv[6]);
200 double mu1LeftX = atof(argv[7]);
201 double mu1RightX = atof(argv[8]);
202 double mu1LeftY = atof(argv[9]);
203 double mu1RightY = atof(argv[10]);
204 double mu1LeftZ = atof(argv[11]);
205 double mu1RightZ = atof(argv[12]);
210 typedef shards::CellTopology CellTopology;
211 CellTopology hex_8(shards::getCellTopologyData<shards::Hexahedron<8> >() );
214 int numNodesPerElem = hex_8.getNodeCount();
215 int numEdgesPerElem = hex_8.getEdgeCount();
216 int numFacesPerElem = hex_8.getSideCount();
217 int numNodesPerEdge = 2;
218 int numNodesPerFace = 4;
219 int numEdgesPerFace = 4;
220 int spaceDim = hex_8.getDimension();
224 for (
int i=0; i<numEdgesPerElem; i++){
225 refEdgeToNode(i,0)=hex_8.getNodeMap(1, i, 0);
226 refEdgeToNode(i,1)=hex_8.getNodeMap(1, i, 1);
231 for (
int i=0; i<numFacesPerElem; i++){
232 refFaceToNode(i,0)=hex_8.getNodeMap(2, i, 0);
233 refFaceToNode(i,1)=hex_8.getNodeMap(2, i, 1);
234 refFaceToNode(i,2)=hex_8.getNodeMap(2, i, 2);
235 refFaceToNode(i,3)=hex_8.getNodeMap(2, i, 3);
240 *outStream <<
"Generating mesh ... \n\n";
242 *outStream <<
" NX" <<
" NY" <<
" NZ\n";
243 *outStream << std::setw(5) << NX <<
244 std::setw(5) << NY <<
245 std::setw(5) << NZ <<
"\n\n";
248 int numElems = NX*NY*NZ;
249 int numNodes = (NX+1)*(NY+1)*(NZ+1);
250 int numEdges = (NX)*(NY + 1)*(NZ + 1) + (NX + 1)*(NY)*(NZ + 1) + (NX + 1)*(NY + 1)*(NZ);
251 int numFaces = (NX)*(NY)*(NZ + 1) + (NX)*(NY + 1)*(NZ) + (NX + 1)*(NY)*(NZ);
252 *outStream <<
" Number of Elements: " << numElems <<
" \n";
253 *outStream <<
" Number of Nodes: " << numNodes <<
" \n";
254 *outStream <<
" Number of Edges: " << numEdges <<
" \n";
255 *outStream <<
" Number of Faces: " << numFaces <<
" \n\n";
258 double leftX = -1.0, rightX = 1.0;
259 double leftY = -1.0, rightY = 1.0;
260 double leftZ = -1.0, rightZ = 1.0;
263 double hx = (rightX-leftX)/((
double)NX);
264 double hy = (rightY-leftY)/((
double)NY);
265 double hz = (rightZ-leftZ)/((
double)NZ);
271 for (
int k=0; k<NZ+1; k++) {
272 for (
int j=0; j<NY+1; j++) {
273 for (
int i=0; i<NX+1; i++) {
274 nodeCoord(inode,0) = leftX + (double)i*hx;
275 nodeCoord(inode,1) = leftY + (double)j*hy;
276 nodeCoord(inode,2) = leftZ + (double)k*hz;
277 if (k==0 || j==0 || i==0 || k==NZ || j==NY || i==NX){
278 nodeOnBoundary(inode)=1;
288 for (
int k=0; k<NZ; k++) {
289 for (
int j=0; j<NY; j++) {
290 for (
int i=0; i<NX; i++) {
291 elemToNode(ielem,0) = (NY + 1)*(NX + 1)*k + (NX + 1)*j + i;
292 elemToNode(ielem,1) = (NY + 1)*(NX + 1)*k + (NX + 1)*j + i + 1;
293 elemToNode(ielem,2) = (NY + 1)*(NX + 1)*k + (NX + 1)*(j + 1) + i + 1;
294 elemToNode(ielem,3) = (NY + 1)*(NX + 1)*k + (NX + 1)*(j + 1) + i;
295 elemToNode(ielem,4) = (NY + 1)*(NX + 1)*(k + 1) + (NX + 1)*j + i;
296 elemToNode(ielem,5) = (NY + 1)*(NX + 1)*(k + 1) + (NX + 1)*j + i + 1;
297 elemToNode(ielem,6) = (NY + 1)*(NX + 1)*(k + 1) + (NX + 1)*(j + 1) + i + 1;
298 elemToNode(ielem,7) = (NY + 1)*(NX + 1)*(k + 1) + (NX + 1)*(j + 1) + i;
309 for (
int k=0; k<NZ+1; k++) {
310 for (
int j=0; j<NY+1; j++) {
311 for (
int i=0; i<NX+1; i++) {
313 edgeToNode(iedge,0) = inode;
314 edgeToNode(iedge,1) = inode + 1;
315 if (j < NY && k < NZ){
316 ielem=i+j*NX+k*NX*NY;
317 elemToEdge(ielem,0) = iedge;
319 elemToEdge(ielem-NX,2) = iedge;
321 elemToEdge(ielem-NX*NY,4) = iedge;
323 elemToEdge(ielem-NX*NY-NX,6) = iedge;
325 else if (j == NY && k == NZ){
326 ielem=i+(NY-1)*NX+(NZ-1)*NX*NY;
327 elemToEdge(ielem,6) = iedge;
329 else if (k == NZ && j < NY){
330 ielem=i+j*NX+(NZ-1)*NX*NY;
331 elemToEdge(ielem,4) = iedge;
333 elemToEdge(ielem-NX,6) = iedge;
335 else if (k < NZ && j == NY){
336 ielem=i+(NY-1)*NX+k*NX*NY;
337 elemToEdge(ielem,2) = iedge;
339 elemToEdge(ielem-NX*NY,6) = iedge;
344 edgeToNode(iedge,0) = inode;
345 edgeToNode(iedge,1) = inode + NX+1;
346 if (i < NX && k < NZ){
347 ielem=i+j*NX+k*NX*NY;
348 elemToEdge(ielem,3) = iedge;
350 elemToEdge(ielem-1,1) = iedge;
352 elemToEdge(ielem-NX*NY,7) = iedge;
354 elemToEdge(ielem-NX*NY-1,5) = iedge;
356 else if (i == NX && k == NZ){
357 ielem=NX-1+j*NX+(NZ-1)*NX*NY;
358 elemToEdge(ielem,5) = iedge;
360 else if (k == NZ && i < NX){
361 ielem=i+j*NX+(NZ-1)*NX*NY;
362 elemToEdge(ielem,7) = iedge;
364 elemToEdge(ielem-1,5) = iedge;
366 else if (k < NZ && i == NX){
367 ielem=NX-1+j*NX+k*NX*NY;
368 elemToEdge(ielem,1) = iedge;
370 elemToEdge(ielem-NX*NY,5) = iedge;
375 edgeToNode(iedge,0) = inode;
376 edgeToNode(iedge,1) = inode + (NX+1)*(NY+1);
377 if (i < NX && j < NY){
378 ielem=i+j*NX+k*NX*NY;
379 elemToEdge(ielem,8) = iedge;
381 elemToEdge(ielem-1,9) = iedge;
383 elemToEdge(ielem-NX,11) = iedge;
385 elemToEdge(ielem-NX-1,10) = iedge;
387 else if (i == NX && j == NY){
388 ielem=NX-1+(NY-1)*NX+k*NX*NY;
389 elemToEdge(ielem,10) = iedge;
391 else if (j == NY && i < NX){
392 ielem=i+(NY-1)*NX+k*NX*NY;
393 elemToEdge(ielem,11) = iedge;
395 elemToEdge(ielem-1,10) = iedge;
397 else if (j < NY && i == NX){
398 ielem=NX-1+j*NX+k*NX*NY;
399 elemToEdge(ielem,9) = iedge;
401 elemToEdge(ielem-NX,10) = iedge;
412 for (
int i=0; i<numEdges; i++){
413 if (nodeOnBoundary(edgeToNode(i,0)) && nodeOnBoundary(edgeToNode(i,1))){
424 for (
int k=0; k<NZ+1; k++) {
425 for (
int j=0; j<NY+1; j++) {
426 for (
int i=0; i<NX+1; i++) {
427 if (i < NX && k < NZ) {
428 faceToNode(iface,0)=inode;
429 faceToNode(iface,1)=inode + 1;
430 faceToNode(iface,2)=inode + (NX+1)*(NY+1)+1;
431 faceToNode(iface,3)=inode + (NX+1)*(NY+1);
433 ielem=i+j*NX+k*NX*NY;
434 faceToEdge(iface,0)=elemToEdge(ielem,0);
435 faceToEdge(iface,1)=elemToEdge(ielem,9);
436 faceToEdge(iface,2)=elemToEdge(ielem,4);
437 faceToEdge(iface,3)=elemToEdge(ielem,8);
438 elemToFace(ielem,0)=iface;
440 elemToFace(ielem-NX,2)=iface;
444 ielem=i+(NY-1)*NX+k*NX*NY;
445 faceToEdge(iface,0)=elemToEdge(ielem,2);
446 faceToEdge(iface,1)=elemToEdge(ielem,10);
447 faceToEdge(iface,2)=elemToEdge(ielem,6);
448 faceToEdge(iface,3)=elemToEdge(ielem,11);
449 elemToFace(ielem,2)=iface;
453 if (j < NY && k < NZ) {
454 faceToNode(iface,0)=inode;
455 faceToNode(iface,1)=inode + NX+1;
456 faceToNode(iface,2)=inode + (NX+1)*(NY+1) + NX+1;
457 faceToNode(iface,3)=inode + (NX+1)*(NY+1);
459 ielem=i+j*NX+k*NX*NY;
460 faceToEdge(iface,0)=elemToEdge(ielem,3);
461 faceToEdge(iface,1)=elemToEdge(ielem,11);
462 faceToEdge(iface,2)=elemToEdge(ielem,7);
463 faceToEdge(iface,3)=elemToEdge(ielem,8);
464 elemToFace(ielem,3)=iface;
466 elemToFace(ielem-1,1)=iface;
470 ielem=NX-1+j*NX+k*NX*NY;
471 faceToEdge(iface,0)=elemToEdge(ielem,1);
472 faceToEdge(iface,1)=elemToEdge(ielem,10);
473 faceToEdge(iface,2)=elemToEdge(ielem,5);
474 faceToEdge(iface,3)=elemToEdge(ielem,9);
475 elemToFace(ielem,1)=iface;
479 if (i < NX && j < NY) {
480 faceToNode(iface,0)=inode;
481 faceToNode(iface,1)=inode + 1;
482 faceToNode(iface,2)=inode + NX+2;
483 faceToNode(iface,3)=inode + NX+1;
485 ielem=i+j*NX+k*NX*NY;
486 faceToEdge(iface,0)=elemToEdge(ielem,0);
487 faceToEdge(iface,1)=elemToEdge(ielem,1);
488 faceToEdge(iface,2)=elemToEdge(ielem,2);
489 faceToEdge(iface,3)=elemToEdge(ielem,3);
490 elemToFace(ielem,4)=iface;
492 elemToFace(ielem-NX*NY,5)=iface;
496 ielem=i+j*NX+(NZ-1)*NX*NY;
497 faceToEdge(iface,0)=elemToEdge(ielem,4);
498 faceToEdge(iface,1)=elemToEdge(ielem,5);
499 faceToEdge(iface,2)=elemToEdge(ielem,6);
500 faceToEdge(iface,3)=elemToEdge(ielem,7);
501 elemToFace(ielem,5)=iface;
512 for (
int i=0; i<numFaces; i++){
513 if (nodeOnBoundary(faceToNode(i,0)) && nodeOnBoundary(faceToNode(i,1))
514 && nodeOnBoundary(faceToNode(i,2)) && nodeOnBoundary(faceToNode(i,3))){
522 ofstream fe2nout(
"elem2node.dat");
523 ofstream fe2fout(
"elem2face.dat");
524 for (
int k=0; k<NZ; k++) {
525 for (
int j=0; j<NY; j++) {
526 for (
int i=0; i<NX; i++) {
527 ielem = i + j * NX + k * NX * NY;
528 for (
int m=0; m<numNodesPerElem; m++){
529 fe2nout << elemToNode(ielem,m) <<
" ";
532 for (
int n=0; n<numFacesPerElem; n++) {
533 fe2fout << elemToFace(ielem,n) <<
" ";
543 #ifdef DUMP_DATA_EXTRA
544 ofstream ff2nout(
"face2node.dat");
545 ofstream ff2eout(
"face2edge.dat");
546 for (
int i=0; i<numFaces; i++) {
547 for (
int j=0; j<numNodesPerFace; j++) {
548 ff2nout << faceToNode(i,j) <<
" ";
550 for (
int k=0; k<numEdgesPerFace; k++) {
551 ff2eout << faceToEdge(i,k) <<
" ";
559 ofstream fBnodeout(
"nodeOnBndy.dat");
560 ofstream fBfaceout(
"faceOnBndy.dat");
561 for (
int i=0; i<numNodes; i++) {
562 fBnodeout << nodeOnBoundary(i) <<
"\n";
564 for (
int i=0; i<numFaces; i++) {
565 fBfaceout << faceOnBoundary(i) <<
"\n";
573 for (
int k=0; k<NZ; k++) {
574 for (
int j=0; j<NY; j++) {
575 for (
int i=0; i<NX; i++) {
576 ielem = i + j * NX + k * NX * NY;
577 double midElemX = nodeCoord(elemToNode(ielem,0),0) + hx/2.0;
578 double midElemY = nodeCoord(elemToNode(ielem,0),1) + hy/2.0;
579 double midElemZ = nodeCoord(elemToNode(ielem,0),2) + hz/2.0;
580 if ( (midElemX > mu1LeftX) && (midElemY > mu1LeftY) && (midElemZ > mu1LeftZ) &&
581 (midElemX <= mu1RightX) && (midElemY <= mu1RightY) && (midElemZ <= mu1RightZ) ){
593 for (
int k=1; k<NZ; k++) {
594 for (
int j=1; j<NY; j++) {
595 for (
int i=1; i<NX; i++) {
596 int inode = i + j * (NX + 1) + k * (NX + 1) * (NY + 1);
598 double rx = 2.0 * (double)rand()/RAND_MAX - 1.0;
599 double ry = 2.0 * (double)rand()/RAND_MAX - 1.0;
600 double rz = 2.0 * (double)rand()/RAND_MAX - 1.0;
602 nodeCoord(inode,0) = nodeCoord(inode,0) + 0.125 * hx * rx;
603 nodeCoord(inode,1) = nodeCoord(inode,1) + 0.125 * hy * ry;
604 nodeCoord(inode,2) = nodeCoord(inode,2) + 0.125 * hz * rz;
612 ofstream fcoordout(
"coords.dat");
613 for (
int i=0; i<numNodes; i++) {
614 fcoordout << nodeCoord(i,0) <<
" ";
615 fcoordout << nodeCoord(i,1) <<
" ";
616 fcoordout << nodeCoord(i,2) <<
"\n";
625 *outStream <<
"Building incidence matrix ... \n\n";
627 Epetra_SerialComm Comm;
628 Epetra_Map globalMapD(numFaces, 0, Comm);
629 Epetra_Map globalMapC(numEdges, 0, Comm);
630 Epetra_FECrsMatrix DCurl(Copy, globalMapD, globalMapC, 2);
633 vals[0]=1.0; vals[1]=1.0; vals[2]=-1.0; vals[3]=-1.0;
634 for (
int j=0; j<numFaces; j++){
637 colNum[0] = faceToEdge(j,0);
638 colNum[1] = faceToEdge(j,1);
639 colNum[2] = faceToEdge(j,2);
640 colNum[3] = faceToEdge(j,3);
641 DCurl.InsertGlobalValues(1, &rowNum, 4, colNum, vals);
648 *outStream <<
"Getting cubature ... \n\n";
652 Teuchos::RCP<Cubature<double> > hexCub = cubFactory.
create(hex_8, cubDegree);
654 int cubDim = hexCub->getDimension();
655 int numCubPoints = hexCub->getNumPoints();
660 hexCub->getCubature(cubPoints, cubWeights);
667 CellTopology paramQuadFace(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
671 Teuchos::RCP<Cubature<double> > hexFaceCubature = cubFactoryFace.
create(paramQuadFace, 3);
672 int cubFaceDim = hexFaceCubature -> getDimension();
673 int numFacePoints = hexFaceCubature -> getNumPoints();
680 hexFaceCubature -> getCubature(paramGaussPoints, paramGaussWeights);
687 *outStream <<
"Getting basis ... \n\n";
700 hexHCurlBasis.
getValues(hexCVals, cubPoints, OPERATOR_VALUE);
701 hexHDivBasis.
getValues(hexDVals, cubPoints, OPERATOR_VALUE);
702 hexHDivBasis.
getValues(hexDivs, cubPoints, OPERATOR_DIV);
708 *outStream <<
"Building mass and stiffness matrices ... \n\n";
758 Epetra_FECrsMatrix MassC(Copy, globalMapC, numFieldsC);
759 Epetra_FECrsMatrix MassD(Copy, globalMapD, numFieldsD);
760 Epetra_FECrsMatrix StiffD(Copy, globalMapD, numFieldsD);
761 Epetra_FEVector rhsD(globalMapD);
764 ofstream fSignsout(
"faceSigns.dat");
768 for (
int k=0; k<numElems; k++) {
771 for (
int i=0; i<numNodesPerElem; i++) {
772 hexNodes(0,i,0) = nodeCoord(elemToNode(k,i),0);
773 hexNodes(0,i,1) = nodeCoord(elemToNode(k,i),1);
774 hexNodes(0,i,2) = nodeCoord(elemToNode(k,i),2);
778 for (
int j=0; j<numFacesPerElem; j++) {
779 hexFaceSigns(0,j) = -1.0;
780 for (
int i=0; i<numNodesPerFace; i++) {
782 if (indf > numNodesPerFace) indf=0;
783 if (elemToNode(k,refFaceToNode(j,0))==faceToNode(elemToFace(k,j),i) &&
784 elemToNode(k,refFaceToNode(j,1))==faceToNode(elemToFace(k,j),indf))
785 hexFaceSigns(0,j) = 1.0;
788 fSignsout << hexFaceSigns(0,j) <<
" ";
796 for (
int j=0; j<numEdgesPerElem; j++) {
797 if (elemToNode(k,refEdgeToNode(j,0))==edgeToNode(elemToEdge(k,j),0) &&
798 elemToNode(k,refEdgeToNode(j,1))==edgeToNode(elemToEdge(k,j),1))
799 hexEdgeSigns(0,j) = 1.0;
801 hexEdgeSigns(0,j) = -1.0;
805 CellTools::setJacobian(hexJacobian, cubPoints, hexNodes, hex_8);
806 CellTools::setJacobianInv(hexJacobInv, hexJacobian );
807 CellTools::setJacobianDet(hexJacobDet, hexJacobian );
813 fst::HCURLtransformVALUE<double>(hexCValsTransformed, hexJacobInv,
816 fst::computeCellMeasure<double>(weightedMeasure, hexJacobDet, cubWeights);
819 fst::multiplyMeasure<double>(hexCValsTransformedWeighted,
820 weightedMeasure, hexCValsTransformed);
823 fst::integrate<double>(massMatrixC,
824 hexCValsTransformed, hexCValsTransformedWeighted,
827 fst::applyLeftFieldSigns<double>(massMatrixC, hexEdgeSigns);
828 fst::applyRightFieldSigns<double>(massMatrixC, hexEdgeSigns);
831 for (
int row = 0; row < numFieldsC; row++){
832 for (
int col = 0; col < numFieldsC; col++){
833 int rowIndex = elemToEdge(k,row);
834 int colIndex = elemToEdge(k,col);
835 double val = massMatrixC(0,row,col);
836 MassC.InsertGlobalValues(1, &rowIndex, 1, &colIndex, &val);
843 fst::HDIVtransformVALUE<double>(hexDValsTransformed, hexJacobian, hexJacobDet,
847 fst::multiplyMeasure<double>(hexDValsTransformedWeighted,
848 weightedMeasure, hexDValsTransformed);
851 fst::integrate<double>(massMatrixD,
852 hexDValsTransformed, hexDValsTransformedWeighted,
855 fst::applyLeftFieldSigns<double>(massMatrixD, hexFaceSigns);
856 fst::applyRightFieldSigns<double>(massMatrixD, hexFaceSigns);
859 for (
int row = 0; row < numFieldsD; row++){
860 for (
int col = 0; col < numFieldsD; col++){
861 int rowIndex = elemToFace(k,row);
862 int colIndex = elemToFace(k,col);
863 double val = massMatrixD(0,row,col);
864 MassD.InsertGlobalValues(1, &rowIndex, 1, &colIndex, &val);
871 fst::HDIVtransformDIV<double>(hexDivsTransformed, hexJacobDet,
875 fst::multiplyMeasure<double>(hexDivsTransformedWeighted,
876 weightedMeasure, hexDivsTransformed);
879 fst::integrate<double>(stiffMatrixD,
880 hexDivsTransformed, hexDivsTransformedWeighted,
884 fst::applyLeftFieldSigns<double>(stiffMatrixD, hexFaceSigns);
885 fst::applyRightFieldSigns<double>(stiffMatrixD, hexFaceSigns);
888 for (
int row = 0; row < numFieldsD; row++){
889 for (
int col = 0; col < numFieldsD; col++){
890 int rowIndex = elemToFace(k,row);
891 int colIndex = elemToFace(k,col);
892 double val = stiffMatrixD(0,row,col);
893 StiffD.InsertGlobalValues(1, &rowIndex, 1, &colIndex, &val);
900 CellTools::mapToPhysicalFrame(physCubPoints, cubPoints, hexNodes, hex_8);
903 for (
int nPt = 0; nPt < numCubPoints; nPt++){
905 double x = physCubPoints(0,nPt,0);
906 double y = physCubPoints(0,nPt,1);
907 double z = physCubPoints(0,nPt,2);
908 double du1, du2, du3;
910 evalCurlCurlu(du1, du2, du3, x, y, z);
911 rhsDatag(0,nPt,0) = du1;
912 rhsDatag(0,nPt,1) = du2;
913 rhsDatag(0,nPt,2) = du3;
915 rhsDatah(0,nPt) = evalDivu(x, y, z);
919 fst::integrate<double>(gD, rhsDatag, hexDValsTransformedWeighted,
923 fst::integrate<double>(hD, rhsDatah, hexDivsTransformedWeighted,
927 fst::applyFieldSigns<double>(gD, hexFaceSigns);
928 fst::applyFieldSigns<double>(hD, hexFaceSigns);
931 for (
int i = 0; i < numFacesPerElem; i++){
932 if (faceOnBoundary(elemToFace(k,i))){
935 CellTools::mapToReferenceSubcell(refGaussPoints,
940 hexHDivBasis.
getValues(worksetDVals, refGaussPoints, OPERATOR_VALUE);
943 CellTools::setJacobian(worksetJacobians, refGaussPoints,
945 CellTools::setJacobianDet(worksetJacobDet, worksetJacobians);
948 fst::HDIVtransformVALUE<double>(worksetDValsTransformed, worksetJacobians,
949 worksetJacobDet, worksetDVals);
952 CellTools::mapToPhysicalFrame(worksetGaussPoints,
957 CellTools::getPhysicalFaceNormals(worksetFaceN,
962 for(
int nPt = 0; nPt < numFacePoints; nPt++){
964 double x = worksetGaussPoints(0, nPt, 0);
965 double y = worksetGaussPoints(0, nPt, 1);
966 double z = worksetGaussPoints(0, nPt, 2);
968 evalCurlu(curluFace(0,nPt,0), curluFace(0,nPt,1), curluFace(0,nPt,2), x, y, z);
972 for (
int nF = 0; nF < numFieldsD; nF++){
973 for(
int nPt = 0; nPt < numFacePoints; nPt++){
974 worksetDataCrossField(0,nF,nPt,0) = (curluFace(0,nPt,1)*worksetDValsTransformed(0,nF,nPt,2)
975 - curluFace(0,nPt,2)*worksetDValsTransformed(0,nF,nPt,1))
976 * paramGaussWeights(nPt);
977 worksetDataCrossField(0,nF,nPt,1) = (curluFace(0,nPt,2)*worksetDValsTransformed(0,nF,nPt,0)
978 - curluFace(0,nPt,0)*worksetDValsTransformed(0,nF,nPt,2))
979 * paramGaussWeights(nPt);
980 worksetDataCrossField(0,nF,nPt,2) = (curluFace(0,nPt,0)*worksetDValsTransformed(0,nF,nPt,1)
981 - curluFace(0,nPt,1)*worksetDValsTransformed(0,nF,nPt,0))
982 *paramGaussWeights(nPt);
987 fst::integrate<double>(gDBoundary, worksetFaceN, worksetDataCrossField,
991 fst::applyFieldSigns<double>(gDBoundary, hexFaceSigns);
994 for (
int nF = 0; nF < numFieldsD; nF++){
995 gD(0,nF) = gD(0,nF) - gDBoundary(0,nF);
1003 for (
int row = 0; row < numFieldsD; row++){
1004 int rowIndex = elemToFace(k,row);
1005 double val = hD(0,row)+gD(0,row);
1006 rhsD.SumIntoGlobalValues(1, &rowIndex, &val);
1013 DCurl.GlobalAssemble(); DCurl.FillComplete(MassC.RowMap(),MassD.RowMap());
1014 MassC.GlobalAssemble(); MassC.FillComplete();
1015 MassD.GlobalAssemble(); MassD.FillComplete();
1016 StiffD.GlobalAssemble(); StiffD.FillComplete();
1017 rhsD.GlobalAssemble();
1024 Epetra_CrsMatrix MassCinv(Copy,MassC.RowMap(),MassC.RowMap(),1);
1025 Epetra_Vector DiagC(MassC.RowMap());
1027 DiagC.PutScalar(1.0);
1028 MassC.Multiply(
false,DiagC,DiagC);
1029 for(
int i=0; i<DiagC.MyLength(); i++) {
1030 DiagC[i]=1.0/DiagC[i];
1032 for(
int i=0; i<DiagC.MyLength(); i++) {
1033 int CID=MassC.GCID(i);
1034 MassCinv.InsertGlobalValues(MassC.GRID(i),1,&(DiagC[i]),&CID);
1036 MassCinv.FillComplete();
1039 for(
int i=0;i<numEdges;i++) {
1040 if (edgeOnBoundary(i)){
1042 MassCinv.ReplaceGlobalValues(i,1,&val,&i);
1051 for (
int row = 0; row<numFaces; row++){
1052 MassD.ExtractMyRowView(row,numEntries,values,cols);
1053 for (
int i=0; i<numEntries; i++){
1054 if (faceOnBoundary(cols[i])) {
1058 StiffD.ExtractMyRowView(row,numEntries,values,cols);
1059 for (
int i=0; i<numEntries; i++){
1060 if (faceOnBoundary(cols[i])) {
1065 for (
int row = 0; row<numFaces; row++){
1066 if (faceOnBoundary(row)) {
1068 StiffD.ExtractMyRowView(row,numEntries,values,cols);
1069 for (
int i=0; i<numEntries; i++){
1072 MassD.ExtractMyRowView(row,numEntries,values,cols);
1073 for (
int i=0; i<numEntries; i++){
1078 StiffD.ReplaceGlobalValues(1, &rowindex, 1, &rowindex, &val);
1084 EpetraExt::RowMatrixToMatlabFile(
"mag_m1inv_matrix.dat",MassCinv);
1085 EpetraExt::RowMatrixToMatlabFile(
"mag_m2_matrix.dat",MassD);
1086 EpetraExt::RowMatrixToMatlabFile(
"mag_k2_matrix.dat",StiffD);
1087 EpetraExt::RowMatrixToMatlabFile(
"mag_t1_matrix.dat",DCurl);
1088 EpetraExt::MultiVectorToMatrixMarketFile(
"mag_rhs2_vector.dat",rhsD,0,0,
false);
1091 std::cout <<
"End Result: TEST PASSED\n";
1094 std::cout.copyfmt(oldFormatState);
1099 int evalu(
double & uExact0,
double & uExact1,
double & uExact2,
double & x,
double & y,
double & z)
1103 uExact0 = exp(y+z)*(x+1.0)*(x-1.0);
1104 uExact1 = exp(x+z)*(y+1.0)*(y-1.0);
1105 uExact2 = exp(x+y)*(z+1.0)*(z-1.0);
1129 double evalDivu(
double & x,
double & y,
double & z)
1133 double divu = 2.0*x*exp(y+z)+2.0*y*exp(x+z)+2.0*z*exp(x+y);
1148 int evalCurlu(
double & curlu0,
double & curlu1,
double & curlu2,
double & x,
double & y,
double & z)
1152 double duxdy = exp(y+z)*(x+1.0)*(x-1.0);
1153 double duxdz = exp(y+z)*(x+1.0)*(x-1.0);
1154 double duydx = exp(x+z)*(y+1.0)*(y-1.0);
1155 double duydz = exp(x+z)*(y+1.0)*(y-1.0);
1156 double duzdx = exp(x+y)*(z+1.0)*(z-1.0);
1157 double duzdy = exp(x+y)*(z+1.0)*(z-1.0);
1170 curlu0 = duzdy - duydz;
1171 curlu1 = duxdz - duzdx;
1172 curlu2 = duydx - duxdy;
1185 int evalCurlCurlu(
double & curlCurlu0,
double & curlCurlu1,
double & curlCurlu2,
double & x,
double & y,
double & z)
1189 double dcurlu0dy = exp(x+y)*(z+1.0)*(z-1.0) - 2.0*y*exp(x+z);
1190 double dcurlu0dz = 2.0*z*exp(x+y) - exp(x+z)*(y+1.0)*(y-1.0);
1191 double dcurlu1dx = 2.0*x*exp(y+z) - exp(x+y)*(z+1.0)*(z-1.0);
1192 double dcurlu1dz = exp(y+z)*(x+1.0)*(x-1.0) - 2.0*z*exp(x+y);
1193 double dcurlu2dx = exp(x+z)*(y+1.0)*(y-1.0) - 2.0*x*exp(y+z);
1194 double dcurlu2dy = 2.0*y*exp(x+z) - exp(y+z)*(x+1.0)*(x-1.0);
1212 curlCurlu0 = dcurlu2dy - dcurlu1dz;
1213 curlCurlu1 = dcurlu0dz - dcurlu2dx;
1214 curlCurlu2 = dcurlu1dx - dcurlu0dy;
void getValues(ArrayScalar &outputValues, const ArrayScalar &inputPoints, const EOperator operatorType) const
Evaluation of a FEM basis on a reference Hexahedron cell.
virtual int getCardinality() const
Returns cardinality of the basis.
Header file for utility class to provide multidimensional containers.
Header file for the Intrepid::HDIV_HEX_I1_FEM class.
void getValues(ArrayScalar &outputValues, const ArrayScalar &inputPoints, const EOperator operatorType) const
Evaluation of a FEM basis on a reference Hexahedron cell.
Header file for the abstract base class Intrepid::DefaultCubatureFactory.
Implementation of the default H(div)-compatible FEM basis of degree 1 on Hexahedron cell...
Implementation of the default H(curl)-compatible FEM basis of degree 1 on Hexahedron cell...
Implementation of a templated lexicographical container for a multi-indexed scalar quantity...
A factory class that generates specific instances of cubatures.
Teuchos::RCP< Cubature< Scalar, ArrayPoint, ArrayWeight > > create(const shards::CellTopology &cellTopology, const std::vector< int > °ree)
Factory method.
Header file for the Intrepid::HCURL_HEX_I1_FEM class.