Esempio n. 1
0
int 
PFEMIntegrator::saveSensitivity(const Vector & dVNew,int gradNum,int numGrads)
{
    // Recover sensitivity results from previous step
    int vectorSize = U->Size();
    Vector dUn(vectorSize);
    dVn.resize(vectorSize); dVn.Zero();

    AnalysisModel *myModel = this->getAnalysisModel();
    DOF_GrpIter &theDOFs = myModel->getDOFs();
    DOF_Group *dofPtr;
    while ((dofPtr = theDOFs()) != 0) {
	  
        const ID &id = dofPtr->getID();
        int idSize = id.Size();
        const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);	
        for (int i=0; i < idSize; i++) {
	    int loc = id(i);
	    if (loc >= 0) {
                dUn(loc) = dispSens(i);		
	    }
        }
	  
        const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
        for (int i=0; i < idSize; i++) {
	    int loc = id(i);
	    if (loc >= 0) {
                dVn(loc) = velSens(i);
	    }
        }

    }


    // Compute new acceleration and velocity vectors:
    Vector dUNew(vectorSize);
    Vector dANew(vectorSize);

    // dudotdot = 1/dt*dv{n+1} - 1/dt*dvn
    dANew.addVector(0.0, dVNew, c3);
    dANew.addVector(1.0, dVn, -c3);

    // du       = dun + dt*dv{n+1}
    dUNew.addVector(0.0, dVNew, c1);
    dUNew.addVector(1.0, dUn, 1.0);

    // Now we can save vNew, vdotNew and vdotdotNew
    DOF_GrpIter &theDOFGrps = myModel->getDOFs();
    DOF_Group 	*dofPtr1;
    while ( (dofPtr1 = theDOFGrps() ) != 0)  {
        dofPtr1->saveSensitivity(dUNew,dVNew,dANew,gradNum,numGrads);
    }
	
    return 0;
}
int
NewmarkSensitivityIntegrator::formEleResidual(FE_Element *theEle)
{

	if (sensitivityFlag == 0) {  // NO SENSITIVITY ANALYSIS

		this->Newmark::formEleResidual(theEle);

	}
	else {  // (ASSEMBLE ALL TERMS)

		theEle->zeroResidual();

		// Compute the time-stepping parameters on the form
		// udotdot = a1*ui+1 + a2*ui + a3*udoti + a4*udotdoti
		// udot    = a5*ui+1 + a6*ui + a7*udoti + a8*udotdoti
		// (see p. 166 of Chopra)

		// The constants are:
		// a1 = 1.0/(beta*dt*dt)
		// a2 = -1.0/(beta*dt*dt)
		// a3 = -1.0/beta*dt
		// a4 = 1.0 - 1.0/(2.0*beta)
		// a5 = gamma/(beta*dt)
		// a6 = -gamma/(beta*dt)
		// a7 = 1.0 - gamma/beta
		// a8 = 1.0 - gamma/(2.0*beta)

		// We can make use of the data members c2 and c3 of this class. 
		// As long as disp==true, they are defined as:
		// c2 = gamma/(beta*dt)
		// c3 = 1.0/(beta*dt*dt)

		// So, the constants can be computed as follows:
		if (displ==false) {
			opserr << "ERROR: Newmark::formEleResidual() -- the implemented"
				<< " scheme only works if the displ variable is set to true." << endln;
		}
		double a2 = -c3;
		double a3 = -c2/gamma;
		double a4 = 1.0 - 1.0/(2.0*beta);
		double a6 = -c2;
		double a7 = 1.0 - gamma/beta;
		double dt = gamma/(beta*c2);
		double a8 = dt*(1.0 - gamma/(2.0*beta));


		// Obtain sensitivity vectors from previous step
		int vectorSize = U->Size();
		Vector V(vectorSize);
		Vector Vdot(vectorSize);
		Vector Vdotdot(vectorSize);
		int i, loc;

		AnalysisModel *myModel = this->getAnalysisModel();
		DOF_GrpIter &theDOFs = myModel->getDOFs();
		DOF_Group *dofPtr;
		while ((dofPtr = theDOFs()) != 0) {

			const ID &id = dofPtr->getID();
			int idSize = id.Size();
			const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);	
			for (i=0; i < idSize; i++) {
				loc = id(i);
				if (loc >= 0) {
					V(loc) = dispSens(i);		
				}
			}

			const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
			for (i=0; i < idSize; i++) {
				loc = id(i);
				if (loc >= 0) {
					Vdot(loc) = velSens(i);
				}
			}

			const Vector &accelSens = dofPtr->getAccSensitivity(gradNumber);	
			for (i=0; i < idSize; i++) {
				loc = id(i);
				if (loc >= 0) {
					Vdotdot(loc) = accelSens(i);
				}
			}
		}


		// Pre-compute the vectors involving a2, a3, etc.
		//Vector tmp1 = V*a2 + Vdot*a3 + Vdotdot*a4;
		Vector tmp1(vectorSize);
		tmp1.addVector(0.0, V, a2);
		tmp1.addVector(1.0, Vdot, a3);
		tmp1.addVector(1.0, Vdotdot, a4);
		//Vector tmp2 = V*a6 + Vdot*a7 + Vdotdot*a8;
		Vector tmp2(vectorSize);
		tmp2.addVector(0.0, V, a6);
		tmp2.addVector(1.0, Vdot, a7);
		tmp2.addVector(1.0, Vdotdot, a8);

		if (massMatrixMultiplicator == 0)
			massMatrixMultiplicator = new Vector(tmp1.Size());
		if (dampingMatrixMultiplicator == 0)
			dampingMatrixMultiplicator = new Vector(tmp2.Size());

		(*massMatrixMultiplicator) = tmp1;
		(*dampingMatrixMultiplicator) = tmp2;


		// Now we're ready to make calls to the FE Element:

		// The term -dPint/dh|u fixed
		theEle->addResistingForceSensitivity(gradNumber); 

		// The term -dM/dh*acc
		theEle->addM_ForceSensitivity(gradNumber, *Udotdot, -1.0);

		// The term -M*(a2*v + a3*vdot + a4*vdotdot)
		theEle->addM_Force(*massMatrixMultiplicator,-1.0);

		// The term -C*(a6*v + a7*vdot + a8*vdotdot)
		theEle->addD_Force(*dampingMatrixMultiplicator,-1.0);

		// The term -dC/dh*vel
		theEle->addD_ForceSensitivity(gradNumber, *Udot,-1.0);
		
	}

	return 0;
}
Esempio n. 3
0
int
PFEMIntegrator::formEleResidual(FE_Element *theEle)
{
    if (sensitivityFlag == 0) {  // NO SENSITIVITY ANALYSIS

        this->TransientIntegrator::formEleResidual(theEle);

    }
    else {  // (ASSEMBLE ALL TERMS)

        theEle->zeroResidual();

        // Compute the time-stepping parameters on the form
        // udotdot = 1/dt*vn+1 - 1/dt*vn
        // u       = un + dt*vn+1


        // Obtain sensitivity vectors from previous step
        dVn.resize(U->Size()); dVn.Zero();
        Vector dUn(U->Size());

        AnalysisModel *myModel = this->getAnalysisModel();
        DOF_GrpIter &theDOFs = myModel->getDOFs();
        DOF_Group *dofPtr = 0;
        while ((dofPtr = theDOFs()) != 0) {

            const ID &id = dofPtr->getID();
            int idSize = id.Size();

            const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);
            for (int i=0; i < idSize; i++) {
                int loc = id(i);
                if (loc >= 0) {
                    dUn(loc) = dispSens(i);
                }
            }

            const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
            for (int i=0; i < idSize; i++) {
                int loc = id(i);
                if (loc >= 0) {
                    dVn(loc) = velSens(i);
                }
            }
        }

        // Now we're ready to make calls to the FE Element:

        // The term -dPint/dh|u fixed
        theEle->addResistingForceSensitivity(gradNumber); 

        // The term -dM/dh*acc
        theEle->addM_ForceSensitivity(gradNumber, *Udotdot, -1.0);

        // The term -M*(-1/dt*dvn)
        theEle->addM_Force(dVn, c3);

        // The term -K*(dun)
        theEle->addK_Force(dUn, -1.0);

        // The term -dC/dh*vel
        theEle->addD_ForceSensitivity(gradNumber, *Udot,-1.0);
		
    }

    return 0;
}    
int 
NewmarkSensitivityIntegrator::saveSensitivity(const Vector & vNew,int gradNum,int numGrads)
{

	// Compute Newmark parameters in general notation
	double a1 = c3;
	double a2 = -c3;
	double a3 = -c2/gamma;
	double a4 = 1.0 - 1.0/(2.0*beta);
	double a5 = c2;
	double a6 = -c2;
	double a7 = 1.0 - gamma/beta;
	double dt = gamma/(beta*c2);
	double a8 = dt*(1.0 - gamma/(2.0*beta));


	// Recover sensitivity results from previous step
	int vectorSize = U->Size();
	Vector V(vectorSize);
	Vector Vdot(vectorSize);
	Vector Vdotdot(vectorSize);
	int i, loc;

	AnalysisModel *myModel = this->getAnalysisModel();
	DOF_GrpIter &theDOFs = myModel->getDOFs();
	DOF_Group *dofPtr;
	while ((dofPtr = theDOFs()) != 0) {
	  
	  const ID &id = dofPtr->getID();
	  int idSize = id.Size();
	  const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber);	
	  for (i=0; i < idSize; i++) {
	    loc = id(i);
	    if (loc >= 0) {
	      V(loc) = dispSens(i);		
	    }
	  }
	  
	  const Vector &velSens = dofPtr->getVelSensitivity(gradNumber);
	  for (i=0; i < idSize; i++) {
	    loc = id(i);
	    if (loc >= 0) {
	      Vdot(loc) = velSens(i);
	    }
	  }
	  
	  const Vector &accelSens = dofPtr->getAccSensitivity(gradNumber);	
	  for (i=0; i < idSize; i++) {
	    loc = id(i);
	    if (loc >= 0) {
	      Vdotdot(loc) = accelSens(i);
	    }
	  }
	}


	// Compute new acceleration and velocity vectors:
	Vector vdotNew(vectorSize);
	Vector vdotdotNew(vectorSize);
	//(*vdotdotNewPtr) = vNew*a1 + V*a2 + Vdot*a3 + Vdotdot*a4;
	vdotdotNew.addVector(0.0, vNew, a1);
	vdotdotNew.addVector(1.0, V, a2);
	vdotdotNew.addVector(1.0, Vdot, a3);
	vdotdotNew.addVector(1.0, Vdotdot, a4);
	//(*vdotNewPtr) = vNew*a5 + V*a6 + Vdot*a7 + Vdotdot*a8;
	vdotNew.addVector(0.0, vNew, a5);
	vdotNew.addVector(1.0, V, a6);
	vdotNew.addVector(1.0, Vdot, a7);
	vdotNew.addVector(1.0, Vdotdot, a8);

	// Now we can save vNew, vdotNew and vdotdotNew
	DOF_GrpIter &theDOFGrps = myModel->getDOFs();
	DOF_Group 	*dofPtr1;
	while ( (dofPtr1 = theDOFGrps() ) != 0)  {
	  dofPtr1->saveSensitivity(vNew,vdotNew,vdotdotNew,gradNum,numGrads);
	}
	
	return 0;
}