void
TensorMechanicsPlasticMohrCoulombMulti::dyieldFunction_dintnlV(const RankTwoTensor & stress, Real intnl, std::vector<Real> & df_dintnl) const
{
  std::vector<Real> eigvals;
  stress.symmetricEigenvalues(eigvals);
  eigvals[0] += _shift;
  eigvals[2] -= _shift;

  const Real sin_angle = std::sin(phi(intnl));
  const Real cos_angle = std::cos(phi(intnl));
  const Real dsin_angle = cos_angle*dphi(intnl);
  const Real dcos_angle = -sin_angle*dphi(intnl);
  const Real dcohcos = dcohesion(intnl)*cos_angle + cohesion(intnl)*dcos_angle;

  df_dintnl.resize(6);
  df_dintnl[0] = df_dintnl[1] = 0.5*(eigvals[0] + eigvals[1])*dsin_angle - dcohcos;
  df_dintnl[2] = df_dintnl[3] = 0.5*(eigvals[0] + eigvals[2])*dsin_angle - dcohcos;
  df_dintnl[4] = df_dintnl[5] = 0.5*(eigvals[1] + eigvals[2])*dsin_angle - dcohcos;
}
void TElemento0d::CalcStiff(TMalha &malha, TPZFMatrix& stiff, TPZFMatrix& rhs)
{
  stiff.Redim(1,1);
  rhs.Redim(1,1);
  std::vector<double> phi(1,1.);
  TPZFMatrix dphi(0,1);
  std::vector<double> point(0);
  Shape(point,phi,dphi);
  double weight = 1.;
  TMaterial *mat = malha.getMaterial(this->fMaterialId);
  mat->Contribute(point,weight,phi,dphi,stiff,rhs);
}
예제 #3
0
  //--------------------------------------------------------
  // apply feedback charges to atoms                        
  //--------------------------------------------------------
  void ChargeRegulatorMethodFeedback::apply_feedback_charges()
  {
    double * q = lammpsInterface_->atom_charge();
    // calculate error in potential on the control nodes
    
    const DENS_MAT & phiField = (atc_->field(ELECTRIC_POTENTIAL)).quantity();
    DENS_MAT dphi(nControlNodes_,1);
    int i = 0;
    set<int>::const_iterator itr;
    for (itr = controlNodes_.begin(); itr != controlNodes_.end(); itr++) {
      dphi(i++,0) = targetPhi_ - phiField(*itr,0);
    }

    // construct the atomic charges consistent with the correction
    DENS_MAT dq = NTinvNNTinvG_*dphi;
    i = 0;
    for (itr = influenceAtomsIds_.begin(); itr != influenceAtomsIds_.end(); itr++) {
      sum_(0) += dq(i,0); 
      q[*itr] += dq(i++,0); 
    }
    
    (interscaleManager_->fundamental_atom_quantity(LammpsInterface::ATOM_CHARGE))->force_reset();
    (interscaleManager_->fundamental_atom_quantity(LammpsInterface::ATOM_CHARGE, GHOST))->force_reset();
  }
