Пример #1
0
// Calculate edge loads
void Quad2D::CalcEdgeLoads(double *re,int iedge,int ndir,double *fload,int np)
{	// iedge is edge number (1 ... NumberSides())
	int ind1=iedge,ind2,ind3;
	
	// assumes corners at 1 ... NumberSides() and midside nodes at
	//    NumberSides+1 ... 2*NumberSides()
	ind2=ind1+NumberSides();
	if(ind1==NumberSides())
		ind3=1;
	else
		ind3=ind1+1;
	QuadEdgeLoad(ind1,ind2,ind3,ndir,fload,re,np);
}
Пример #2
0
// If this node has crack tip nodes, move neighboring nodes toward the crack tip
void Quad2D::MakeQuarterPointNodes(int crackTip,vector<int> &movedNodes)
{
	// check real corner nodes (in nodes[0] to nodes[NumberSides()]
	int i,ct=-1;;
    for(i=0;i<NumberSides();i++)
    {	if(nodes[i]==crackTip)
		{	ct=i;
			break;
		}
    }
	if(ct<0) return;
	
	// edge after ct (assumes midside nodes and ct+NumberSides())
	// note hav internal nodes after last midside node as 2*NumberSides()-1 (zero based)
	if(ct<NumberSides()-1)
		AdjustMidSideNode(ct,ct+NumberSides(),ct+1,movedNodes);
	else
		AdjustMidSideNode(NumberSides()-1,2*NumberSides()-1,0,movedNodes);
	
	// edge before ct
	if(ct>0)
		AdjustMidSideNode(ct,ct-1+NumberSides(),ct-1,movedNodes);
	else
		AdjustMidSideNode(0,2*NumberSides()-1,NumberSides()-1,movedNodes);
}
Пример #3
0
/* Find element (0 based) that touches the element face stating in gridNode
    First time called, search other elements for the edge, but then store result
    Assumes nodes[NumberNodes()]=nodes[0]
    return NO_NEIGHBOR (-1) if no neighbor (i.e., on edge of grid)
    return UNKNOWN_NEIGHBOR (-2) if gridNode not in this element
*/
int ElementBase::Neighbor(int gridNode)
{
    int i,edge=-1;
    
    // first find which edge (0 to NumberSides()-1) to search?
    for(i=0;i<NumberSides();i++)
    {	if(nodes[i]==gridNode)
        {   edge=i;
            break;
        }
    }
    
    // if edge not found and error because the gridNode is not even in this element
    if(edge<0) return UNKNOWN_NEIGHBOR;
    
    // search for neighbor if needed
    if(neighbors[edge]==UNKNOWN_NEIGHBOR)
    {	int nextNode=nodes[edge+1];
        neighbors[edge]=NO_NEIGHBOR;
        
        // search for element with nextNode,gridNode in ccw direction
        for(i=0;i<nelems;i++)
        {   if(theElements[i]->FindEdge(nextNode,gridNode)>=0)
            {	neighbors[edge]=i;
                break;
            }
        }
    }
    
    // return result
    return neighbors[edge];
}
Пример #4
0
/*	Use ray crossing algorithm to find out if a point (pt.x,pt.y) is in an element
	nd is pointer to 1-based array NodalPoints
*/
short Quad2D::PtInElement(Vector &pt) const
{
	short i,ns=NumberSides(),crossings=0;
	double d,x1,y1,x2,y2;
	
	for(i=0;i<ns;i++)
	{	// start to mid side node
		x1=nd[nodes[i]]->x;
		y1=nd[nodes[i]]->y;
		x2=nd[nodes[i+ns]]->x;
		y2=nd[nodes[i+ns]]->y;
		d=(pt.y-y1)*(x2-x1) - (pt.x-x1)*(y2-y1);
		
		// get crossing unless both y's on same side of edge
		if((y1>=pt.y) != (y2>=pt.y))
		{	crossings+= (y2-y1>=0.) ? d>=0. : d<=0. ;
		}
		
		// if d is 0, check if point is on line (and thus in polygon)
		if(!d && fmin(x1,x2)<=pt.x && pt.x<=fmax(x1,x2) &&
				 fmin(y1,y2)<=pt.y && pt.y<=fmax(y1,y2))
		{	return(1);
		}
		
		// mid side node to end
		x1=x2;
		y1=y2;
		if(i+1<ns)
		{	x2=nd[nodes[i+1]]->x;
			y2=nd[nodes[i+1]]->y;
		}
		else
		{	x2=nd[nodes[0]]->x;
			y2=nd[nodes[0]]->y;
		}
		d=(pt.y-y1)*(x2-x1) - (pt.x-x1)*(y2-y1);
		
		// get crossing unless both y's on same side of egde
		if((y1>=pt.y) != (y2>=pt.y))
		{	crossings+= (y2-y1>=0.) ? d>=0. : d<=0. ;
		}
		
		// if d is 0, check if point is on line (and thus in polygon
		if(!d && fmin(x1,x2)<=pt.x && pt.x<=fmax(x1,x2) &&
				 fmin(y1,y2)<=pt.y && pt.y<=fmax(y1,y2))
		{	return(1);
		}
	}
	return crossings & 0x01;
}
Пример #5
0
/*	Calculate area of element (in mm^2 because nodes in mm)
	nodes is pointer to 0-based array NodalPoints
*/
double Quad2D::GetArea(void) const
{
	short i,ns=NumberSides(),nn=NumberNodes()-1;
	double area;
	
	area=0.;
	for(i=0;i<ns-1;i++)
	{	area+=nd[nodes[i]]->x*nd[nodes[i+ns]]->y
					-nd[nodes[i]]->y*nd[nodes[i+ns]]->x
					+nd[nodes[i+ns]]->x*nd[nodes[i+1]]->y
					-nd[nodes[i+ns]]->y*nd[nodes[i+1]]->x;
	}
	ns--;
	area+=nd[nodes[ns]]->x*nd[nodes[nn]]->y
				-nd[nodes[ns]]->y*nd[nodes[nn]]->x
				+nd[nodes[nn]]->x*nd[nodes[0]]->y
				-nd[nodes[nn]]->y*nd[nodes[0]]->x;
	return area/2.;
}
Пример #6
0
// If needed, create the neighbors array (only done for 2D with cracks)
void ElementBase::AllocateNeighborsArray(void)
{	neighbors = new int[NumberSides()];
	int i;
	for(i=0;i<NumberSides();i++)
		neighbors[i]=UNKNOWN_NEIGHBOR;
}
Пример #7
0
// return dimensionless location for material points
void ElementBase::MPMPoints(short numPerElement,Vector *mpos) const
{
    int i,j,k;
    double fxn[MaxElNd],row,zrow;
    
    if(NumberSides()==4)
    {	switch(numPerElement)
        {   case 4:
                // ENI or FNI - 2D only
                mpos[0].x=-.5;
                mpos[0].y=-.5;
                mpos[0].z=0.;
                mpos[1].x=.5;
                mpos[1].y=-.5;
                mpos[1].z=0.;
                mpos[2].x=-.5;
                mpos[2].y=.5;
                mpos[2].z=0.;
                mpos[3].x=.5;
                mpos[3].y=.5;
                mpos[3].z=0.;
                break;
            case 1:
                // CM of square or brick
                mpos[0].x=0.;
                mpos[0].y=0.;
				mpos[0].z=0.;
				break;
			case 8:
				// 3D box
                mpos[0].x=-.5;
                mpos[0].y=-.5;
				mpos[0].z=-.5;
                mpos[1].x=.5;
                mpos[1].y=-.5;
				mpos[1].z=-.5;
                mpos[2].x=-.5;
                mpos[2].y=.5;
				mpos[2].z=-.5;
                mpos[3].x=.5;
                mpos[3].y=.5;
				mpos[3].z=-.5;
                mpos[4].x=-.5;
                mpos[4].y=-.5;
				mpos[4].z=.5;
                mpos[5].x=.5;
                mpos[5].y=-.5;
				mpos[5].z=.5;
                mpos[6].x=-.5;
                mpos[6].y=.5;
				mpos[6].z=.5;
                mpos[7].x=.5;
                mpos[7].y=.5;
				mpos[7].z=.5;
				break;
            case 9:
                // 2D
                k=0;
                row = -2./3.;
                for(j=0;j<3;j++)
                {   mpos[k].x=-2./3.;
                    mpos[k].y=row;
                    mpos[k].z=0.;
                    mpos[k+1].x=0.;
                    mpos[k+1].y=row;
                    mpos[k+1].z=0.;
                    mpos[k+2].x=2./3.;
                    mpos[k+2].y=row;
                    mpos[k+2].z=0.;
                    k += 3;
                    row += 2./3.;
                }
                break;
            case 16:
                // 2D
                k=0;
                row = -0.75;
                for(j=0;j<4;j++)
                {   mpos[k].x=-0.75;
                    mpos[k].y=row;
                    mpos[k].z=0.;
                    mpos[k+1].x=-.25;
                    mpos[k+1].y=row;
                    mpos[k+1].z=0.;
                    mpos[k+2].x=.25;
                    mpos[k+2].y=row;
                    mpos[k+2].z=0.;
                    mpos[k+3].x=.75;
                    mpos[k+3].y=row;
                    mpos[k+3].z=0.;
                    k += 4;
                    row += 0.5;
                }
                break;
            case 25:
                // 2D
                k=0;
                row = -0.8;
                for(j=0;j<5;j++)
                {   mpos[k].x=-0.8;
                    mpos[k].y=row;
                    mpos[k].z=0.;
                    mpos[k+1].x=-.4;
                    mpos[k+1].y=row;
                    mpos[k+1].z=0.;
                    mpos[k+2].x=0.;
                    mpos[k+2].y=row;
                    mpos[k+2].z=0.;
                    mpos[k+3].x=.4;
                    mpos[k+3].y=row;
                    mpos[k+3].z=0.;
                    mpos[k+4].x=.8;
                    mpos[k+4].y=row;
                    mpos[k+4].z=0.;
                    k += 5;
                    row += 0.4;
                }
                break;
            case 27:
                // 3D
                k=0;
                zrow = -2./3.;
                for(i=0;i<3;i++)
                {   row = -2./3.;
                    for(j=0;j<3;j++)
                    {   mpos[k].x=-2./3.;
                        mpos[k].y=row;
                        mpos[k].z=zrow;
                        mpos[k+1].x=0.;
                        mpos[k+1].y=row;
                        mpos[k+1].z=zrow;
                        mpos[k+2].x=2./3.;
                        mpos[k+2].y=row;
                        mpos[k+2].z=zrow;
                        k += 3;
                        row += 2./3.;
                    }
                    zrow += 2./3.;
                }
                break;
            default:
                throw CommonException("Invalid number of material points per element.","ElementBase::MPMPoints");
                break;
        }
    }
    
    // covert to x-y-z locations
    for(k=0;k<numPerElement;k++)
    {	ShapeFunction(&mpos[k],FALSE,fxn,NULL,NULL,NULL);
		ZeroVector(&mpos[k]);
        for(j=0;j<NumberNodes();j++)
        {   mpos[k].x+=nd[nodes[j]]->x*fxn[j];
            mpos[k].y+=nd[nodes[j]]->y*fxn[j];
            mpos[k].z+=nd[nodes[j]]->z*fxn[j];
        }
    }
}