Boolean FGLvar::iS(void){ // Steps base vertex along ideal edge e // returns FALSE if no such edge GLref ref=bv; Boolean edgeIsDefined=xS(GLideal,ref); if(edgeIsDefined) bv=ref; return(edgeIsDefined); }
Boolean FGLvar::icS(void){ // Steps companion vertex along distinguished entry of ideal edge e // returns FALSE if no such edge GLref ref=cv; Boolean edgeIsDefined=xS(GLideal,ref); if(edgeIsDefined) cv=ref; return(edgeIsDefined); }
Boolean FGLvar::rcS(void){ // Steps companion vertex along real edge e // returns FALSE if no such edge GLref ref=cv; Boolean edgeIsDefined=xS(GLreal,ref); if(edgeIsDefined) cv=ref; return(edgeIsDefined); }
void Strand2dFCBlockMesh::initialize(const int& level0, const int& meshOrder0, const int& nSurfElem0, const int& nSurfNodeG, const int& nBndNode0, const int& nStrandNodeG, const int& nCompBd0, int** surfElemG, const Array1D<int>& bndNodeG, const Array2D<double>& surfXG, const Array1D<double>& strandXG, const Array1D<int>& surfElemTagG, const Array1D<int>& bndNodeTagG, const Array2D<double>& bndNodeNormalG) { // copy dimensions for this block level = level0; meshOrder = meshOrder0; nSurfElem = nSurfElem0; nBndNode = nBndNode0; nCompBd = nCompBd0; // allocate space for the mesh data, and copy the known data surfElem.allocate(nSurfElem,meshOrder+1); surfElemTag.allocate(nSurfElem); bndNode.allocate(nBndNode); bndNodeTag.allocate(nBndNode); bndNodeNormal.allocate(nBndNode,2); for (int n=0; n<nSurfElem; n++) surfElemTag(n) = surfElemTagG(n); for (int n=0; n<nBndNode; n++){ bndNodeTag(n) = bndNodeTagG(n); bndNodeNormal(n,0) = bndNodeNormalG(n,0); bndNodeNormal(n,1) = bndNodeNormalG(n,1); } // form surface elements of the desired order, count surface nodes int n1,n2; Array1D<int> flag(nSurfNodeG); flag.set(-1); nSurfNode = 0; for (int n=0; n<nSurfElem; n++){ //add element end points first n1 = surfElemG[n][1]; n2 = surfElemG[n][2]; if (flag(n1) == -1) flag(n1) = nSurfNode++; if (flag(n2) == -1) flag(n2) = nSurfNode++; surfElem(n,0) = flag(n1); surfElem(n,1) = flag(n2); } for (int n=0; n<nSurfElem; n++) //add interior dofs next for (int j=2; j<meshOrder+1; j++) surfElem(n,j) = nSurfNode++; // point the bndNode array to the new node numbers for (int n=0; n<nBndNode; n++) bndNode(n) = flag(bndNodeG(n)); // find surface mesh coordinates based on mappings from the mesh file Array1D<double> ss(meshOrder+1); int spacing=0; // assume equal spacing for now solutionPoints1D(meshOrder, //find s-locations based on desired spacing spacing, &ss(0)); surfX.allocate(nSurfNode,2); surfX.set(0.); bool test=false; int orderM; double lm; Array1D<double> sM; Array2D<double> lcM; flag.deallocate(); flag.allocate(nSurfNode); flag.set(-1); for (int n=0; n<nSurfElem; n++){ orderM = surfElemG[n][0]; // s-locations using numbering consistent with the mesh sM.allocate(orderM+1); solutionPoints1D(orderM, spacing, &sM(0)); // lagrange polynomials at the sM locations lcM.allocate(orderM+1,orderM+1); lagrangePoly1D(test, orderM, &sM(0), &lcM(0,0)); // evaluate the x-coordinates at the local solution points for (int i=0; i<meshOrder+1; i++) //ith local point if (flag(surfElem(n,i)) == -1){//haven't computed this location yet for (int m=0; m<orderM+1; m++){ //mth Lagrange poly. used in mapping lm = 0.; for (int k=0; k<orderM+1; k++) lm += pow(ss(i),k)*lcM(m,k); surfX(surfElem(n,i),0) += lm*surfXG(surfElemG[n][m+1],0); surfX(surfElem(n,i),1) += lm*surfXG(surfElemG[n][m+1],1); } flag(surfElem(n,i)) = 0; } sM.deallocate(); lcM.deallocate(); } // generate pointing vectors // first find surface mapping based on global mesh Array2D<double> xS(nSurfElem,meshOrder+1),yS(nSurfElem,meshOrder+1); xS.set(0.); yS.set(0.); int ni,nm; Array2D<double> lsM; for (int n=0; n<nSurfElem; n++){ orderM = surfElemG[n][0]; // s-locations using numbering consistent with the mesh sM.allocate(orderM+1); solutionPoints1D(orderM, spacing, &sM(0)); // lagrange polynomials at the sM locations lcM.allocate(orderM+1,orderM+1); lagrangePoly1D(test, orderM, &sM(0), &lcM(0,0)); // ls(i,j) = (dl_j/ds)_i (a row is all Lagrange polynomials (derivatives) // evaluated at a single mesh point i) lsM.allocate(meshOrder+1,orderM+1); lsM.set(0.); int km; for (int i=0; i<meshOrder+1; i++) // ith mesh point for (int j=0; j<orderM+1; j++) // jth Lagrange polynomial for (int k=0; k<orderM+1; k++){ km = max(0,k-1); lsM(i,j) +=((double)k)*pow(ss(i),km)*lcM(j,k); } for (int n=0; n<nSurfElem; n++) for (int i=0; i<meshOrder+1; i++) //ith point in the element for (int m=0; m<orderM+1; m++){ //mth Lagrange poly. in mapping xS(n,i) += lsM(i,m)*surfXG(surfElemG[n][m+1],0); yS(n,i) += lsM(i,m)*surfXG(surfElemG[n][m+1],1); } sM.deallocate(); lcM.deallocate(); } // initialize all pointing vectors // using the surface mapping (averaged among neighboring elements) pointingVec.allocate(nSurfNode,2); pointingVec.set(0.); int m; double nx,ny,ds,rms; for (int n=0; n<nSurfElem; n++) for (int i=0; i<meshOrder+1; i++){ m = surfElem(n,i); nx =-yS(n,i); ny = xS(n,i); ds = 1./sqrt(nx*nx+ny*ny); nx *= ds; ny *= ds; //////////////////////////////////////////////////////////////////////// //~ change the 2 comment lines below with code lines to have normal //~ pointing vectors instead of verticle pointing vectors //~ pointingVec(m,0) += nx; //~ pointingVec(m,1) += ny; pointingVec(m,0) = 0.; //shaun change pointingVec(m,1) = 1.; } for (int n=0; n<nSurfNode; n++){ ds = 1./sqrt(pointingVec(n,0)*pointingVec(n,0)+ pointingVec(n,1)*pointingVec(n,1)); pointingVec(n,0) *= ds; pointingVec(n,1) *= ds; } // smooth the strands interior to elements iteratively int* psp1; int** psp2; psp1 = new int[meshOrder+1]; psp2 = new int*[meshOrder+1]; if (meshOrder == 1){ psp1[0] = 1; psp1[1] = 1; psp2[0] = new int[psp1[0]]; psp2[0][0] = 1; psp2[1] = new int[psp1[1]]; psp2[1][0] = 0; } else if (meshOrder == 2){ psp1[0] = 1; psp1[1] = 1; psp1[2] = 2; psp2[0] = new int[psp1[0]]; psp2[0][0] = 2; psp2[1] = new int[psp1[1]]; psp2[1][0] = 2; psp2[2] = new int[psp1[2]]; psp2[2][0] = 0; psp2[2][1] = 1; } else if (meshOrder == 3){ psp1[0] = 1; psp1[1] = 1; psp1[2] = 2; psp1[3] = 2; psp2[0] = new int[psp1[0]]; psp2[0][0] = 2; psp2[1] = new int[psp1[1]]; psp2[1][0] = 3; psp2[2] = new int[psp1[2]]; psp2[2][0] = 0; psp2[2][1] = 3; psp2[3] = new int[psp1[3]]; psp2[3][0] = 2; psp2[3][1] = 1; } else if (meshOrder == 4){ psp1[0] = 1; psp1[1] = 1; psp1[2] = 2; psp1[3] = 2; psp1[4] = 2; psp2[0] = new int[psp1[0]]; psp2[0][0] = 2; psp2[1] = new int[psp1[1]]; psp2[1][0] = 4; psp2[2] = new int[psp1[2]]; psp2[2][0] = 0; psp2[2][1] = 3; psp2[3] = new int[psp1[3]]; psp2[3][0] = 2; psp2[3][1] = 4; psp2[4] = new int[psp1[4]]; psp2[4][0] = 3; psp2[4][1] = 1; } else{ cout << "\nPlease choose meshOrder=3 or less." << endl; exit(0); } if (meshOrder > 1) for (int n=0; n<nSurfElem; n++) for (int iter=0; iter<1000; iter++){ rms = 0.; for (int i=2; i<meshOrder+1; i++){ ni = surfElem(n,i); nx = 0.; ny = 0.; for (int m=0; m<psp1[i]; m++){ nm = surfElem(n,psp2[i][m]); nx += pointingVec(nm,0); ny += pointingVec(nm,1); } ds = 1./sqrt(nx*nx+ny*ny); nx *= ds; ny *= ds; rms += (nx-pointingVec(ni,0))*(nx-pointingVec(ni,0))+ (ny-pointingVec(ni,1))*(ny-pointingVec(ni,1)); pointingVec(ni,0) = nx; pointingVec(ni,1) = ny; } rms = sqrt(rms/(double)(meshOrder-1)); if (rms < 1.e-13) break; } /* for (int n=0; n<nSurfNode; n++){ pointingVec(n,0) = 0.; pointingVec(n,1) = 1.; } */ // determine strand node distribution int ks=nStrandNodeG-1,js=pow(2,level); if (ks%js != 0){ cout << "\n***Number of strand nodes not a good multigrid number.***" << endl; exit(0); } nStrandNode =(nStrandNodeG-1)/pow(2,level); nStrandNode++; strandX.allocate(nStrandNode); int i=0; for (int j=0; j<nStrandNode; j++){ strandX(j) = strandXG(i); i += pow(2,level); } // generate clipping index clip.allocate(nSurfNode); clip.set(nStrandNode-1); // report mesh statistics if (level == 0){ cout.setf(ios::scientific); cout << "\nMesh statistics: " << endl << "Number of surface elements: " << nSurfElem << endl << "Number of surface nodes: " << nSurfNode << endl << "Number of boundary nodes: " << nBndNode << endl << "Number of boundary comp.: " << nCompBd << endl << "Number of strand nodes: " << nStrandNode << endl; cout << "\nstrand distribution:"; for (int n=0; n<nStrandNode; n++) cout << "\n" << n << "\t" << strandX(n); cout << "\nwall spacing: " << strandX(1) << "\ntip spacing: " << strandX(nStrandNode-1)-strandX(nStrandNode-2) << "\n" << endl; } // clean up if (psp1){ delete [] psp1; psp1 = NULL; } if (psp2){ for (int i=0; i<meshOrder+1; i++) if (psp2[i]){ delete [] psp2[i]; psp2[i] = NULL; } delete [] psp2; psp2 = NULL; } xS.deallocate(); yS.deallocate(); lcM.deallocate(); lsM.deallocate(); sM.deallocate(); ss.deallocate(); flag.deallocate(); }