예제 #4
0
// Second Approach
BzzVectorInt OpenSMOKE_Grid1D::QueryNewPointsGradient(const int nGrad, const double delta, BzzVector &phi)
{
	int i;

	BzzVector diffPhi(Ni);
	BzzVector dphi(Np);
	BzzVectorInt pointList;
	BzzVectorInt iList;
	BzzVector vList;

	int index;
	double maximumValue;

	FirstDerivative('C', phi, dphi);
	
	double maxValue = dphi.Max();
	double minValue = dphi.Min();
	double coefficient = delta*(maxValue-minValue);


	for(i=1;i<=Ni;i++)
		diffPhi[i] = fabs(dphi[i+1]-dphi[i]);


	for(i=1;i<=Ni;i++)
		if (diffPhi[i] > coefficient)
		{
			iList.Append(i);
			vList.Append(diffPhi[i]);
		}

	for(i=1;i<=min(iList.Size(), nGrad);i++)
	{
		maximumValue = vList.Max(&index);
		pointList.Append(iList[index]);
		vList[index] = -1.;
	}

	return pointList;
}
예제 #5
0
void TPZIncNavierStokesKEps::Contribute(TPZMaterialData &data,
                                        REAL weight,
                                        TPZFMatrix<REAL> &ek,
                                        TPZFMatrix<REAL> &ef){
	
    int numbersol = data.sol.size();
    if (numbersol != 1) {
        DebugStop();
    }

	TPZFMatrix<REAL> &dphi = data.dphix;
	// TPZFMatrix<REAL> &dphiL = data.dphixl;
	// TPZFMatrix<REAL> &dphiR = data.dphixr;
	TPZFMatrix<REAL> &phi = data.phi;
	// TPZFMatrix<REAL> &phiL = data.phil;
	// TPZFMatrix<REAL> &phiR = data.phir;
	// TPZManVector<REAL,3> &normal = data.normal;
	// TPZManVector<REAL,3> &x = data.x;
	// int &POrder=data.p;
	// int &LeftPOrder=data.leftp;
	// int &RightPOrder=data.rightp;
	TPZVec<REAL> &sol=data.sol[0];
	// TPZVec<REAL> &solL=data.soll;
	// TPZVec<REAL> &solR=data.solr;
	TPZFMatrix<REAL> &dsol=data.dsol[0];
	// TPZFMatrix<REAL> &dsolL=data.dsoll;
	// TPZFMatrix<REAL> &dsolR=data.dsolr;
	// REAL &faceSize=data.HSize;
	// TPZFMatrix<REAL> &daxesdksi=data.daxesdksi;
	// TPZFMatrix<REAL> &axes=data.axes;
	
	REAL valor;
	
	const int dim = this->Dimension();
	const int nstate = this->NStateVariables();
	//Getting state variables
	REAL K = sol[EK];
	REAL Eps = sol[EEpsilon];
	REAL Pressure = sol[EPressure];  
	TPZManVector<REAL,3> V(dim);
	int i,j;
	for(i = 0; i < dim; i++) V[i] = sol[EVx+i];
	
	//Getting Grad[state variables]
	TPZManVector<REAL,3> GradK(dim,1);
	for(i = 0; i < dim; i++) GradK[i] = dsol(i, EK);
	TPZManVector<REAL,3> GradEps(dim,1);
	for(i = 0; i < dim; i++) GradEps[i] = dsol(i, EEpsilon);
	TPZManVector<REAL,3> GradPressure(dim,1);
	for(i = 0; i < dim; i++) GradPressure[i] = dsol(i, EPressure);
	TPZFNMatrix<9> GradV(dim,dim);
	for(i = 0; i < dim; i++){
		for(j = 0; j < dim; j++){
			GradV(i,j) = dsol(j,EVx+i);
		}
	}
	
	//Constants:
	REAL Rt = K*K /(Eps*fMU/fRHO);
	REAL muT = fRHO * fCmu * (K*K/Eps) * exp(-2.5/(1.+Rt/50.));
	
	//TURBULENCE RESIDUALS
	//CONSERVATION OF K                              
	const int nShape = phi.Rows(); 
	TPZFNMatrix<9> S(dim,dim);
	for(i = 0; i < dim; i++){
		for(j = 0; j < dim; j++){
			S(i,j) = 0.5 * (GradV(i,j) + GradV(j,i) );
		}
	}
	REAL Diss = 2. * fMU * (1. / (4. * K) ) * this->Dot(GradK, GradK);
	
	TPZManVector<REAL,3> GradPhi(dim);
	for(i = 0; i < nShape; i++){
		int k;
		for(k = 0; k < dim; k++) GradPhi[k] = dphi(k,i);
		ef(i*nstate+EK) += -1. * fRHO * this->Dot(V, GradPhi) * K 
		+ (fMU + muT / fSigmaK) * Dot(GradK,GradPhi) 
		-2.0 * muT * this->Dot(S,GradV)*phi[i]
		+ fRHO * Eps * phi[i] 
		-1. * Diss;
		valor = -1. * fRHO * this->Dot(V, GradPhi) * K 
		+ (fMU + muT / fSigmaK) * Dot(GradK,GradPhi) 
		-2.0 * muT * this->Dot(S,GradV)*phi[i]
		+ fRHO * Eps * phi[i] 
		-1. * Diss;                
	}
	
	//CONSERVATION OF EPSILON
	for(i = 0; i < nShape; i++){
		int k;
		for(k = 0; k < dim; k++) GradPhi[k] = dphi(k,i);
		ef(i*nstate+EEpsilon) += -1. * fRHO * this->Dot(V, GradPhi) * Eps
		+ (fMU + muT / fSigmaEps) * this->Dot(GradEps, GradPhi)
		-1. * fCepsilon1 * (Eps/K) * 2. * muT * this->Dot(S,GradV) * phi[i]
		+ fCepsilon2 * (Eps*Eps/K) * phi[i];
		valor = -1. * fRHO * this->Dot(V, GradPhi) * Eps
		+ (fMU + muT / fSigmaEps) * this->Dot(GradEps, GradPhi)
		-1. * fCepsilon1 * (Eps/K) * 2. * muT * this->Dot(S,GradV) * phi[i]
		+ fCepsilon2 * (Eps*Eps/K) * phi[i];                  
	}
	
	//INCOMPRESSIBLE NAVIERS-STOKES RESIDUALS  
	//CONTINUITY EQUATION
	for(i = 0; i < nShape; i++){
		REAL trGradV = 0.;
		int k;
		for(k = 0; k < dim; k++) trGradV += GradV(k,k);
		ef(i*nstate+EPressure) += trGradV * phi[i];
		valor = trGradV * phi[i];
	}  
	
	//CONSERVATION OF LINEAR MOMENTUM
	TPZFNMatrix<9> T(dim,dim);
	//T = -p I + (mu + muT) * 2 * S
	T = S;
	T *= (fMU + muT ) *2.;
	for(i = 0; i < dim; i++) T(i,i) += -1. * Pressure;
	
	for(j = 0; j < dim; j++){
		for(i = 0; i < nShape; i++){
			int k;
			for(k = 0; k < dim; k++) GradPhi[k] = dphi(k,i);
			valor = fRHO * this->Dot(V, GradV, j) * phi[i]
			-1.  * this->Dot(GradPhi, T, j)
			-1.  * fBodyForce[j] * phi[i];                      
			ef(i*nstate+ EVx+j) += valor;
		}
	}
	
}//method
예제 #6
0
bool Foam::chemPointISAT<CompType, ThermoType>::grow(const scalarField& phiq)
{
    scalarField dphi(phiq - phi());
    label dim = completeSpaceSize();
    label initNActiveSpecies(nActiveSpecies_);
    bool isMechRedActive = chemistry_.mechRed()->active();

    if (isMechRedActive)
    {
        label activeAdded(0);
        DynamicList<label> dimToAdd(0);

        // check if the difference of active species is lower than the maximum
        // number of new dimensions allowed
        for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; i++)
        {
            // first test if the current chemPoint has an inactive species
            // corresponding to an active one in the query point
            if
            (
                completeToSimplifiedIndex_[i] == -1
             && chemistry_.completeToSimplifiedIndex()[i]!=-1
            )
            {
                activeAdded++;
                dimToAdd.append(i);
            }
            // then test if an active species in the current chemPoint
            // corresponds to an inactive on the query side
            if
            (
                completeToSimplifiedIndex_[i] != -1
             && chemistry_.completeToSimplifiedIndex()[i] == -1
            )
            {
                activeAdded++;
                // we don't need to add a new dimension but we count it to have
                // control on the difference through maxNumNewDim
            }
            // finally test if both points have inactive species but
            // with a dphi!=0
            if
            (
                completeToSimplifiedIndex_[i] == -1
             && chemistry_.completeToSimplifiedIndex()[i] == -1
             && dphi[i] != 0
            )
            {
                activeAdded++;
                dimToAdd.append(i);
            }
        }

        // if the number of added dimension is too large, growth fail
        if (activeAdded > maxNumNewDim_)
        {
            return false;
        }

        // the number of added dimension to the current chemPoint
        nActiveSpecies_ += dimToAdd.size();
        simplifiedToCompleteIndex_.setSize(nActiveSpecies_);
        forAll(dimToAdd, i)
        {
            label si = nActiveSpecies_ - dimToAdd.size() + i;
            // add the new active species
            simplifiedToCompleteIndex_[si] = dimToAdd[i];
            completeToSimplifiedIndex_[dimToAdd[i]] = si;
        }

        // update LT and A :
        //-add new column and line for the new active species
        //-transfer last two lines of the previous matrix (p and T) to the end
        //  (change the diagonal position)
        //-set all element of the new lines and columns to zero except diagonal
        //  (=1/(tolerance*scaleFactor))
        if (nActiveSpecies_ > initNActiveSpecies)
        {
            scalarSquareMatrix LTvar = LT_; // take a copy of LT_
            scalarSquareMatrix Avar = A_; // take a copy of A_
            LT_ = scalarSquareMatrix(nActiveSpecies_+nAdditionalEqns_, Zero);
            A_ = scalarSquareMatrix(nActiveSpecies_+nAdditionalEqns_, Zero);

            // write the initial active species
            for (label i=0; i<initNActiveSpecies; i++)
            {
                for (label j=0; j<initNActiveSpecies; j++)
                {
                    LT_(i, j) = LTvar(i, j);
                    A_(i, j) = Avar(i, j);
                }
            }

            // write the columns for temperature and pressure
            for (label i=0; i<initNActiveSpecies; i++)
            {
                for (label j=1; j>=0; j--)
                {
                    LT_(i, nActiveSpecies_+j)=LTvar(i, initNActiveSpecies+j);
                    A_(i, nActiveSpecies_+j)=Avar(i, initNActiveSpecies+j);
                    LT_(nActiveSpecies_+j, i)=LTvar(initNActiveSpecies+j, i);
                    A_(nActiveSpecies_+j, i)=Avar(initNActiveSpecies+j, i);
                }
            }
            // end with the diagonal elements for temperature and pressure
            LT_(nActiveSpecies_, nActiveSpecies_)=
                LTvar(initNActiveSpecies, initNActiveSpecies);
            A_(nActiveSpecies_, nActiveSpecies_)=
                Avar(initNActiveSpecies, initNActiveSpecies);
            LT_(nActiveSpecies_+1, nActiveSpecies_+1)=
                LTvar(initNActiveSpecies+1, initNActiveSpecies+1);
            A_(nActiveSpecies_+1, nActiveSpecies_+1)=
                Avar(initNActiveSpecies+1, initNActiveSpecies+1);

            if (variableTimeStep())
            {
                LT_(nActiveSpecies_+2, nActiveSpecies_+2)=
                    LTvar(initNActiveSpecies+2, initNActiveSpecies+2);
                A_(nActiveSpecies_+2, nActiveSpecies_+2)=
                    Avar(initNActiveSpecies+2, initNActiveSpecies+2);
            }

            for (label i=initNActiveSpecies; i<nActiveSpecies_;i++)
            {
                LT_(i, i)=
                    1.0
                   /(tolerance_*scaleFactor_[simplifiedToCompleteIndex_[i]]);
                A_(i, i) = 1;
            }
        }

        dim = nActiveSpecies_ + nAdditionalEqns_;
    }
