Пример #1
0
const Vector&
PFEMElement3D::getResistingForceIncInertia()
{
    // resize P
    int ndf = this->getNumDOF();
    P.resize(ndf);
    P.Zero();

    // get velocity, accleration
    Vector v(ndf), vdot(ndf);
    for(int i=0; i<4; i++) {
        const Vector& accel = nodes[2*i]->getTrialAccel();
        vdot(numDOFs(2*i)) = accel(0);
        vdot(numDOFs(2*i)+1) = accel(1);
        vdot(numDOFs(2*i)+2) = accel(2);

        const Vector& vel = nodes[2*i]->getTrialVel();
        v(numDOFs(2*i)) = vel(0);
        v(numDOFs(2*i)+1) = vel(1);
        v(numDOFs(2*i)+2) = vel(2);

        const Vector& vel2 = nodes[2*i+1]->getTrialVel();
        v(numDOFs(2*i+1)) = vel2(0);
        v(numDOFs(2*i+1)+1) = vel2(1);
        v(numDOFs(2*i+1)+2) = vel2(2);
        v(numDOFs(2*i+1)+3) = vel2(3);
    }

    double d = v.Norm();
    if(d!=d) opserr<<"v "<<this->getTag()<<"\n";
    d = vdot.Norm();
    if(d!=d) opserr<<"vdot "<<this->getTag()<<"\n";

    P.addMatrixVector(1.0, getMass(), vdot, 1.0);
    P.addMatrixVector(1.0, getDampWithK(), v, 1.0);

    Vector ones(ndf); 
    for(int i=0;i<ndf;i++) ones(i) = 1.0;
    Vector Q1(ndf), Q2(ndf);
    Q1.addMatrixVector(1.0, getMass(), ones, 1.0);
    Q2.addMatrixVector(1.0, getDampWithK(), ones, 1.0);
    d = Q1.Norm();
    if(d!=d) opserr<<"mass "<<this->getTag()<<"\n";
    d = Q2.Norm();
    if(d!=d) {
        opserr<<"damp "<<this->getTag()<<"\n";
        exit(1);
    }

    // get Jacobi
    for(int i=0; i<4; i++) {
        P(numDOFs(2*i)) -= rho*bx/24.*J;
        P(numDOFs(2*i)+1) -= rho*by/24.*J;
        P(numDOFs(2*i)+2) -= rho*bz/24.*J;
    }


    return P;
}
Пример #2
0
const Vector &
SSPquadUP::getResistingForceIncInertia()
{
	// terms stemming from acceleration
	const Vector &accel1 = theNodes[0]->getTrialAccel();
	const Vector &accel2 = theNodes[1]->getTrialAccel();
	const Vector &accel3 = theNodes[2]->getTrialAccel();
	const Vector &accel4 = theNodes[3]->getTrialAccel();
	
	// compute current resisting force
	this->getResistingForce();

	// compute mass matrix
	this->getMass();

	Vector a(12);
	a(0)  = accel1(0);
	a(1)  = accel1(1);
	a(2)  = accel1(2);
	a(3)  = accel2(0);
	a(4)  = accel2(1);
	a(5)  = accel2(2);
	a(6)  = accel3(0);
	a(7)  = accel3(1);
	a(8)  = accel3(2);
	a(9)  = accel4(0);
	a(10) = accel4(1);
	a(11) = accel4(2);

	mInternalForces.addMatrixVector(1.0, mMass, a, 1.0);

	// terms stemming from velocity
	const Vector &vel1 = theNodes[0]->getTrialVel();
	const Vector &vel2 = theNodes[1]->getTrialVel();
	const Vector &vel3 = theNodes[2]->getTrialVel();
	const Vector &vel4 = theNodes[3]->getTrialVel();
	
	Vector v(12);
	v(0)  = vel1(0);
	v(1)  = vel1(1);
	v(2)  = vel1(2);
	v(3)  = vel2(0);
	v(4)  = vel2(1);
	v(5)  = vel2(2);
	v(6)  = vel3(0);
	v(7)  = vel3(1);
	v(8)  = vel3(2);
	v(9)  = vel4(0);
	v(10) = vel4(1);
	v(11) = vel4(2);

	// compute damping matrix
	this->getDamp();

	mInternalForces.addMatrixVector(1.0, mDamp, v, 1.0);

	return mInternalForces;
}
/*!
  Returns the correct coefficient of friction for this contact.  If either
  body is dynamic, and the relative velocity between them is greater than
  1.0 mm/sec (should be made a parameter), then it returns the kinetic COF,
  otherwise it returns the static COF.
*/
double
Contact::getCof() const
{
  DynamicBody *db;
  vec3 radius,vel1(vec3::ZERO),vel2(vec3::ZERO),rotvel;

  if (body1->isDynamic()) {
    db = (DynamicBody *)body1;
    radius = db->getTran().rotation() * (loc - db->getCoG());
    vel1.set(db->getVelocity()[0],db->getVelocity()[1],db->getVelocity()[2]);
    rotvel.set(db->getVelocity()[3],db->getVelocity()[4],db->getVelocity()[5]);
    vel1 += radius * rotvel;
  }
  if (body2->isDynamic()) {
    db = (DynamicBody *)body2;
    radius = db->getTran().rotation() * (mate->loc - db->getCoG());
    vel2.set(db->getVelocity()[0],db->getVelocity()[1],db->getVelocity()[2]);
    rotvel.set(db->getVelocity()[3],db->getVelocity()[4],db->getVelocity()[5]);
    vel2 += radius * rotvel;
  }
  if ((vel1 - vel2).len() > 1.0) {
    DBGP("SLIDING!");
    return kcof;
  }
  else return cof;
}
Пример #4
0
int TwoNodeLink::update()
{
    int errCode = 0;
    
    // get global trial response
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    
    int numDOF2 = numDOF/2;
    Vector ug(numDOF), ugdot(numDOF), uldot(numDOF);
    for (int i=0; i<numDOF2; i++)  {
        ug(i)         = dsp1(i);  ugdot(i)         = vel1(i);
        ug(i+numDOF2) = dsp2(i);  ugdot(i+numDOF2) = vel2(i);
    }
    
    // transform response from the global to the local system
    ul.addMatrixVector(0.0, Tgl, ug, 1.0);
    uldot.addMatrixVector(0.0, Tgl, ugdot, 1.0);
    
    // transform response from the local to the basic system
    ub.addMatrixVector(0.0, Tlb, ul, 1.0);
    ubdot.addMatrixVector(0.0, Tlb, uldot, 1.0);
    //ub = (Tlb*Tgl)*ug;
    //ubdot = (Tlb*Tgl)*ugdot;
    
    // set trial response for material models
    for (int i=0; i<numDir; i++)
        errCode += theMaterials[i]->setTrialStrain(ub(i),ubdot(i));
    
    return errCode;
}
Пример #5
0
CollisionAttributes Hurtbox::resolveHurtboxCollision(Hurtbox* hb,
                                                     MapObject* obj1, MapObject* obj2) {
    CollisionAttributes c(obj1);
    // Very simple bouncing simulation, utilizing the property of total elastic collision
    // The resulting angles are not entirely correct at this point
    double mass1 = 1, mass2 = 1; // Mass should be determined in each MapObject later
    Vector2D vel1(obj1->getXVel(), obj1->getYVel());
    Vector2D vel2(obj2->getXVel(), obj2->getYVel());
    // Calculate the new velocities
    Vector2D newVel = (vel1 * (mass1 - mass2) + vel2 * 2 * mass2) / (mass1 + mass2);
    Vector2D* finalVel = new Vector2D(newVel.getX(), newVel.getY());
    c.setVelocity(finalVel);
    return c;
}
Пример #6
0
const Vector&
PFEMElement2DBubble::getResistingForceIncInertia()
{

    // resize P
    int ndf = this->getNumDOF();
    P.resize(ndf);
    P.Zero();

    // get velocity, accleration
    Vector v(ndf), vdot(ndf);
    for(int i=0; i<3; i++) {
        const Vector& accel = nodes[2*i]->getTrialAccel();
        vdot(numDOFs(2*i)) = accel(0);
        vdot(numDOFs(2*i)+1) = accel(1);

        const Vector& accel2 = nodes[2*i+1]->getTrialAccel();  // pressure
        vdot(numDOFs(2*i+1)) = accel2(0);

        const Vector& vel = nodes[2*i]->getTrialVel();
        v(numDOFs(2*i)) = vel(0);
        v(numDOFs(2*i)+1) = vel(1);

        const Vector& vel2 = nodes[2*i+1]->getTrialVel();   // pressure
        v(numDOFs(2*i+1)) = vel2(0);

    }

    // bubble force
    Vector fp(3);
    getFp(fp);

    // internal force
    P.addMatrixVector(1.0, getMass(), vdot, 1.0);
    P.addMatrixVector(1.0, getDamp(), v, 1.0);

    // external force
    Vector F(6);
    getF(F);
    for(int i=0; i<3; i++) {
        P(numDOFs(2*i)) -= F(2*i);
        P(numDOFs(2*i)+1) -= F(2*i+1);
        P(numDOFs(2*i+1)) -= fp(i);
    }

    //opserr<<"F = "<<F;
    return P;
}
Пример #7
0
double
Truss::computeCurrentStrainRate(void) const
{
    // NOTE method will not be called if L == 0

    // determine the strain
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();	

    double dLength = 0.0;
    for (int i = 0; i < dimension; i++)
      dLength += (vel2(i)-vel1(i))*cosX[i];

    // this method should never be called with L == 0
    return dLength/L;
}
Пример #8
0
int EETruss::update()
{
    int rValue = 0;
    
    // get current time
    Domain *theDomain = this->getDomain();
    (*t)(0) = theDomain->getCurrentTime();
    
    // determine dsp, vel and acc in basic system
    const Vector &disp1 = theNodes[0]->getTrialDisp();
    const Vector &disp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    const Vector &accel1 = theNodes[0]->getTrialAccel();
    const Vector &accel2 = theNodes[1]->getTrialAccel();
    const Vector &dispIncr1 = theNodes[0]->getIncrDeltaDisp();
    const Vector &dispIncr2 = theNodes[1]->getIncrDeltaDisp();
    
    (*db)(0) = (*vb)(0) = (*ab)(0) = 0.0;
    double dbDelta = 0.0;
    for (int i=0; i<numDIM; i++)  {
        (*db)(0) += (disp2(i)-disp1(i))*cosX[i];
        (*vb)(0) += (vel2(i)-vel1(i))*cosX[i];
        (*ab)(0) += (accel2(i)-accel1(i))*cosX[i];
        dbDelta  += (dispIncr2(i)-dispIncr1(i))*cosX[i];
    }
    
    // do not check time for right now because of transformation constraint
    // handler calling update at beginning of new step when applying load
    // if (fabs(dbDelta) > DBL_EPSILON || (*t)(0) > tLast)  {
    if (fabs(dbDelta) > DBL_EPSILON)  {
        // set the trial response at the site
        if (theSite != 0)  {
            theSite->setTrialResponse(db, vb, ab, (Vector*)0, t);
        }
        else  {
            sData[0] = OF_RemoteTest_setTrialResponse;
            rValue += theChannel->sendVector(0, 0, *sendData, 0);
        }
    }
    
    // save the last time
    tLast = (*t)(0);
    
    return rValue;
}
Пример #9
0
const Vector &
PDeltaCrdTransf2d::getBasicTrialVel(void)
{
	// determine global velocities
	const Vector &vel1 = nodeIPtr->getTrialVel();
	const Vector &vel2 = nodeJPtr->getTrialVel();
	
	static double vg[6];
	for (int i = 0; i < 3; i++) {
		vg[i]   = vel1(i);
		vg[i+3] = vel2(i);
	}
	
	static Vector vb(3);
	
	double oneOverL = 1.0/L;
	double sl = sinTheta*oneOverL;
	double cl = cosTheta*oneOverL;
	
	vb(0) = -cosTheta*vg[0] - sinTheta*vg[1] +
		cosTheta*vg[3] + sinTheta*vg[4];
	
	vb(1) = -sl*vg[0] + cl*vg[1] + vg[2] +
		sl*vg[3] - cl*vg[4];
	
	if (nodeIOffset != 0) {
		double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
		double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
		vb(0) -= t02*vg[2];
		vb(1) += oneOverL*t12*vg[2];
	}
	
	if (nodeJOffset != 0) {
		double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
		double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
		vb(0) += t35*vg[5];
		vb(1) -= oneOverL*t45*vg[5];
	}
	
	vb(2) = vb(1) + vg[5] - vg[2];
	
	return vb;
}
const Vector&
PFEMElement2DCompressible::getResistingForceIncInertia()
{

    // resize P
    int ndf = this->getNumDOF();
    P.resize(ndf);
    P.Zero();

    // get velocity, accleration
    Vector v(ndf), vdot(ndf);
    for(int i=0; i<3; i++) {
        const Vector& accel = nodes[2*i]->getTrialAccel();
        vdot(numDOFs(2*i)) = accel(0);
        vdot(numDOFs(2*i)+1) = accel(1);

        const Vector& accel2 = nodes[2*i+1]->getTrialAccel();
        vdot(numDOFs(2*i+1)) = accel2(0);

        const Vector& vel = nodes[2*i]->getTrialVel();
        v(numDOFs(2*i)) = vel(0);
        v(numDOFs(2*i)+1) = vel(1);

        const Vector& vel2 = nodes[2*i+1]->getTrialVel();
        v(numDOFs(2*i+1)) = vel2(0);
    }

    // Ma+k1v-Gp
    // Gt*v+Mp*p
    P.addMatrixVector(1.0, getMass(), vdot, 1.0);
    P.addMatrixVector(1.0, getDamp(), v, 1.0);

    // f
    double J2 = J/2.0;
    for(int i=0; i<3; i++) {
        P(numDOFs(2*i)) -= rho*bx/3.*J2;
        P(numDOFs(2*i)+1) -= rho*by/3.*J2;
    }


    return P;
}
Пример #11
0
bool Game::init()
{
	mShouldExit = false;

	//create Timers
	mpLoopTimer = new Timer;
	mpMasterTimer = new Timer;

	//startup allegro
	if(!al_init()) 
	{
		fprintf(stderr, "failed to initialize allegro!\n");
		return false;
	}

	//create and init GraphicsSystem
	mpGraphicsSystem = new GraphicsSystem();
	bool goodGraphics = mpGraphicsSystem->init( WIDTH, HEIGHT );
	if(!goodGraphics) 
	{
		fprintf(stderr, "failed to initialize GraphicsSystem object!\n");
		return false;
	}

	mpGraphicsBufferManager = new GraphicsBufferManager();
	mpSpriteManager = new SpriteManager();

	//startup a lot of allegro stuff

	//load image loader addon
	if( !al_init_image_addon() )
	{
		fprintf(stderr, "image addon failed to load!\n");
		return false;
	}

	//install audio stuff
	if( !al_install_audio() )
	{
		fprintf(stderr, "failed to initialize sound!\n");
		return false;
	}

	if(!al_init_acodec_addon())
	{
		fprintf(stderr, "failed to initialize audio codecs!\n");
		return false;
	}
 
	if (!al_reserve_samples(1))
	{
		fprintf(stderr, "failed to reserve samples!\n");
		return false;
	}

	//should probably be done in the InputSystem!
	if( !al_install_keyboard() )
	{
		printf( "Keyboard not installed!\n" ); 
		return false;
	}

	//should probably be done in the InputSystem!
	if( !al_install_mouse() )
	{
		printf( "Mouse not installed!\n" ); 
		return false;
	}

	//should be somewhere else!
	al_init_font_addon();
	if( !al_init_ttf_addon() )
	{
		printf( "ttf font addon not initted properly!\n" ); 
		return false;
	}

	//actually load the font
	mpFont = al_load_ttf_font( "cour.ttf", 20, 0 );
	if( mpFont == NULL )
	{
		printf( "ttf font file not loaded properly!\n" ); 
		return false;
	}

	//show the mouse
	if( !al_hide_mouse_cursor( mpGraphicsSystem->getDisplay() ) )
	{
		printf( "Mouse cursor not able to be hidden!\n" ); 
		return false;
	}

	if( !al_init_primitives_addon() )
	{
		printf( "Primitives addon not added!\n" ); 
		return false;
	}

	//load the sample
	mpSample = al_load_sample( "clapping.wav" );
	if (!mpSample)
	{
		printf( "Audio clip sample not loaded!\n" ); 
		return false;
	}

	mpMessageManager = new GameMessageManager();

	//load buffers
	mBackgroundBufferID = mpGraphicsBufferManager->loadBuffer("wallpaper.bmp");
	mPlayerIconBufferID = mpGraphicsBufferManager->loadBuffer("arrow.bmp");
	mEnemyIconBufferID = mpGraphicsBufferManager->loadBuffer("enemy-arrow.bmp");
	
	//setup sprites
	GraphicsBuffer* pBackGroundBuffer = mpGraphicsBufferManager->getBuffer( mBackgroundBufferID );
	if( pBackGroundBuffer != NULL )
	{
		mpSpriteManager->createAndManageSprite( BACKGROUND_SPRITE_ID, pBackGroundBuffer, 0, 0, pBackGroundBuffer->getWidth(), pBackGroundBuffer->getHeight() );
	}
	GraphicsBuffer* pPlayerBuffer = mpGraphicsBufferManager->getBuffer( mPlayerIconBufferID );
	Sprite* pArrowSprite = NULL;
	if( pPlayerBuffer != NULL )
	{
		pArrowSprite = mpSpriteManager->createAndManageSprite( PLAYER_ICON_SPRITE_ID, pPlayerBuffer, 0, 0, pPlayerBuffer->getWidth(), pPlayerBuffer->getHeight() );
	}
	GraphicsBuffer* pAIBuffer = mpGraphicsBufferManager->getBuffer( mEnemyIconBufferID );
	Sprite* pEnemyArrow = NULL;
	if( pAIBuffer != NULL )
	{
		pEnemyArrow = mpSpriteManager->createAndManageSprite( AI_ICON_SPRITE_ID, pAIBuffer, 0, 0, pAIBuffer->getWidth(), pAIBuffer->getHeight() );
	}

	//setup units
	Vector2D pos( 0.0f, 0.0f );
	Vector2D vel( 0.0f, 0.0f );
	mpUnit = new KinematicUnit( pArrowSprite, pos, 1, vel, 0.0f, 200.0f, 10.0f );
	
	Vector2D pos2( 1000.0f, 500.0f );
	Vector2D vel2( 0.0f, 0.0f );
	mpAIUnit = new KinematicUnit( pEnemyArrow, pos2, 1, vel2, 0.0f, 180.0f, 100.0f );
	//give steering behavior
	mpAIUnit->dynamicArrive( mpUnit ); 

	Vector2D pos3( 500.0f, 500.0f );
	mpAIUnit2 = new KinematicUnit( pEnemyArrow, pos3, 1, vel2, 0.0f, 180.0f, 100.0f );
	//give steering behavior
	mpAIUnit2->dynamicSeek( mpUnit );  

	return true;
}
Пример #12
0
int EETrussCorot::update()
{
    int rValue = 0;
    
    // get current time
    Domain *theDomain = this->getDomain();
    (*t)(0) = theDomain->getCurrentTime();
    
    // determine dsp, vel and acc in basic system
    const Vector &disp1 = theNodes[0]->getTrialDisp();
    const Vector &disp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    const Vector &accel1 = theNodes[0]->getTrialAccel();
    const Vector &accel2 = theNodes[1]->getTrialAccel();
    const Vector &dispIncr1 = theNodes[0]->getIncrDeltaDisp();
    const Vector &dispIncr2 = theNodes[1]->getIncrDeltaDisp();
    
    // initial offsets
    double d21Last[3];
    d21[0] = L; d21[1] = d21[2] = 0.0;
    v21[0] = v21[1] = v21[2] = 0.0;
    a21[0] = a21[1] = a21[2] = 0.0;
    d21Last[0] = L; d21Last[1] = d21Last[2] = 0.0;
    
    // update offsets in basic system
    for (int i=0; i<numDIM; i++)  {
        double deltaDisp = disp2(i) - disp1(i);
        d21[0] += deltaDisp*R(0,i);
        d21[1] += deltaDisp*R(1,i);
        d21[2] += deltaDisp*R(2,i);
        double deltaVel = vel2(i) - vel1(i);
        v21[0] += deltaVel*R(0,i);
        v21[1] += deltaVel*R(1,i);
        v21[2] += deltaVel*R(2,i);
        double deltaAccel = accel2(i) - accel1(i);
        a21[0] += deltaAccel*R(0,i);
        a21[1] += deltaAccel*R(1,i);
        a21[2] += deltaAccel*R(2,i);
        double deltaDispLast = (disp2(i)-dispIncr2(i))
                             - (disp1(i)-dispIncr1(i));
        d21Last[0] += deltaDispLast*R(0,i);
        d21Last[1] += deltaDispLast*R(1,i);
        d21Last[2] += deltaDispLast*R(2,i);
    }
    
    // compute new length and deformation
    Ln = sqrt(d21[0]*d21[0] + d21[1]*d21[1] + d21[2]*d21[2]);
    double c1 = d21[0]*v21[0] + d21[1]*v21[1] + d21[2]*v21[2];
    double c2 = v21[0]*v21[0] + v21[1]*v21[1] + v21[2]*v21[2]
              + d21[0]*a21[0] + d21[1]*a21[1] + d21[2]*a21[2];
    (*db)(0) = Ln - L;
    (*vb)(0) = c1/Ln;
    (*ab)(0) = c2/Ln - (c1*c1)/(Ln*Ln*Ln);
    double LnLast = sqrt(d21Last[0]*d21Last[0] + d21Last[1]*d21Last[1]
                  + d21Last[2]*d21Last[2]);
    double dbDelta = (Ln - L) - (LnLast - L);

    // do not check time for right now because of transformation constraint
    // handler calling update at beginning of new step when applying load
    // if (fabs(dbDelta) > DBL_EPSILON || (*t)(0) > tLast)  {
    if (fabs(dbDelta) > DBL_EPSILON)  {
        // set the trial response at the site
        if (theSite != 0)  {
            theSite->setTrialResponse(db, vb, ab, (Vector*)0, t);
        }
        else  {
            sData[0] = OF_RemoteTest_setTrialResponse;
            rValue += theChannel->sendVector(0, 0, *sendData, 0);
        }
    }
    
    // save the last time
    tLast = (*t)(0);
    
    return rValue;
}
int ElastomericBearingBoucWen2d::update()
{
    // get global trial displacements and velocities
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    
    static Vector ug(6), ugdot(6), uldot(6), ubdot(3);
    for (int i=0; i<3; i++)  {
        ug(i)   = dsp1(i);  ugdot(i)   = vel1(i);
        ug(i+3) = dsp2(i);  ugdot(i+3) = vel2(i);
    }
    
    // transform response from the global to the local system
    ul.addMatrixVector(0.0, Tgl, ug, 1.0);
    uldot.addMatrixVector(0.0, Tgl, ugdot, 1.0);
    
    // transform response from the local to the basic system
    ub.addMatrixVector(0.0, Tlb, ul, 1.0);
    ubdot.addMatrixVector(0.0, Tlb, uldot, 1.0);
    
    // 1) get axial force and stiffness in basic x-direction
    theMaterials[0]->setTrialStrain(ub(0), ubdot(0));
    qb(0) = theMaterials[0]->getStress();
    kb(0,0) = theMaterials[0]->getTangent();
    
    // 2) calculate shear force and stiffness in basic y-direction
    // get displacement increment (trial - commited)
    double delta_ub = ub(1) - ubC(1);
    if (fabs(delta_ub) > 0.0)  {
        
        // get yield displacement
        double uy = qYield/k0;
        
        // calculate hysteretic evolution parameter z using Newton-Raphson
        int iter = 0;
        double zAbs, tmp1, f, Df, delta_z;
        do  {
            zAbs = fabs(z);
            if (zAbs == 0.0)    // check because of negative exponents
                zAbs = DBL_EPSILON;
            tmp1 = gamma + beta*sgn(z*delta_ub);
            
            // function and derivative
            f  = z - zC - delta_ub/uy*(A - pow(zAbs,eta)*tmp1);
            Df = 1.0 + delta_ub/uy*eta*pow(zAbs,eta-1.0)*sgn(z)*tmp1;
            
            // issue warning if derivative Df is zero
            if (fabs(Df) <= DBL_EPSILON)  {
                opserr << "WARNING: ElastomericBearingBoucWen2d::update() - "
                    << "zero derivative in Newton-Raphson scheme for "
                    << "hysteretic evolution parameter z.\n";
                return -1;
            }
            
            // advance one step
            delta_z = f/Df;
            z -= delta_z;
            iter++;
        } while ((fabs(delta_z) >= tol) && (iter < maxIter));
        
        // issue warning if Newton-Raphson scheme did not converge
        if (iter >= maxIter)   {
            opserr << "WARNING: ElastomericBearingBoucWen2d::update() - "
                << "did not find the hysteretic evolution parameter z after "
                << iter << " iterations and norm: " << fabs(delta_z) << endln;
            return -2;
        }
        
        // get derivative of hysteretic evolution parameter * uy
        dzdu = A - pow(fabs(z),eta)*(gamma + beta*sgn(z*delta_ub));
        // set shear force
        qb(1) = qYield*z + k2*ub(1) + k3*sgn(ub(1))*pow(fabs(ub(1)),mu);
        // set tangent stiffness
        kb(1,1) = k0*dzdu + k2 + k3*mu*pow(fabs(ub(1)),mu-1.0);
    }
    
    // 3) get moment and stiffness about basic z-direction
    theMaterials[1]->setTrialStrain(ub(2), ubdot(2));
    qb(2) = theMaterials[1]->getStress();
    kb(2,2) = theMaterials[1]->getTangent();
    
    return 0;
}
Пример #14
0
const Vector &
PFEMElement2DBubble::getResistingForceSensitivity(int gradnumber)
{
    // resize P
    int ndf = this->getNumDOF();
    P.resize(ndf);
    P.Zero();

    Vector dF(6), dFp(3), vdot(6), v(6), p(3), du(6);
    for(int i=0; i<3; i++) {
        const Vector& accel = nodes[2*i]->getTrialAccel();
        vdot(2*i) = accel(0);
        vdot(2*i+1) = accel(1);

        const Vector& vel = nodes[2*i]->getTrialVel();
        v(2*i) = vel(0);
        v(2*i+1) = vel(1);

        const Vector& vel2 = nodes[2*i+1]->getTrialVel();   // pressure
        p(i) = vel2(0);

        du(2*i) = nodes[2*i]->getDispSensitivity(1,gradnumber);
        du(2*i+1) = nodes[2*i]->getDispSensitivity(2,gradnumber);
    }
    
    // consditional sensitivity
    getdF(dF);
    double dm = getdM();
    dF.addVector(-1.0, vdot, dm);

    getdFp(dFp);
    Matrix dl;
    getdL(dl);
    dFp.addMatrixVector(-1.0, dl, p, 1.0);

    // geometric sensitivity
    Matrix dM, dg, df;
    getdM(vdot, dM);
    getdG(p, dg);
    getdF(df);
    dF.addMatrixVector(1.0, dM, du, 1.0);
    dF.addMatrixVector(1.0, dg, du, -1.0);
    dF.addMatrixVector(1.0, df, du, -1.0);

    Matrix dgt, dL, dfp;
    getdGt(v, dgt);
    getdL(p, dL);
    getdFp(dfp);
    dFp.addMatrixVector(1.0, dgt, du, 1.0);
    dFp.addMatrixVector(1.0, dL, du, 1.0);
    dFp.addMatrixVector(1.0, dfp, du, -1.0);

    // copy
    for(int i=0; i<3; i++) {
        P(numDOFs(2*i)) += dF(2*i);
        P(numDOFs(2*i)+1) += dF(2*i+1);
        P(numDOFs(2*i+1)) += dFp(i);
    }

    return P;
}
Пример #15
0
int ElastomericBearing2d::update()
{
    // get global trial displacements and velocities
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    
    static Vector ug(6), ugdot(6), uldot(6), ubdot(3);
    for (int i=0; i<3; i++)  {
        ug(i)   = dsp1(i);  ugdot(i)   = vel1(i);
        ug(i+3) = dsp2(i);  ugdot(i+3) = vel2(i);
    }
    
    // transform response from the global to the local system
    ul = Tgl*ug;
    uldot = Tgl*ugdot;
    
    // transform response from the local to the basic system
    ub = Tlb*ul;
    ubdot = Tlb*uldot;
    
    // 1) get axial force and stiffness in basic x-direction
    theMaterials[0]->setTrialStrain(ub(0),ubdot(0));
    qb(0) = theMaterials[0]->getStress();
    kb(0,0) = theMaterials[0]->getTangent();
    
    // 2) calculate shear force and stiffness in basic y-direction
    // get trial shear force of hysteretic component
    double qTrial = k0*(ub(1) - ubPlasticC);
    
    // compute yield criterion of hysteretic component
    double qTrialNorm = fabs(qTrial);
    double Y = qTrialNorm - qYield;
    
    // elastic step -> no updates required
    if (Y <= 0.0)  {
        // set shear force
        qb(1) = qTrial + k2*ub(1);
        // set tangent stiffness
        kb(1,1) = k0 + k2;
    }
    // plastic step -> return mapping
    else  {
        // compute consistency parameter
        double dGamma = Y/k0;
        // update plastic displacement
        ubPlastic = ubPlasticC + dGamma*qTrial/qTrialNorm;
        // set shear force
        qb(1) = qYield*qTrial/qTrialNorm + k2*ub(1);
        // set tangent stiffness
        kb(1,1) = k2;
    }
    
    // 3) get moment and stiffness in basic z-direction
    theMaterials[1]->setTrialStrain(ub(2),ubdot(2));
    qb(2) = theMaterials[1]->getStress();
    kb(2,2) = theMaterials[1]->getTangent();
    
    return 0;
}
Пример #16
0
int SingleFPSimple2d::update()
{
    // get global trial displacements and velocities
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
    const Vector &vel1 = theNodes[0]->getTrialVel();
    const Vector &vel2 = theNodes[1]->getTrialVel();
    
    static Vector ug(6), ugdot(6), uldot(6), ubdot(3);
    for (int i=0; i<3; i++)  {
        ug(i)   = dsp1(i);  ugdot(i)   = vel1(i);
        ug(i+3) = dsp2(i);  ugdot(i+3) = vel2(i);
    }
    
    // transform response from the global to the local system
    ul = Tgl*ug;
    uldot = Tgl*ugdot;
    
    // transform response from the local to the basic system
    ub = Tlb*ul;
    ubdot = Tlb*uldot;
    
    // get absolute velocity
    double ubdotAbs = sqrt(pow(ubdot(1)/Reff*ub(1),2) + pow(ubdot(1),2));
    
    // 1) get axial force and stiffness in basic x-direction
    double ub0Old = theMaterials[0]->getStrain();
    theMaterials[0]->setTrialStrain(ub(0),ubdot(0));
    qb(0) = theMaterials[0]->getStress();
    kb(0,0) = theMaterials[0]->getTangent();
    
    // check for uplift
    if (qb(0) >= 0.0)  {
        kb = kbInit;
        if (qb(0) > 0.0)  {
            theMaterials[0]->setTrialStrain(ub0Old,0.0);
            kb(0,0) *= DBL_EPSILON;
            kb(2,2) *= DBL_EPSILON;
            // update plastic displacement
            ubPlastic = ub(1);
        }
        qb.Zero();
        return 0;
    }
    
    // 2) calculate shear force and stiffness in basic y-direction
    int iter = 0;
    double qb1Old = 0.0;
    do  {
        // save old shear force
        qb1Old = qb(1);
        
        // get normal and friction (yield) forces
        double N = -qb(0) + qb(1)/Reff*ub(1) - qb(1)*ul(2);
        theFrnMdl->setTrial(N, ubdotAbs);
        double qYield = (theFrnMdl->getFrictionForce());
        
        // get stiffness of elastic component
        double k2 = N/Reff;
        // get initial stiffness of hysteretic component
        double k0 = qYield/uy;
        
        // get trial shear force of hysteretic component
        double qTrial = k0*(ub(1) - ubPlasticC);
        
        // compute yield criterion of hysteretic component
        double qTrialNorm = fabs(qTrial);
        double Y = qTrialNorm - qYield;
        
        // elastic step -> no updates required
        if (Y <= 0.0)  {
            // set shear force
            qb(1) = qTrial + k2*ub(1) - N*ul(2);
            // set tangent stiffness
            kb(1,1) = k0 + k2;
        }
        // plastic step -> return mapping
        else  {
            // compute consistency parameter
            double dGamma = Y/k0;
            // update plastic displacement
            ubPlastic = ubPlasticC + dGamma*qTrial/qTrialNorm;
            // set shear force
            qb(1) = qYield*qTrial/qTrialNorm + k2*ub(1) - N*ul(2);
            // set tangent stiffness
            kb(1,1) = k2;
        }
        iter++;
    } while ((fabs(qb(1)-qb1Old) >= tol) && (iter < maxIter));
    
    // issue warning if iteration did not converge
    if (iter >= maxIter)  {
        opserr << "WARNING: SingleFPSimple2d::update() - did not find the shear force after "
            << iter << " iterations and norm: " << fabs(qb(1)-qb1Old) << endln;
        return -1;
    }
    
    // 3) get moment and stiffness in basic z-direction
    theMaterials[1]->setTrialStrain(ub(2),ubdot(2));
    qb(2) = theMaterials[1]->getStress();
    kb(2,2) = theMaterials[1]->getTangent();
    
    return 0;
}
Пример #17
0
const Vector&
FourNodeQuadUP::getResistingForceIncInertia()
{
    int i, j, k;

    const Vector &accel1 = nd1Ptr->getTrialAccel();
    const Vector &accel2 = nd2Ptr->getTrialAccel();
    const Vector &accel3 = nd3Ptr->getTrialAccel();
    const Vector &accel4 = nd4Ptr->getTrialAccel();

    static double a[12];

    a[0] = accel1(0);
    a[1] = accel1(1);
    a[2] = accel1(2);
    a[3] = accel2(0);
    a[4] = accel2(1);
    a[5] = accel2(2);
    a[6] = accel3(0);
    a[7] = accel3(1);
    a[8] = accel3(2);
    a[9] = accel4(0);
    a[10] = accel4(1);
    a[11] = accel4(2);

    // Compute the current resisting force
    this->getResistingForce();
    //opserr<<"K "<<P<<endln;

    // Compute the mass matrix
    this->getMass();

    for (i = 0; i < 12; i++) {
        for (j = 0; j < 12; j++)
            P(i) += K(i,j)*a[j];
    }
    //opserr<<"K+M "<<P<<endln;

    // dynamic seepage force
    /*for (i = 0, k = 0; i < 4; i++, k += 3) {
      // loop over integration points
      for (j = 0; j < 4; j++) {
        P(i+2) -= rho*dvol[j]*(shp[2][i][j]*a[k]*perm[0]*shp[0][i][j]
    		     +shp[2][i][j]*a[k+1]*perm[1]*shp[1][i][j]);
      }
    }*/
    //opserr<<"K+M+fb "<<P<<endln;

    const Vector &vel1 = nd1Ptr->getTrialVel();
    const Vector &vel2 = nd2Ptr->getTrialVel();
    const Vector &vel3 = nd3Ptr->getTrialVel();
    const Vector &vel4 = nd4Ptr->getTrialVel();

    a[0] = vel1(0);
    a[1] = vel1(1);
    a[2] = vel1(2);
    a[3] = vel2(0);
    a[4] = vel2(1);
    a[5] = vel2(2);
    a[6] = vel3(0);
    a[7] = vel3(1);
    a[8] = vel3(2);
    a[9] = vel4(0);
    a[10] = vel4(1);
    a[11] = vel4(2);

    this->getDamp();

    for (i = 0; i < 12; i++) {
        for (j = 0; j < 12; j++) {
            P(i) += K(i,j)*a[j];
        }
    }
    //opserr<<"final "<<P<<endln;
    return P;
}