示例#1
0
/* Mesh a line in dimensionless coordinates from (x1,y1) to (x2,y2)
	ratio is ratio of first to last interval size
	numIntervals is number of intervals (>1)
*/
void Area::MeshLine(double x1,double y1,double x2,double y2,double ratio,int numIntervals,int doingMidNodes)
{
	double a,r,t,fxn[8],xNode,yNode,last;
	double x1arg,x2arg,y1arg,y2arg,xlast,ylast;
	int numMesh,i,j;
	Vector xi;
	
	GetLineParameters(numIntervals,ratio,&r,&a);
	x1arg=(x2+x1)/2.;
	x2arg=(x2-x1)/2.;
	y1arg=(y2+y1)/2.;
	y2arg=(y2-y1)/2.;
	
	numMesh=numIntervals-1;
	if(doingMidNodes) numMesh++;
	
	t=-1.+a;
	last=a;
	xlast=x1;
	ylast=y1;
	for(i=1;i<=numMesh;i++)
	{	// vector xi has dimensionless coordinates of next node
		xi.x=x1arg+t*x2arg;
		xi.y=y1arg+t*y2arg;
		if(doingMidNodes)
		{	xNode=(xi.x+xlast)/2.;
			yNode=(xi.y+ylast)/2.;
			xlast=xi.x;
			ylast=xi.y;
			xi.x=xNode;
			xi.y=yNode;
		}
		
		// Convert to real coordinates using shape functions
		areaElem->ShapeFunction(&xi,FALSE,fxn,NULL,NULL,NULL,NULL,NULL,NULL);
		xNode=0.;
		yNode=0.;
		for(j=0;j<areaElem->NumberNodes();j++)
		{	xNode+=fxn[j]*areaNode[j].x;
			yNode+=fxn[j]*areaNode[j].y;
		}
		
		// add node to list
		theNodes->AddNode(xNode,yNode,(double)0.,(double)0.0);
		
		last*=r;
		t+=last;
	}
}
示例#2
0
/* Copy algorithm of Mesh Line to find a point along a path
	(x1,y1) to (x2,y2) line in dimensionless coordinates
	ratio is element size ratio
	numIntervals in number of intervals on full line
	numFind is which node point to find
	returns t (relative position along line) and parameters
		for subsequent call to LineLocate()
*/
void Area::FindPtOnLine(double x1,double y1,double x2,double y2,double ratio,
		int numIntervals,int numFind,double *targ,double *x1arg,
		double *x2arg,double *y1arg,double *y2arg)
{
	double a,r;
	GetLineParameters(numIntervals,ratio,&r,&a);
	*x1arg=(x2+x1)/2.;
	*x2arg=(x2-x1)/2.;
	*y1arg=(y2+y1)/2.;
	*y2arg=(y2-y1)/2.;
	
	// find dimensionless position of point numFind along the path
	if(fabs(ratio-1.)>0.001)
		*targ=-1. + a*(1.-pow(r,(double)numFind))/(1.-r);
	else
		*targ=-1. + a*(double)numFind;
}
示例#3
0
// Mesh an area that has been checked already as valid and is quadrilateral
// throws std::bad_alloc
const char *Area::MeshArea(void)
{
	int i;
	int eNode[MaxElNd];
	
	// space for area nodes and element object
	areaNode=new Vector[2*numPaths];
	for(i=0;i<8;i++) eNode[i]=i+1;
	areaElem=new EightNodeIsoparam(1,eNode,1,(double)0.0,(double)0.0);
	
	// put nodes at the corners
	for(i=0;i<numPaths;i++)
	{	edges[i]->FirstKeypointToNode();
		edges[i]->GetFirstAndMidXY(&areaNode[i],&areaNode[i+numPaths]);
	}
		
	// place nodes along the edges
	for(i=0;i<numPaths;i++)
	{	if(!edges[i]->IsMeshed())
		{	// Get line in dimensionless coordinates
			double x1=1.,y1=1.,x2=1.,y2=1.;
			switch(i)
			{	case 0:
					x1=y1=y2=-1;
					break;
				case 1:
					y1=-1;
					break;
				case 2:
					x2=-1;
					break;
				case 3:	
					x1=x2=y2=-1;
					break;
				default:
					break;
			}
			
			// Do main nodes (note: 1 interval is special case)
			if(edges[i]->intervals==1)
			{	// Only 1 interval - no need to get nodes
				edges[i]->firstMainNode=0;
			}
			else
			{	edges[i]->firstMainNode=theNodes->NextNodeNumber();
				MeshLine(x1,y1,x2,y2,edges[i]->ratio,edges[i]->intervals,FALSE);
			}
			
			/* Do mid side nodes */
			if(theElems->HasMidsideNodes())
			{	edges[i]->firstMidsideNode=theNodes->NextNodeNumber();
				MeshLine(x1,y1,x2,y2,edges[i]->ratio,edges[i]->intervals,TRUE);
			}
		}
	}
	
	/*-------------------------------------------------------------------
	 	Use the following section when the numbers of elements are not
	 		that same on opposite sides
		Divide element as follows:
		 
			   _____na__________
			  |\               |
			  |  \+5           |+3      na, nb, nc are numbers of intervals
			  |    \ nc        5 nc                
			  |      \         |        1. create new keypoints (#'s on lines)
		  nb  |        6___+6__3        2. create new paths (+numbers
			  |  1st    |  na  |+2      3. Call MeshArea recursively for the
			  |   nb  +4|      4 nb          newly created areas with equal
			  |   +0    |   +1 |             interval numbers on opposites sides
			  -----1----0---2--
				  nc         na
	-------------------------------------------------------------------*/
	if(edges[0]->intervals!=edges[2]->intervals)
	{	// area intervals (have been ordered such that n1>n3, which implies n2>n4)
		int n1=edges[0]->intervals;
		int n3=edges[2]->intervals;
		int n4=edges[3]->intervals;
		int nc=n1-n3;
		int na=n3;
		int nb=n4;
		
		// keypoint at junction of two new paths along path 1
		double targ,t1arg,x1arg,x2arg,y1arg,y2arg,xkey,ykey;
		Keypoint *addedKeys[7];
		FindPtOnLine((double)-1.,(double)-1.,(double)1.,(double)-1.,edges[0]->ratio,
				edges[0]->intervals,nc,&targ,&x1arg,&x2arg,&y1arg,&y2arg);
		t1arg=targ;
		LineLocate(targ,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[0]=new Keypoint("",xkey,ykey);
		addedKeys[0]->node=edges[0]->firstMainNode+(nc-1)*edges[0]->nodeIncrement;
		
		// Create keypoint in middle of added path 0
		LineLocate((targ-1.)/2.,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[1]=new Keypoint("",xkey,ykey);
		
		// Create keypoint in middle of added path 1 */
		LineLocate((1.+targ)/2.,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[2]=new Keypoint("",xkey,ykey);
		
		// keypoint at junction of two new paths along path 2
		FindPtOnLine((double)1.,(double)-1.,(double)1.,(double)1.,edges[1]->ratio,
				edges[1]->intervals,nb,&targ,&x1arg,&x2arg,&y1arg,&y2arg);
		LineLocate(targ,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[3]=new Keypoint("",xkey,ykey);
		addedKeys[3]->node=edges[1]->firstMainNode+(nb-1)*edges[1]->nodeIncrement;
		
		// Create keypoint in middle of added path 2
		LineLocate((targ-1.)/2.,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[4]=new Keypoint("",xkey,ykey);
		
		// Create keypoint in middle of added path 3
		LineLocate((1.+targ)/2.,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[5]=new Keypoint("",xkey,ykey);
		
		// keypoint at middle of area
		FindPtOnLine(t1arg,(double)-1.,t1arg,(double)1.,edges[1]->ratio,
				edges[1]->intervals,nb,&targ,&x1arg,&x2arg,&y1arg,&y2arg);
		LineLocate(targ,x1arg,x2arg,y1arg,y2arg,&xkey,&ykey);
		addedKeys[6]=new Keypoint("",xkey,ykey);
		
		// First new path along path 1
		Path *addedPaths[7];
		double r,a1,a4;
		GetLineParameters(edges[0]->intervals,edges[0]->ratio,&r,&a1);
		addedPaths[0]=new Path("",nc,GetRatio(nc,r));
		addedPaths[0]->SetKeys(edges[0]->FirstKeypoint(),addedKeys[1],addedKeys[0]);
		addedPaths[0]->firstMainNode=edges[0]->firstMainNode;
		addedPaths[0]->firstMidsideNode=edges[0]->firstMidsideNode;
		addedPaths[0]->nodeIncrement=edges[0]->nodeIncrement;
		edges[0]->subPath[0]=addedPaths[0];
		
		// Second new path along path 1
		addedPaths[1]=new Path("",na,GetRatio(na,r));
		addedPaths[1]->SetKeys(addedKeys[0],addedKeys[2],edges[0]->LastKeypoint());
		addedPaths[1]->firstMainNode=edges[0]->firstMainNode+nc*edges[0]->nodeIncrement;
		addedPaths[1]->firstMidsideNode=edges[0]->firstMidsideNode+nc*edges[0]->nodeIncrement;
		addedPaths[1]->nodeIncrement=edges[0]->nodeIncrement;
		edges[0]->subPath[1]=addedPaths[1];
		
		// First new path along path 2
		GetLineParameters(edges[1]->intervals,edges[1]->ratio,&r,&a4);
		addedPaths[2]=new Path("",nb,GetRatio(nb,r));
		addedPaths[2]->SetKeys(edges[1]->FirstKeypoint(),addedKeys[4],addedKeys[3]);
		addedPaths[2]->firstMainNode=edges[1]->firstMainNode;
		addedPaths[2]->firstMidsideNode=edges[1]->firstMidsideNode;
		addedPaths[2]->nodeIncrement=edges[1]->nodeIncrement;
		edges[1]->subPath[0]=addedPaths[2];

		// Second new path along path 2
		addedPaths[3]=new Path("",nc,GetRatio(nc,r));
		addedPaths[3]->SetKeys(addedKeys[3],addedKeys[5],edges[1]->LastKeypoint());
		addedPaths[3]->firstMainNode=edges[1]->firstMainNode+nb*edges[1]->nodeIncrement;
		addedPaths[3]->firstMidsideNode=edges[1]->firstMidsideNode+nb*edges[1]->nodeIncrement;
		addedPaths[3]->nodeIncrement=edges[1]->nodeIncrement;
		edges[1]->subPath[1]=addedPaths[3];
		
		// New Path from path 1 to central point
		addedPaths[4]=new Path("",nb,addedPaths[2]->ratio);
		addedPaths[4]->SetKeys(addedKeys[0],addedKeys[6],NULL);
		
		// New Path from central point to upper-left corner
		GetLineParameters(addedPaths[0]->intervals,addedPaths[0]->ratio,&r,&a1);
		GetLineParameters(addedPaths[3]->intervals,addedPaths[3]->ratio,&r,&a4);
		x2arg=addedKeys[0]->x-(edges[0]->FirstKeypoint())->x;
		y2arg=addedKeys[0]->y-(edges[0]->FirstKeypoint())->y;
		double p1d1=a1*a1*(x2arg*x2arg+y2arg*y2arg);
		double p1d2=p1d1/(addedPaths[0]->ratio*addedPaths[0]->ratio);
		x2arg=(edges[1]->LastKeypoint())->x-addedKeys[3]->x;
		y2arg=(edges[1]->LastKeypoint())->y-addedKeys[3]->y;
		double p4d1=a4*a4*(x2arg*x2arg+y2arg*y2arg);
		double p4d2=p4d1/(addedPaths[3]->ratio*addedPaths[3]->ratio);
		double ratio=sqrt(p1d2 + p4d1)/sqrt(p1d1 + p4d2);
		addedPaths[5]=new Path("",nc,ratio);
		addedPaths[5]->SetKeys(addedKeys[6],edges[3]->FirstKeypoint(),NULL);

		// New Path from path 2 to central point
		addedPaths[6]=new Path("",na,1./addedPaths[1]->ratio);
		addedPaths[6]->SetKeys(addedKeys[3],addedKeys[6],NULL);
		
		// clear and store items
		delete [] areaNode;
		delete areaElem;
		areaNode=NULL;
		areaElem=NULL;
		Path *oldEdges[4];
		for(i=0;i<=3;i++) oldEdges[i]=edges[i];
		
		// Call MeshArea three times (do not flip 1st or 3rd areas)
		bool oldFlip=theElems->FlipTriangles();
		theElems->SetFlipTriangles("0");
		edges[0]=addedPaths[0];
		edges[1]=addedPaths[4];
		edges[2]=addedPaths[5];
		edges[3]=oldEdges[3];
		const char *msg=MeshArea();
		if(msg!=NULL) return msg;
		
		theElems->SetFlipTriangles(oldFlip);
		edges[0]=addedPaths[1];
		edges[1]=addedPaths[2];
		edges[2]=addedPaths[6];
		edges[3]=addedPaths[4];
		edges[3]->ReorientPath();
		msg=MeshArea();
		if(msg!=NULL) return msg;

		theElems->SetFlipTriangles("0");
		edges[0]=addedPaths[6];
		edges[1]=addedPaths[3];
		edges[2]=oldEdges[2];
		edges[3]=addedPaths[5];
		edges[0]->ReorientPath();
		edges[3]->ReorientPath();
		msg=MeshArea();
		if(msg!=NULL) return msg;
		
		theElems->SetFlipTriangles(oldFlip);		// restore
		// add to list so they get deleted when no longer needed
		for(i=0;i<=6;i++)
		{	keyPts->AddObject(addedKeys[i]);
			paths->AddObject(addedPaths[i]);
		}
		return NULL;
	}

	/* Mesh nodes that are interior to the area
	*/
	double rLeft,aLeft,rRight,aRight;
	int firstInterior=0,firstInteriorMidside=0;
	double yLeft,yRight,yLLast,yRLast;
	double ratio,botFraction,yLeftLast,yRightLast,yLeftMid,yRightMid;
	
	// Linear interpolation of ratios
	double ratioTop=1./edges[2]->ratio;
	double ratioBot=edges[0]->ratio;
	
	// Define interval spacing along left and right edges
	GetLineParameters(edges[3]->intervals,1/edges[3]->ratio,&rLeft,&aLeft);
	GetLineParameters(edges[1]->intervals,edges[1]->ratio,&rRight,&aRight);
	
	// Do main nodes interior to area (if any are there) */
	if(edges[3]->intervals>1 && edges[0]->intervals>1)
	{	firstInterior=theNodes->NextNodeNumber();
		
		// Loop over intervals
		yLeft=yRight=-1.;
		yLLast=aLeft;
		yRLast=aRight;
		for(i=1;i<edges[3]->intervals;i++)
		{	yLeft+=yLLast;
			yLLast*=rLeft;
			yRight+=yRLast;
			yRLast*=rRight;
			botFraction=(1.-(yLeft+yRight)/2.)/2.;
			ratio=botFraction*ratioBot+(1-botFraction)*ratioTop;
			MeshLine((double)-1.,yLeft,(double)1.,yRight,ratio,edges[0]->intervals,FALSE);
		}
	}

	// Do mid side nodes (if needed)
	if(theElems->HasMidsideNodes() && (edges[0]->intervals>1 || edges[3]->intervals>1))
	{	firstInteriorMidside=theNodes->NextNodeNumber();
		
		// Loop over intervals
		yLeft=yRight=yLeftLast=yRightLast=-1.;
		yLLast=aLeft;
		yRLast=aRight;
		for(i=1;i<=edges[3]->intervals;i++)
		{	yLeft+=yLLast;
			yLLast*=rLeft;
			yRight+=yRLast;
			yRLast*=rRight;
			
			// Do mid side nodes on right edges of elements
			if(edges[0]->intervals>1)
			{	yLeftMid=(yLeftLast+yLeft)/2.;
				yRightMid=(yRightLast+yRight)/2.;
				botFraction=(1.-(yLeftMid+yRightMid)/2.)/2.;
				ratio=botFraction*ratioBot+(1-botFraction)*ratioTop;
				MeshLine((double)-1.,yLeftMid,(double)1.,yRightMid,ratio,edges[0]->intervals,FALSE);
			}
			
			// Do mid side nodes to tops of elements
			if(i!=edges[3]->intervals)
			{	botFraction=(1.-(yLeft+yRight)/2.)/2.;
				ratio=botFraction*ratioBot+(1-botFraction)*ratioTop;
				MeshLine((double)-1.,yLeft,(double)1.,yRight,ratio,edges[0]->intervals,TRUE);
			}
			
			// Save current point
			yLeftLast=yLeft;
			yRightLast=yRight;
		}
	}
	
	/* Mesh the area or get nodes in each element
	*/
	int row,rows=edges[1]->intervals;
	int col,cols=edges[0]->intervals;
	
	/* Calculate element numbers along surronding paths -
		First element means first one on boundary */
	int elemNum=theElems->numObjects;
	if(theElems->ElementSides()==3)
	{	edges[0]->firstElem=elemNum+1;
		edges[0]->elemIncrement=2;
		if(theElems->FlipTriangles())
			edges[1]->firstElem=elemNum+2*cols;
		else
			edges[1]->firstElem=elemNum+2*cols-1;
		edges[1]->elemIncrement=2*cols;
		edges[2]->firstElem=elemNum+2*rows*cols;
		edges[2]->elemIncrement=-2;
		if(theElems->FlipTriangles())
			edges[3]->firstElem=elemNum+2*(rows-1)*cols+1;
		else
			edges[3]->firstElem=elemNum+2*(rows-1)*cols+2;
		edges[3]->elemIncrement=-2*cols;
	}
	else if(theElems->ElementSides()==4)
	{	edges[0]->firstElem=elemNum+1;
		edges[0]->elemIncrement=1;
		edges[1]->firstElem=elemNum+cols;
		edges[1]->elemIncrement=cols;
		edges[2]->firstElem=elemNum+rows*cols;
		edges[2]->elemIncrement=-1;
		edges[3]->firstElem=elemNum+(rows-1)*cols+1;
		edges[3]->elemIncrement=-cols;
	}
	
	// Calculate the elements
	for(row=1;row<=rows;row++)
	{	for(col=1;col<=cols;col++)
		{	/* Assume all nodes are interior to area and get
				the nodes - wrong ones will be corrected latter */
			eNode[3]=firstInterior+(row-1)*(cols-1)+(col-1);
			eNode[4]=eNode[3]-1;
			eNode[1]=eNode[4]-(cols-1);
			eNode[2]=eNode[1]+1;
			if(theElems->HasMidsideNodes())
			{	eNode[6]=firstInteriorMidside+(row-1)*(2*cols-1)+(col-1);
				eNode[7]=eNode[6]+cols-1;
				eNode[8]=eNode[6]-1;
				eNode[5]=eNode[6]-cols;
			}
				
			// Correct nodes that are actually on an edge for first row
			if(row==1)
			{	// First assume rows and cols>1
				if(col==1)
				{	eNode[1]=(edges[0]->FirstKeypoint())->node;
					eNode[2]=edges[0]->firstMainNode;
					eNode[4]=edges[3]->firstMainNode+edges[3]->nodeIncrement*(rows-2);
					if(theElems->HasMidsideNodes())
					{	eNode[5]=edges[0]->firstMidsideNode;
						eNode[8]=edges[3]->firstMidsideNode+edges[3]->nodeIncrement*(rows-1);
					}
				}
				else if(col==cols)
				{	eNode[1]=edges[0]->firstMainNode+edges[0]->nodeIncrement*(cols-2);
					eNode[2]=(edges[0]->LastKeypoint())->node;
					eNode[3]=edges[1]->firstMainNode;
					if(theElems->HasMidsideNodes())
					{	eNode[5]=edges[0]->firstMidsideNode+edges[0]->nodeIncrement*(cols-1);
						eNode[6]=edges[1]->firstMidsideNode;
					}
				}
				else
				{	eNode[1]=edges[0]->firstMainNode+edges[0]->nodeIncrement*(col-2);
					eNode[2]=eNode[1]+edges[0]->nodeIncrement;
					if(theElems->HasMidsideNodes())
						eNode[5]=edges[0]->firstMidsideNode+edges[0]->nodeIncrement*(col-1);
				}
				
				/* Final correction for rows or cols equal to 1
					(Note: both will not be 1 (trapped earlier)) */
				if(rows==1)
				{	if(col==1)	// Note: cols won't be 1
					{	eNode[3]=edges[2]->firstMainNode+edges[2]->nodeIncrement*(cols-2);
						eNode[4]=(edges[3]->FirstKeypoint())->node;
						if(theElems->HasMidsideNodes())
							eNode[7]=edges[2]->firstMidsideNode+edges[2]->nodeIncrement*(cols-1);
					}
					else if(col==cols)
					{	eNode[3]=(edges[2]->FirstKeypoint())->node;
						eNode[4]=edges[2]->firstMainNode;
						if(theElems->HasMidsideNodes())
							eNode[7]=edges[2]->firstMidsideNode;
					}
					else
					{	eNode[3]=edges[2]->firstMainNode+edges[2]->nodeIncrement*(cols-col-1);
						eNode[4]=eNode[3]+edges[2]->nodeIncrement;
						if(theElems->HasMidsideNodes())
							eNode[7]=edges[2]->firstMidsideNode+edges[2]->nodeIncrement*(cols-col);
					}
				}
				else if(cols==1)	// Note rows can not also be 1
				{	eNode[2]=(edges[1]->FirstKeypoint())->node;
					eNode[3]=edges[1]->firstMainNode;
					if(theElems->HasMidsideNodes())
						eNode[6]=edges[1]->firstMidsideNode;
				}
			}
			
			// Correct nodes that are actually on an edge for last row
			else if(row==rows)
			{	if(col==1)
				{	eNode[1]=edges[3]->firstMainNode;
					eNode[3]=edges[2]->firstMainNode+edges[2]->nodeIncrement*(cols-2);
					eNode[4]=(edges[2]->LastKeypoint())->node;
					if(theElems->HasMidsideNodes())
					{	eNode[7]=edges[2]->firstMidsideNode+edges[2]->nodeIncrement*(cols-1);
						eNode[8]=edges[3]->firstMidsideNode;
					}
				}
				else if(col==cols)
				{	eNode[2]=edges[1]->firstMainNode+edges[1]->nodeIncrement*(rows-2);
					eNode[3]=(edges[1]->LastKeypoint())->node;
					eNode[4]=edges[2]->firstMainNode;
					if(theElems->HasMidsideNodes())
					{	eNode[6]=edges[1]->firstMidsideNode+edges[1]->nodeIncrement*(rows-1);
						eNode[7]=edges[2]->firstMidsideNode;
					}
				}
				else
				{	eNode[3]=edges[2]->firstMainNode+edges[2]->nodeIncrement*(cols-col-1);
					eNode[4]=eNode[3]+edges[2]->nodeIncrement;
					if(theElems->HasMidsideNodes())
						eNode[7]=edges[2]->firstMidsideNode+edges[2]->nodeIncrement*(cols-col);
				}
				
				/* Final correction cols equal to 1
					(Note: rows won't be 1 - it will come through in
						first in if(row==1) section */
				if(cols==1)
				{	eNode[3]=(edges[2]->FirstKeypoint())->node;
					eNode[2]=edges[1]->firstMainNode+edges[1]->nodeIncrement*(rows-2);
					if(theElems->HasMidsideNodes())
						eNode[6]=edges[1]->firstMidsideNode+edges[1]->nodeIncrement*(rows-1);
				}
			}
			
			// Correct nodes that are actually on an edge for interior rows
			else
			{	if(col==1)
				{	eNode[4]=edges[3]->firstMainNode+edges[3]->nodeIncrement*(rows-row-1);
					eNode[1]=eNode[4]+edges[3]->nodeIncrement;
					if(theElems->HasMidsideNodes())
						eNode[8]=edges[3]->firstMidsideNode+edges[3]->nodeIncrement*(rows-row);
				}
				
				if(col==cols)
				{	eNode[2]=edges[1]->firstMainNode+edges[1]->nodeIncrement*(row-2);
					eNode[3]=eNode[2]+edges[1]->nodeIncrement;
					if(theElems->HasMidsideNodes())
						eNode[6]=edges[1]->firstMidsideNode+edges[1]->nodeIncrement*(row-1);
				}
			}
			
			// Special case for 1 element area
			if(rows==1 && cols==1)
			{	eNode[1]=(edges[0]->FirstKeypoint())->node;
				eNode[2]=(edges[1]->FirstKeypoint())->node;
				eNode[3]=(edges[2]->FirstKeypoint())->node;
				eNode[4]=(edges[3]->FirstKeypoint())->node;
				if(theElems->HasMidsideNodes())
				{	eNode[5]=edges[0]->firstMidsideNode;
					eNode[6]=edges[1]->firstMidsideNode;
					eNode[7]=edges[2]->firstMidsideNode;
					eNode[8]=edges[3]->firstMidsideNode;
				}
			}
			
			// calculate angle
			if(angleExpr!=NULL)
			{	int imax= theElems->HasMidsideNodes() ? 4 : 8 ;
				Vector midPt;
				theNodes->MidPoint(&eNode[1],imax,&midPt);
				angle=FunctionValue(1,midPt.x,midPt.y,0.,0.,0.,0.);
			}
			
			if(!theElems->MeshElement(eNode,mat,angle,thick))
				return "Unable to create elements in the meshing area";
			
		}
	}

	/* adjust path faces for some elements */
	if(theElems->ElementSides()==3)
	{	if(!theElems->FlipTriangles())
		{	if(edges[2]->face>0) edges[2]->face=1;
			if(edges[3]->face>0) edges[3]->face=2;
		}
		else
		{	if(edges[3]->face>0) edges[3]->face=3;
		}
	}
	
	// all done
	return NULL;
}
示例#4
0
文件: Path.cpp 项目: bbanerjee/ParSim
// assign edge boundary conditions to a path
void Path::AddEdgeBCsToPath(int dir,int nloads,double *stress)
{
	int i,j;
	
	// get three loads
	if(nloads==1)
		stress[1]=stress[2]=stress[0];
	else if(nloads==2)
	{	stress[2]=stress[1];
		stress[1]=(stress[0]+stress[2])/2.;
	}
	
	// Get line parametrization parameters
	double r,a,t=-1.,last;
	GetLineParameters(intervals,ratio,&r,&a);
	last=a;
	
	// element parameters
	int elementInc,switchPaths;
	int element=firstElem;
	if(element>=0)
	{	// use this path
		elementInc=elemIncrement;
		switchPaths=intervals+1;		// never switch paths
	}
	else
	{	// must look at sub paths
		element=subPath[0]->firstElem;
		elementInc=subPath[0]->elemIncrement;
		switchPaths=subPath[0]->intervals;		// when to switch to other subpath
	}
	
	// loop over intervals
	int faceLoc = (face<0) ? -face : face;		// negative face is when interface is present too
	double tn[3],values[3];
	for(i=1;i<=intervals;i++)
	{	tn[0]=t;
		t+=last;
		last*=r;
		tn[1]=(tn[0]+t)/2.;
		tn[2]=t;
		for(j=0;j<=2;j++)
		{	values[j]=0.5*(2*stress[1]+(stress[2]-stress[0])*tn[j]
				+(stress[2]+stress[0]-2*stress[1])*tn[j]*tn[j]);
		}
		
		// create new edge BC
		EdgeBC *newEdgeBC=new EdgeBC(element,faceLoc,dir);
		if(edgeBCCtrl->AddObject(newEdgeBC))
		{	if(firstMidsideNode>0)
				newEdgeBC->SetStress(values,3);
			else
			{	values[1]=values[2];
				newEdgeBC->SetStress(values,2);
			}
		}

		// should loop by switched to second subpath?
		if(i!=switchPaths)
			element+=elementInc;
		else
		{	element=subPath[1]->firstElem;
			elementInc=subPath[1]->elemIncrement;
		}
	}
}