예제 #7
0
bool Foam::chemPointISAT<CompType, ThermoType>::checkSolution
(
    const scalarField& phiq,
    const scalarField& Rphiq
)
{
    scalar eps2 = 0;
    scalarField dR(Rphiq - Rphi());
    scalarField dphi(phiq - phi());
    const scalarField& scaleFactorV(scaleFactor());
    const scalarSquareMatrix& Avar(A());
    bool isMechRedActive = chemistry_.mechRed()->active();
    scalar dRl = 0;
    label dim = completeSpaceSize()-2;
    if (isMechRedActive)
    {
        dim = nActiveSpecies_;
    }

    // Since we build only the solution for the species, T and p are not
    // included
    for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; i++)
    {
        dRl = 0;
        if (isMechRedActive)
        {
            label si = completeToSimplifiedIndex_[i];

            // If this species is active
            if (si != -1)
            {
                for (label j=0; j<dim; j++)
                {
                    label sj=simplifiedToCompleteIndex_[j];
                    dRl += Avar(si, j)*dphi[sj];
                }
                dRl += Avar(si, nActiveSpecies_)*dphi[idT_];
                dRl += Avar(si, nActiveSpecies_+1)*dphi[idp_];
                if (variableTimeStep())
                {
                    dRl += Avar(si, nActiveSpecies_+2)*dphi[iddeltaT_];
                }
            }
            else
            {
                dRl = dphi[i];
            }
        }
        else
        {
            for (label j=0; j<completeSpaceSize(); j++)
            {
                dRl += Avar(i, j)*dphi[j];
            }
        }
        eps2 += sqr((dR[i]-dRl)/scaleFactorV[i]);
    }

    eps2 = sqrt(eps2);
    if (eps2 > tolerance())
    {
        return false;
    }
    else
    {
        // if the solution is in the ellipsoid of accuracy
        return true;
    }
}
예제 #8
0
bool Foam::chemPointISAT<CompType, ThermoType>::inEOA(const scalarField& phiq)
{
    scalarField dphi(phiq-phi());
    bool isMechRedActive = chemistry_.mechRed()->active();
    label dim(0);
    if (isMechRedActive)
    {
        dim = nActiveSpecies_;
    }
    else
    {
        dim = completeSpaceSize() - nAdditionalEqns_;
    }

    scalar epsTemp = 0;
    List<scalar> propEps(completeSpaceSize(), scalar(0));

    for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; i++)
    {
        scalar temp = 0;

        // When mechanism reduction is inactive OR on active species multiply L
        // by dphi to get the distance in the active species direction else (for
        // inactive species), just multiply the diagonal element and dphi
        if
        (
            !(isMechRedActive)
          ||(isMechRedActive && completeToSimplifiedIndex_[i] != -1)
        )
        {
            label si=(isMechRedActive) ? completeToSimplifiedIndex_[i] : i;

            for (label j=si; j<dim; j++)// LT is upper triangular
            {
                label sj=(isMechRedActive) ? simplifiedToCompleteIndex_[j] : j;
                temp += LT_(si, j)*dphi[sj];
            }

            temp += LT_(si, dim)*dphi[idT_];
            temp += LT_(si, dim+1)*dphi[idp_];
            if (variableTimeStep())
            {
                temp += LT_(si, dim+2)*dphi[iddeltaT_];
            }
        }
        else
        {
            temp = dphi[i]/(tolerance_*scaleFactor_[i]);
        }

        epsTemp += sqr(temp);

        if (printProportion_)
        {
            propEps[i] = temp;
        }
    }

    // Temperature
    if (variableTimeStep())
    {
        epsTemp +=
            sqr
            (
                LT_(dim, dim)*dphi[idT_]
               +LT_(dim, dim+1)*dphi[idp_]
               +LT_(dim, dim+2)*dphi[iddeltaT_]
            );
    }
    else
    {
        epsTemp +=
            sqr
            (
                LT_(dim, dim)*dphi[idT_]
               +LT_(dim, dim+1)*dphi[idp_]
            );
    }

    // Pressure
    if (variableTimeStep())
    {
        epsTemp +=
            sqr
            (
                LT_(dim+1, dim+1)*dphi[idp_]
               +LT_(dim+1, dim+2)*dphi[iddeltaT_]
            );
    }
    else
    {
        epsTemp += sqr(LT_(dim+1, dim+1)*dphi[idp_]);
    }

    if (variableTimeStep())
    {
        epsTemp += sqr(LT_[dim+2][dim+2]*dphi[iddeltaT_]);
    }

    if (printProportion_)
    {
        propEps[idT_] = sqr
        (
            LT_(dim, dim)*dphi[idT_]
          + LT_(dim, dim+1)*dphi[idp_]
        );

        propEps[idp_] =
            sqr(LT_(dim+1, dim+1)*dphi[idp_]);

        if (variableTimeStep())
        {
            propEps[iddeltaT_] =
                sqr(LT_[dim+2][dim+2]*dphi[iddeltaT_]);
        }

    }

    if (sqrt(epsTemp) > 1 + tolerance_)
    {
        if (printProportion_)
        {
            scalar max = -1;
            label maxIndex = -1;
            for (label i=0; i<completeSpaceSize(); i++)
            {
                if(max < propEps[i])
                {
                    max = propEps[i];
                    maxIndex = i;
                }
            }
            word propName;
            if (maxIndex >= completeSpaceSize() - nAdditionalEqns_)
            {
                if (maxIndex == idT_)
                {
                    propName = "T";
                }
                else if (maxIndex == idp_)
                {
                    propName = "p";
                }
                else if (maxIndex == iddeltaT_)
                {
                    propName = "deltaT";
                }
            }
            else
            {
                propName = chemistry_.Y()[maxIndex].member();
            }
            Info<< "Direction maximum impact to error in ellipsoid: "
                << propName << endl;
            Info<< "Proportion to the total error on the retrieve: "
                << max/(epsTemp+small) << endl;
        }
        return false;
    }
    else
    {
        return true;
    }
}
bool
TensorMechanicsPlasticMohrCoulombMulti::returnEdge010100(const std::vector<Real> & eigvals, const std::vector<RealVectorValue> & n,
                                                         std::vector<Real> & dpm, RankTwoTensor & returned_stress, Real intnl_old,
                                                         Real & sinphi, Real & cohcos, Real initial_guess, Real mag_E,
                                                         bool & nr_converged, Real ep_plastic_tolerance, std::vector<Real> & yf) const
{
  // This returns to the Mohr-Coulomb edge
  // with 010100 being active.  This means that
  // f1=f3=0.  Denoting the returned stress by "a"
  // (in principal stress space), this means that
  // a1=a2 = (2Ccosphi + a0(1-sinphi))/(sinphi+1)
  //
  // Also, a = eigvals - dpm1*n1 - dpm3*n3,
  // where the dpm are the plastic multipliers
  // and the n are the flow directions.
  //
  // Hence we have 5 equations and 5 unknowns (a,
  // dpm1 and dpm3).  Eliminating all unknowns
  // except for x = dpm1+dpm3 gives the residual below
  // (I used mathematica)

  Real x = initial_guess;
  sinphi = std::sin(phi(intnl_old + x));
  Real cosphi = std::cos(phi(intnl_old + x));
  Real coh = cohesion(intnl_old + x);
  cohcos = coh*cosphi;

  const Real numer_const = - n[1](2)*eigvals[0] - n[3](1)*eigvals[0] + n[3](2)*eigvals[0] - n[1](0)*eigvals[1] + n[1](2)*eigvals[1] + n[3](0)*eigvals[1] - n[3](2)*eigvals[1] + n[1](0)*eigvals[2] - n[3](0)*eigvals[2] + n[3](1)*eigvals[2] - n[1](1)*(-eigvals[0] + eigvals[2]);
  const Real numer_coeff1 = 2*(n[1](1) - n[1](2) - n[3](1) + n[3](2));
  const Real numer_coeff2 = n[3](2)*(-eigvals[0] - eigvals[1]) + n[1](2)*(eigvals[0] + eigvals[1]) + n[3](1)*(eigvals[0] + eigvals[2]) + (n[1](0) - n[3](0))*(eigvals[1] - eigvals[2]) - n[1](1)*(eigvals[0] + eigvals[2]);
  Real numer = numer_const + numer_coeff1*cohcos + numer_coeff2*sinphi;
  const Real denom_const = -n[1](0)*(n[3](1) - n[3](2)) + n[1](2)*(-n[3](0) + n[3](1)) + n[1](1)*(-n[3](2) + n[3](0));
  const Real denom_coeff = n[1](0)*(n[3](1) - n[3](2)) + n[1](2)*(n[3](0) + n[3](1)) - n[1](1)*(n[3](0) + n[3](2));
  Real denom = denom_const + denom_coeff*sinphi;
  Real residual = -x + numer/denom;

  Real deriv_phi;
  Real deriv_coh;
  Real jacobian;
  const Real tol = Utility::pow<2>(_f_tol / (mag_E * 10.0));
  unsigned int iter = 0;
  do {
    do {
      deriv_phi = dphi(intnl_old + dpm[3]);
      deriv_coh = dcohesion(intnl_old + dpm[3]);
      jacobian = -1 + (numer_coeff1*deriv_coh*cosphi - numer_coeff1*coh*sinphi*deriv_phi + numer_coeff2*cosphi*deriv_phi)/denom - numer*denom_coeff*cosphi*deriv_phi/denom/denom;
      x -= residual/jacobian;
      if (iter > _max_iters) // not converging
      {
        nr_converged = false;
        return false;
      }

      sinphi = std::sin(phi(intnl_old + x));
      cosphi = std::cos(phi(intnl_old + x));
      coh = cohesion(intnl_old + x);
      cohcos = coh*cosphi;
      numer = numer_const + numer_coeff1*cohcos + numer_coeff2*sinphi;
      denom = denom_const + denom_coeff*sinphi;
      residual = -x + numer/denom;
      iter ++;
    } while (residual*residual > tol);

    // now must ensure that yf[1] and yf[3] are both "zero"
    Real dpm1minusdpm3 = (2*(eigvals[1] - eigvals[2]) + x*(n[1](2) - n[1](1) + n[3](2) - n[3](1)))/(n[1](1) - n[1](2) + n[3](2) - n[3](1));
    dpm[1] = (x + dpm1minusdpm3)/2.0;
    dpm[3] = (x - dpm1minusdpm3)/2.0;

    for (unsigned i = 0; i < 3; ++i)
      returned_stress(i, i) = eigvals[i] - dpm[1]*n[1](i) - dpm[3]*n[3](i);
    yieldFunctionEigvals(returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
  } while (yf[1]*yf[1] > _f_tol*_f_tol && yf[3]*yf[3] > _f_tol*_f_tol);

  // so the NR process converged, but we must
  // check Kuhn-Tucker
  nr_converged = true;

  if (dpm[1] < -ep_plastic_tolerance || dpm[3] < -ep_plastic_tolerance)
    // Kuhn-Tucker failure.    This is a potential weak-point: if the user has set _f_tol quite large, and ep_plastic_tolerance quite small, the above NR process will quickly converge, but the solution may be wrong and violate Kuhn-Tucker
    return false;

  if (yf[0] > _f_tol || yf[2] > _f_tol || yf[4] > _f_tol || yf[5] > _f_tol)
    // Kuhn-Tucker failure
    return false;

  // success
  dpm[0] = dpm[2] = dpm[4] = dpm[5] = 0;
  return true;
}
bool
TensorMechanicsPlasticMohrCoulombMulti::returnPlane(const std::vector<Real> & eigvals, const std::vector<RealVectorValue> & n,
                                                    std::vector<Real> & dpm, RankTwoTensor & returned_stress, Real intnl_old,
                                                    Real & sinphi, Real & cohcos, Real initial_guess, bool & nr_converged,
                                                    Real ep_plastic_tolerance, std::vector<Real> & yf) const
{
  // This returns to the Mohr-Coulomb plane using n[3] (ie 000100)
  //
  // The returned point is defined by the f[3]=0 and
  //    a = eigvals - dpm[3]*n[3]
  // where "a" is the returned point and dpm[3] is the plastic multiplier.
  // This equation is a vector equation in principal stress space.
  // (Kuhn-Tucker also demands that dpm[3]>=0, but we leave checking
  // that condition for the end.)
  // Since f[3]=0, we must have
  // a[2]*(1+sinphi) + a[0]*(-1+sinphi) - 2*coh*cosphi = 0
  // which gives dpm[3] as the solution of
  //     alpha*dpm[3] + eigvals[2] - eigvals[0] + beta*sinphi - 2*coh*cosphi = 0
  // with alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0))*sinphi
  //      beta = eigvals[2] + eigvals[0]

  mooseAssert(n.size() == 6, "TensorMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be supplied with n of size 6, whereas yours is " << n.size());
  mooseAssert(dpm.size() == 6, "TensorMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be supplied with dpm of size 6, whereas yours is " << dpm.size());
  mooseAssert(yf.size() == 6, "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be supplied with yf of size 6, whereas yours is " << yf.size());

  dpm[3] = initial_guess;
  sinphi = std::sin(phi(intnl_old + dpm[3]));
  Real cosphi = std::cos(phi(intnl_old + dpm[3]));
  Real coh = cohesion(intnl_old + dpm[3]);
  cohcos = coh*cosphi;

  Real alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
  Real deriv_phi;
  Real dalpha;
  const Real beta = eigvals[2] + eigvals[0];
  Real deriv_coh;

  Real residual = alpha*dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos; // this is 2*yf[3]
  Real jacobian;

  const Real f_tol2 =  Utility::pow<2>(_f_tol);
  unsigned int iter = 0;
  do {
    deriv_phi = dphi(intnl_old + dpm[3]);
    dalpha = -(n[3](2) + n[3](0)) * cosphi * deriv_phi;
    deriv_coh = dcohesion(intnl_old + dpm[3]);
    jacobian = alpha + dalpha * dpm[3] + beta * cosphi * deriv_phi - 2.0 * deriv_coh * cosphi + 2.0 * coh * sinphi * deriv_phi;

    dpm[3] -= residual / jacobian;
    if (iter > _max_iters) // not converging
    {
      nr_converged = false;
      return false;
    }

    sinphi = std::sin(phi(intnl_old + dpm[3]));
    cosphi = std::cos(phi(intnl_old + dpm[3]));
    coh = cohesion(intnl_old + dpm[3]);
    cohcos = coh * cosphi;
    alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
    residual = alpha * dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos;
    iter++;
  } while (residual * residual > f_tol2);

  // so the NR process converged, but we must
  // check Kuhn-Tucker
  nr_converged = true;
  if (dpm[3] < -ep_plastic_tolerance)
    // Kuhn-Tucker failure
    return false;

  for (unsigned i = 0; i < 3; ++i)
    returned_stress(i, i) = eigvals[i] - dpm[3]*n[3](i);
  yieldFunctionEigvals(returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);

  // by construction abs(yf[3]) = abs(residual/2) < _f_tol/2
  if (yf[0] > _f_tol || yf[1] > _f_tol || yf[2] > _f_tol || yf[4] > _f_tol || yf[5] > _f_tol)
    // Kuhn-Tucker failure
    return false;

  // success!
  dpm[0] = dpm[1] = dpm[2] = dpm[4] = dpm[5] = 0;
  return true;
}
bool
TensorMechanicsPlasticMohrCoulombMulti::returnTip(const std::vector<Real> & eigvals, const std::vector<RealVectorValue> & n,
                                                  std::vector<Real> & dpm, RankTwoTensor & returned_stress, Real intnl_old,
                                                  Real & sinphi, Real & cohcos, Real initial_guess, bool & nr_converged,
                                                  Real ep_plastic_tolerance, std::vector<Real> & yf) const
{
  // This returns to the Mohr-Coulomb tip using the THREE directions
  // given in n, and yields the THREE dpm values.  Note that you
  // must supply THREE suitable n vectors out of the total of SIX
  // flow directions, and then interpret the THREE dpm values appropriately.
  //
  // Eg1.  You supply the flow directions n[0], n[1] and n[3] as
  //       the "n" vectors.  This is return-to-the-tip via 110100.
  //       Then the three returned dpm values will be dpm[0], dpm[1] and dpm[3].

  // Eg2.  You supply the flow directions n[1], n[3] and n[5] as
  //       the "n" vectors.  This is return-to-the-tip via 010101.
  //       Then the three returned dpm values will be dpm[1], dpm[3] and dpm[5].

  // The returned point is defined by the three yield functions (corresonding
  // to the three supplied flow directions) all being zero.
  // that is, returned_stress = diag(cohcot, cohcot, cohcot), where
  // cohcot = cohesion*cosphi/sinphi
  // where intnl = intnl_old + dpm[0] + dpm[1] + dpm[2]
  // The 3 plastic multipliers, dpm, are defiend by the normality condition
  //     eigvals - cohcot = dpm[0]*n[0] + dpm[1]*n[1] + dpm[2]*n[2]
  // (Kuhn-Tucker demands that all dpm are non-negative, but we leave
  //  that checking for the end.)
  // (Remember that these "n" vectors and "dpm" values must be interpreted
  //  differently depending on what you pass into this function.)
  // This is a vector equation with solution (A):
  //   dpm[0] = triple(eigvals - cohcot, n[1], n[2])/trip;
  //   dpm[1] = triple(eigvals - cohcot, n[2], n[0])/trip;
  //   dpm[2] = triple(eigvals - cohcot, n[0], n[1])/trip;
  // where trip = triple(n[0], n[1], n[2]).
  // By adding the three components of that solution together
  // we can get an equation for x = dpm[0] + dpm[1] + dpm[2],
  // and then our Newton-Raphson only involves one variable (x).
  // In the following, i specialise to the isotropic situation.

  mooseAssert(n.size() == 3, "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be supplied with n of size 3, whereas yours is " << n.size());
  mooseAssert(dpm.size() == 3, "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be supplied with dpm of size 3, whereas yours is " << dpm.size());
  mooseAssert(yf.size() == 6, "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be supplied with yf of size 6, whereas yours is " << yf.size());

  Real x = initial_guess;
  const Real trip = triple_product(n[0], n[1], n[2]);
  sinphi = std::sin(phi(intnl_old + x));
  Real cosphi = std::cos(phi(intnl_old + x));
  Real coh = cohesion(intnl_old + x);
  cohcos = coh*cosphi;
  Real cohcot = cohcos/sinphi;

  if (_cohesion.modelName().compare("Constant") != 0 || _phi.modelName().compare("Constant") != 0)
  {
    // Finding x is expensive.  Therefore
    // although x!=0 for Constant Hardening, solution (A)
    // demonstrates that we don't
    // actually need to know x to find the dpm for
    // Constant Hardening.
    //
    // However, for nontrivial Hardening, the following
    // is necessary
    // cohcot_coeff = [1,1,1].(Cross[n[1], n[2]] + Cross[n[2], n[0]] + Cross[n[0], n[1]])/trip
    Real cohcot_coeff = (n[0](0)*(n[1](1) - n[1](2) - n[2](1)) + (n[1](2) - n[1](1))*n[2](0) + (n[1](0) - n[1](2))*n[2](1) + n[0](2)*(n[1](0) - n[1](1) - n[2](0) + n[2](1)) + n[0](1)*(n[1](2) - n[1](0) + n[2](0) - n[2](2)) + (n[0](0) - n[1](0) + n[1](1))*n[2](2))/trip;
    // eig_term = eigvals.(Cross[n[1], n[2]] + Cross[n[2], n[0]] + Cross[n[0], n[1]])/trip
    Real eig_term = eigvals[0]*(-n[0](2)*n[1](1) + n[0](1)*n[1](2) + n[0](2)*n[2](1) - n[1](2)*n[2](1) - n[0](1)*n[2](2) + n[1](1)*n[2](2))/trip;
    eig_term += eigvals[1]*(n[0](2)*n[1](0) - n[0](0)*n[1](2) - n[0](2)*n[2](0) + n[1](2)*n[2](0) + n[0](0)*n[2](2) - n[1](0)*n[2](2))/trip;
    eig_term += eigvals[2]*(n[0](0)*n[1](1) - n[1](1)*n[2](0) + n[0](1)*n[2](0) - n[0](1)*n[1](0) - n[0](0)*n[2](1) + n[1](0)*n[2](1))/trip;
    // and finally, the equation we want to solve is:
    // x - eig_term + cohcot*cohcot_coeff = 0
    // but i divide by cohcot_coeff so the result has the units of
    // stress, so using _f_tol as a convergence check is reasonable
    eig_term /= cohcot_coeff;
    Real residual = x/cohcot_coeff - eig_term + cohcot;
    Real jacobian;
    Real deriv_phi;
    Real deriv_coh;
    unsigned int iter = 0;
    do {
      deriv_phi = dphi(intnl_old + x);
      deriv_coh = dcohesion(intnl_old + x);
      jacobian = 1.0/cohcot_coeff + deriv_coh*cosphi/sinphi - coh*deriv_phi/Utility::pow<2>(sinphi);
      x += -residual/jacobian;

      if (iter > _max_iters) // not converging
      {
        nr_converged = false;
        return false;
      }

      sinphi = std::sin(phi(intnl_old + x));
      cosphi = std::cos(phi(intnl_old + x));
      coh = cohesion(intnl_old + x);
      cohcos = coh*cosphi;
      cohcot = cohcos/sinphi;
      residual = x/cohcot_coeff - eig_term + cohcot;
      iter ++;
    } while (residual*residual > _f_tol*_f_tol/100);
  }

  // so the NR process converged, but we must
  // calculate the individual dpm values and
  // check Kuhn-Tucker
  nr_converged = true;
  if (x < -3*ep_plastic_tolerance)
    // obviously at least one of the dpm are < -ep_plastic_tolerance.  No point in proceeding.  This is a potential weak-point: if the user has set _f_tol quite large, and ep_plastic_tolerance quite small, the above NR process will quickly converge, but the solution may be wrong and violate Kuhn-Tucker.
    return false;

  // The following is the solution (A) written above
  // (dpm[0] = triple(eigvals - cohcot, n[1], n[2])/trip, etc)
  // in the isotropic situation
  RealVectorValue v;
  v(0) = eigvals[0] - cohcot;
  v(1) = eigvals[1] - cohcot;
  v(2) = eigvals[2] - cohcot;
  dpm[0] = triple_product(v, n[1], n[2])/trip;
  dpm[1] = triple_product(v, n[2], n[0])/trip;
  dpm[2] = triple_product(v, n[0], n[1])/trip;

  if (dpm[0] < -ep_plastic_tolerance || dpm[1] < -ep_plastic_tolerance || dpm[2] < -ep_plastic_tolerance)
    // Kuhn-Tucker failure.  No point in proceeding
    return false;

  // Kuhn-Tucker has succeeded: just need returned_stress and yf values
  // I do not use the dpm to calculate returned_stress, because that
  // might add error (and computational effort), simply:
  returned_stress(0, 0) = returned_stress(1, 1) = returned_stress(2, 2) = cohcot;
  // So by construction the yield functions are all zero
  yf[0] = yf[1] = yf[2] = yf[3] = yf[4] = yf[5] = 0;
  return true;
}
예제 #12
0
파일: main.cpp 프로젝트: labmec/neopz
int main()
{
#ifdef _AUTODIFF

#ifdef FAD
  const int dim = 3;
  const int nstate = dim+2;
  const int nphi = 6;

  // emulating state variables
  TPZVec<TPZDiffMatrix<REAL> > Ai, Tau;
  TPZVec<TPZVec<REAL> > TauDiv;
  TPZVec<TPZDiffMatrix<REAL> > TaudDiv;
  /*char ArtDiff[32]="LS";*/
  TPZArtDiffType artDiffType = LeastSquares_AD;
  TPZFMatrix dsol(dim,nstate);
  TPZFMatrix dphi(dim,nphi);
  TPZVec<REAL> phi(nphi);
  TPZVec<REAL> sol(nstate);


  TPZVec<FADREAL> FADsol(nstate);
  TPZVec<FADREAL> FADdsol(nstate*dim);
  TPZVec<TPZVec<FADREAL> > FADTauDiv;
  // generating data

  TPZArtDiff ArtDiff(artDiffType, 1.4);

  //solution
  sol[0]=2.;
  sol[1]=3.;
  sol[2]=5.;
  sol[3]=7.;
  sol[4]=11.;

  //phi
  phi[0]=2.3;
  phi[1]=3.5;
  phi[2]=5.7;
  phi[3]=7.11;
  phi[4]=11.13;
  phi[5]=13.17;

  //dphi
  int i;
  int j;
  for(i=0;i<dim;i++)
     for(j=0;j<nphi;j++)
        dphi(i,j)=45.8*i-3.2*j; // any choice

  //dsol
  for(i=0;i<dim;i++)
     for(j=0;j<nstate;j++)
        dsol(i,j)=49.8*i-3.1*j; // any choice

  int k, l;

  //FADsol
  for(i=0;i<nstate;i++)
     {
        FADsol[i]=sol[i];
        FADsol[i].diff(0,nphi*nstate);
	FADsol[i].fastAccessDx(0)=0.;
	for(j=0;j<nphi;j++)FADsol[i].fastAccessDx(i+j*nstate)=phi[j];
     }

/*  FADREAL teste;
  for(i=0;i<FADsol.NElements();i++)teste+=FADsol[i];
  cout << "\n\nFADsol\n" << teste;

  cout << "\n\nphi\n" << phi;
*/

  //FADdSol
  for(k=0;k<dim;k++)
     for(i=0;i<nstate;i++)
        {
            FADdsol[k+i*dim]=dsol(k,i);
	    FADdsol[k+i*dim].diff(0,nphi*nstate);
	    FADdsol[k+i*dim].fastAccessDx(0)=0.;
	    for(j=0;j<nphi;j++)
	    	    FADdsol[k+i*dim].fastAccessDx(i+j*nstate)=dphi(k,j);
	}
/*
	cout << "\n\nFADdsol\n";
teste=0;
for(i=0;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

teste=0;
for(i=1;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

teste=0;
for(i=2;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

//cout << "\n\nFADdsol\n" << FADdsol;

cout << "\n\ndphi\n" << dphi;
*/
  TPZFMatrix Jac(dim,dim,1.);
  ArtDiff.PrepareFastDiff(dim,Jac, sol, dsol, dphi, TauDiv, &TaudDiv);
  ArtDiff.PrepareFastDiff(dim, Jac, FADsol, FADdsol, FADTauDiv);


  cout << "\n\nFADTauDiv\n" << FADTauDiv;

  cout << "\n\nTauDiv\n" << TauDiv;

  cout << "\n\nTaudDiv\n" << TaudDiv;
#endif
	
#endif
  return 0;
}
예제 #13
0
void getphase(int si, int idx, int wd2, float *wbuff1, float *wbuff, int ni, int nf)
{
  int j;
  float n11, n12, n21, n22, m1, m2;
  
  n11=0.0;n12=0.0;
  n21=0.0;n22=0.0;
  for (j=0; j<si/16; j++)
  {
    n11 += wbuff[ni*si+2*j]*wbuff[ni*si+2*j]+wbuff[ni*si+2*j+1]*wbuff[ni*si+2*j+1];
    n12 += wbuff[nf*si+2*j]*wbuff[nf*si+2*j]+wbuff[nf*si+2*j+1]*wbuff[nf*si+2*j+1];
  }
  for (j=7*si/16; j<si/2; j++)
  {
    n21 += wbuff[ni*si+2*j]*wbuff[ni*si+2*j]+wbuff[ni*si+2*j+1]*wbuff[ni*si+2*j+1];
    n22 += wbuff[nf*si+2*j]*wbuff[nf*si+2*j]+wbuff[nf*si+2*j+1]*wbuff[nf*si+2*j+1];
  }
  if (n12>n11)
  {
    n12 = n11;
  }
  else
  {
    n11 = n12;
  }
  if (n22>n21)
  {
    n22 = n21;
  }
  else
  {
    n21 = n22;
  }
  if (n22>n11)
  {
    n22 = n11;
  }
  else
  {
    n11 = n22;
  }
  n11 = n11*16/si;
/*end determination of RMS noise level */
  for (j=si/4-wd2-1; j<si/4+wd2+1; j++)
  {
    wbuff1[idx*si+2*j] = dphi(wbuff[ni*si+2*j],wbuff[nf*si+2*j],wbuff[ni*si+2*j+1],wbuff[nf*si+2*j+1]);
    m1 = wbuff[ni*si+2*j]*wbuff[ni*si+2*j]+wbuff[ni*si+2*j+1]*wbuff[ni*si+2*j+1];
    m2 = wbuff[nf*si+2*j]*wbuff[nf*si+2*j]+wbuff[nf*si+2*j+1]*wbuff[nf*si+2*j+1];
    if ((m1>=100*n11) && (m2>=100*n11))
    {
      wbuff1[idx*si+2*j+1] = 1/m2+1/m1;
    }
    else
    {
      wbuff1[idx*si+2*j+1] = 0.0;
    }
  }
/*
wbuff[i*np+2*j]=dphi((float)in_data[2*i].lo[2*j],(float)in_data[2*i+1].lo[2*j],(float)in_data[2*i].lo[2*j+1],(float)in_data[2*i+1].lo[2*j+1]);
*/
}
예제 #14
0
void UnplacedTorus::Print(std::ostream &os) const {
  os << "UnplacedTorus {" << rmin() << ", " << rmax() << ", " << rtor()
     << ", " << sphi() << ", " << dphi();
}
예제 #15
0
void UnplacedTorus::Print() const {
  printf("UnplacedTorus {%.2f, %.2f, %.2f, %.2f, %.2f}",
         rmin(), rmax(), rtor(), sphi(), dphi() );
}
예제 #16
0
int
Fitfraction(){
gStyle->SetOptStat(0);
  RooAbsReal::defaultIntegratorConfig()->getConfigSection("RooIntegrator1D").setRealValue("maxSteps",50000); 
   float ZG_XS = 87.2678;
   float WG_XS = 350.674;
   float k_factor = 489.0/350.674;
   float WG130_XS = 1.161/k_factor;
   float WG_nevt = 5916785;
   float ZG_nevt = 4391376; 
   float WG130_nevt = 1561571;
 
  TH1F *p_WG = new TH1F("p_WG",";#Delta#phi;",64,-3.2,3.2);
  TH1F *p_WG130 = new TH1F("p_WG130",";#Delta#phi;",64,-3.2,3.2);
  TH1F *p_ZG = new TH1F("p_ZG",";#Delta#phi;",64,-3.2,3.2); 
  TH1F *p_MC = new TH1F("p_MC",";#Delta#phi;",64,-3.2,3.2); 
//************ Signal Tree **********************//
  TChain *egtree = new TChain("egTree");
  egtree->Add("../data/resTree_VGamma_WG.root");
  egtree->Add("../data/resTree_VGamma_ZG.root");
  egtree->Add("../data/resTree_VGamma_WG130.root");
  float eg_phoEt(0);
  float eg_sigMET(0);
  float eg_dPhiLepMET(0);
  float eg_invmass(0);
  int mcType(0);
  egtree->SetBranchAddress("phoEt",     &eg_phoEt);
  egtree->SetBranchAddress("sigMET",    &eg_sigMET);
  egtree->SetBranchAddress("dPhiLepMET",&eg_dPhiLepMET);
  egtree->SetBranchAddress("invmass",   &eg_invmass);
  egtree->SetBranchAddress("mcType",    &mcType);

  for(unsigned ievt(0); ievt < egtree->GetEntries(); ievt++){
    double weight(0);
    egtree->GetEntry(ievt);
    if(mcType == MCType::WG)weight = WG_XS*2.26*1000.0/WG_nevt;
    else if(mcType == MCType::WG130)weight = WG130_XS*2.26*1000.0/WG130_nevt;   
    else if(mcType == MCType::ZG)weight = ZG_XS*2.26*1000.0/ZG_nevt;

    if(eg_invmass < 95)continue;
    if(eg_sigMET > 40 && eg_sigMET < 70){
      if(mcType == MCType::WG && eg_phoEt < 140){p_WG->Fill(eg_dPhiLepMET, weight); p_MC->Fill(eg_dPhiLepMET, weight);}
      else if(mcType == MCType::WG130 && eg_phoEt >= 140){p_WG->Fill(eg_dPhiLepMET, weight); p_MC->Fill(eg_dPhiLepMET, weight);}
      else if(mcType == MCType::ZG){p_ZG->Fill(eg_dPhiLepMET, weight); p_MC->Fill(eg_dPhiLepMET, weight);}
    }
  }

   TFile *target_file = TFile::Open("~/public/bkgTree_eg_new.root");
   TFile *proxy_file  = TFile::Open("~/public/compare_leptonProxy_doubleEG_data.root");

   TH1F *p_target = (TH1F*)target_file->Get("p_dPhiEleMET");
   TH1F *tem_proxy = (TH1F*)proxy_file->Get("h_proxy_electron_dPhi");
   p_target->GetXaxis()->SetTitle("#Delta#phi");

   TH1F *p_proxy = new TH1F("p_proxy",";#Delta#phi;",64,-3.2,3.2);
   TH1 *p_MCabs= new TH1F("p_MCabs",";#Delta#phi;",32,0,3.2);
   TH1F *p_targetabs= new TH1F("p_targetabs",";#Delta#phi;",32,0,3.2);

   p_target->Rebin(2);

 
   for(unsigned ibin(1); ibin < 32; ibin++){
     p_proxy->SetBinContent(32+ibin, tem_proxy->GetBinContent(ibin));
     p_proxy->SetBinContent(32-(ibin-1), tem_proxy->GetBinContent(ibin));
   } 
  p_proxy->GetXaxis()->SetTitle("#Delta#phi");

  TCanvas *can1=new TCanvas("can1","",600,600);
  can1->cd();
  p_target->SetTitle("target #Delta#Phi(e, MET)");
  p_target->SetLineWidth(2);
  p_target->Draw();
  can1->SaveAs("target_dPhi_eg.pdf");
  TCanvas *can2=new TCanvas("can2","",600,600); 
  can2->cd();
  p_MC->SetTitle("WG+ZG #Delta#Phi(e, MET)");
  p_MC->SetLineWidth(2);
  p_MC->SetMaximum(20);
  p_MC->SetMinimum(0);
  p_MC->Draw();
  p_WG->SetLineColor(kRed);
  p_WG->SetLineWidth(2);
  p_WG->Draw("hist same");
  p_ZG->SetLineColor(kGreen);
  p_ZG->SetLineWidth(2);
  p_ZG->Draw("hist same");
  TLegend *legMC=new TLegend(0.6,0.7,0.9,0.9);
  legMC->AddEntry(p_WG, "WG");
  legMC->AddEntry(p_ZG, "ZG");
  legMC->AddEntry(p_MC, "WG + ZG");
  legMC->Draw("same");
  can2->SaveAs("MC_dPhi_eg.pdf");
  TCanvas *can3=new TCanvas("can3","",600,600);
  p_proxy->SetTitle("proxy e #Delta#Phi(e,MET)");
  p_proxy->SetLineWidth(2);
  p_proxy->Draw();
  can3->SaveAs("proxy_dPhi_eg.pdf");

  RooRealVar dphi("dphi","",-3.2,3.2);
  RooDataHist* h_target = new RooDataHist("h_target","h_target",dphi,p_target);
  RooDataHist* h_proxy  = new RooDataHist("h_proxy", "h_proxy", dphi,p_proxy );
  RooDataHist* h_MC     = new RooDataHist("h_MC",    "h_MC",    dphi,p_MC);
  RooHistPdf*  pdf_proxy= new RooHistPdf("pdf_proxy","pdf_proxy",dphi, *h_proxy);
  RooHistPdf*  pdf_MC   = new RooHistPdf("pdf_MC",   "pdf_MC",   dphi, *h_MC);
  RooRealVar nFake("nFake","nFake", 13.8);
  RooRealVar nMC("nMC","nMC",887,0,2000 );
  RooAddPdf model("model","",RooArgList(*pdf_proxy, *pdf_MC),RooArgList(nFake,nMC));

  RooPlot* frame = dphi.frame(RooFit::Title("#Delta#phi(l,MET) (40 GeV < MET < 70 GeV)"));
  TCanvas *can=new TCanvas("can","",600,600);
  can->cd(1);
  RooFitResult* result = model.fitTo(*h_target,RooFit::SumW2Error(kTRUE),RooFit::Save());
  h_target->plotOn(frame);
  model.plotOn(frame,
		   RooFit::FillColor(kBlue-4));
  model.plotOn(frame, RooFit::Components(*pdf_proxy),
               RooFit::LineStyle(kDashed),
               RooFit::LineColor(kRed),
               RooFit::Normalization(1.0, RooAbsReal::RelativeExpected));
  frame->Draw();
  can->SaveAs("fit_dPhi_eg_new.pdf");

  double nMCtotal(0);
  for(unsigned i(1); i<=64; i++)nMCtotal+= p_MC->GetBinContent(i);
  std::cout << "factor for fake: " << nFake.getVal() << "/" << tem_proxy->GetEntries() << std::endl;
  std::cout << "factor for MC: " << nMC.getVal() << "/" << nMCtotal << std::endl;

  return 1;
}