Example #1
0
void PeakHKLErrors::functionDeriv1D(Jacobian *out, const double *xValues,
                                    const size_t nData) {
  PeaksWorkspace_sptr Peaks =
      AnalysisDataService::Instance().retrieveWS<PeaksWorkspace>(
          PeakWorkspaceName);
  boost::shared_ptr<Geometry::Instrument> instNew = getNewInstrument(Peaks);

  const DblMatrix &UB = Peaks->sample().getOrientedLattice().getUB();
  DblMatrix UBinv(UB);
  UBinv.Invert();
  UBinv /= 2 * M_PI;

  double GonRotx = getParameter("GonRotx");
  double GonRoty = getParameter("GonRoty");
  double GonRotz = getParameter("GonRotz");
  Matrix<double> InvGonRotxMat = RotationMatrixAboutRegAxis(GonRotx, 'x');
  Matrix<double> InvGonRotyMat = RotationMatrixAboutRegAxis(GonRoty, 'y');
  Matrix<double> InvGonRotzMat = RotationMatrixAboutRegAxis(GonRotz, 'z');
  Matrix<double> GonRot = InvGonRotxMat * InvGonRotyMat * InvGonRotzMat;

  InvGonRotxMat.Invert();
  InvGonRotyMat.Invert();
  InvGonRotzMat.Invert();

  std::map<int, Kernel::Matrix<double>> RunNums2GonMatrix;
  getRun2MatMap(Peaks, OptRuns, RunNums2GonMatrix);

  g_log.debug()
      << "----------------------------Derivative------------------------\n";

  V3D samplePosition = instNew->getSample()->getPos();
  IPeak &ppeak = Peaks->getPeak(0);
  double L0 = ppeak.getL1();
  double velocity = (L0 + ppeak.getL2()) / ppeak.getTOF();

  double K =
      2 * M_PI / ppeak.getWavelength() / velocity; // 2pi/lambda = K* velocity
  V3D beamDir = instNew->getBeamDirection();

  size_t paramNums[] = {parameterIndex(std::string("SampleXOffset")),
                        parameterIndex(std::string("SampleYOffset")),
                        parameterIndex(std::string("SampleZOffset"))};

  for (size_t i = 0; i < nData; i += 3) {
    int peakNum = boost::math::iround(xValues[i]);
    IPeak &peak_old = Peaks->getPeak(peakNum);
    Peak peak = createNewPeak(peak_old, instNew, 0, peak_old.getL1());

    int runNum = peak_old.getRunNumber();
    std::string runNumStr = std::to_string(runNum);

    for (int kk = 0; kk < static_cast<int>(nParams()); kk++) {
      out->set(i, kk, 0.0);
      out->set(i + 1, kk, 0.0);
      out->set(i + 2, kk, 0.0);
    }

    double chi, phi, omega;
    size_t chiParamNum, phiParamNum, omegaParamNum;

    size_t N = OptRuns.find("/" + runNumStr);
    if (N < OptRuns.size()) {
      chi = getParameter("chi" + (runNumStr));
      phi = getParameter("phi" + (runNumStr));
      omega = getParameter("omega" + (runNumStr));

      peak.setGoniometerMatrix(GonRot * RunNums2GonMatrix[runNum]);

      chiParamNum = parameterIndex("chi" + (runNumStr));
      phiParamNum = parameterIndex("phi" + (runNumStr));
      omegaParamNum = parameterIndex("omega" + (runNumStr));
    } else {

      Geometry::Goniometer Gon(peak.getGoniometerMatrix());
      std::vector<double> phichiOmega = Gon.getEulerAngles("YZY");
      chi = phichiOmega[1];
      phi = phichiOmega[2];
      omega = phichiOmega[0];
      // peak.setGoniometerMatrix( GonRot*Gon.getR());
      chiParamNum = phiParamNum = omegaParamNum = nParams() + 10;
      peak.setGoniometerMatrix(GonRot * peak.getGoniometerMatrix());
    }
    V3D sampOffsets(getParameter("SampleXOffset"),
                    getParameter("SampleYOffset"),
                    getParameter("SampleZOffset"));
    peak.setSamplePos(peak.getSamplePos() + sampOffsets);
    // NOTE:Use getQLabFrame except for below.
    // For parameters the getGoniometerMatrix should remove GonRot, for derivs
    // wrt GonRot*, wrt chi*,phi*,etc.

    // Deriv wrt chi phi and omega
    if (phiParamNum < nParams()) {
      Matrix<double> chiMatrix = RotationMatrixAboutRegAxis(chi, 'z');
      Matrix<double> phiMatrix = RotationMatrixAboutRegAxis(phi, 'y');
      Matrix<double> omegaMatrix = RotationMatrixAboutRegAxis(omega, 'y');

      Matrix<double> dchiMatrix = DerivRotationMatrixAboutRegAxis(chi, 'z');
      Matrix<double> dphiMatrix = DerivRotationMatrixAboutRegAxis(phi, 'y');
      Matrix<double> domegaMatrix = DerivRotationMatrixAboutRegAxis(omega, 'y');

      Matrix<double> InvG = omegaMatrix * chiMatrix * phiMatrix;
      InvG.Invert();
      // Calculate Derivatives wrt chi(phi,omega) in degrees
      Matrix<double> R = omegaMatrix * chiMatrix * dphiMatrix;
      Matrix<double> InvR = InvG * R * InvG * -1;
      V3D lab = peak.getQLabFrame();
      V3D Dhkl0 = UBinv * InvR * lab;

      R = omegaMatrix * dchiMatrix * phiMatrix;
      InvR = InvG * R * InvG * -1;
      V3D Dhkl1 = UBinv * InvR * peak.getQLabFrame();

      R = domegaMatrix * chiMatrix * phiMatrix;
      InvR = InvG * R * InvG * -1;
      V3D Dhkl2 =
          UBinv * InvR * peak.getQLabFrame(); // R.transpose should be R inverse

      out->set(i, chiParamNum, Dhkl1[0]);
      out->set(i + 1, chiParamNum, Dhkl1[1]);
      out->set(i + 2, chiParamNum, Dhkl1[2]);
      out->set(i, phiParamNum, Dhkl0[0]);
      out->set(i + 1, phiParamNum, Dhkl0[1]);
      out->set(i + 2, phiParamNum, Dhkl0[2]);
      out->set(i, omegaParamNum, Dhkl2[0]);
      out->set(i + 1, omegaParamNum, Dhkl2[1]);
      out->set(i + 2, omegaParamNum, Dhkl2[2]);

    } // if optimize for chi phi and omega on this peak

    //------------------------Goniometer Rotation Derivatives
    //-----------------------
    Matrix<double> InvGonRot(GonRot);
    InvGonRot.Invert();
    Matrix<double> InvGon = InvGonRot * peak.getGoniometerMatrix();
    InvGon.Invert();
    V3D DGonx = (UBinv * InvGon * InvGonRotzMat * InvGonRotyMat *
                 DerivRotationMatrixAboutRegAxis(
                     -GonRotx, 'x') * // - gives inverse of GonRot
                 peak.getQLabFrame()) *
                -1;

    V3D DGony = (UBinv * InvGon * InvGonRotzMat *
                 DerivRotationMatrixAboutRegAxis(-GonRoty, 'y') *
                 InvGonRotxMat * peak.getQLabFrame()) *
                -1;
    V3D DGonz =
        (UBinv * InvGon * DerivRotationMatrixAboutRegAxis(-GonRotz, 'z') *
         InvGonRotyMat * InvGonRotxMat * peak.getQLabFrame()) *
        -1;

    size_t paramnum = parameterIndex("GonRotx");
    out->set(i, paramnum, DGonx[0]);
    out->set(i + 1, paramnum, DGonx[1]);
    out->set(i + 2, paramnum, DGonx[2]);
    out->set(i, parameterIndex("GonRoty"), DGony[0]);
    out->set(i + 1, parameterIndex("GonRoty"), DGony[1]);
    out->set(i + 2, parameterIndex("GonRoty"), DGony[2]);
    out->set(i, parameterIndex("GonRotz"), DGonz[0]);
    out->set(i + 1, parameterIndex("GonRotz"), DGonz[1]);
    out->set(i + 2, parameterIndex("GonRotz"), DGonz[2]);
    //-------------------- Sample Orientation derivatives
    //----------------------------------
    // Qlab = -KV + k|V|*beamdir
    // D = pos-sampPos
    //|V|= vmag=(L0 + D )/tof
    // t1= tof - L0/|V|   {time from sample to pixel}
    // V = D/t1
    V3D D = peak.getDetPos() - samplePosition;
    double vmag = (L0 + D.norm()) / peak.getTOF();
    double t1 = peak.getTOF() - L0 / vmag;

    // Derivs wrt sample x, y, z
    // Ddsx =( - 1, 0, 0),  d|D|^2/dsx -> 2|D|d|D|/dsx =d(tranp(D)* D)/dsx =2
    // Ddsx* tranp(D)
    //|D| also called Dmag
    V3D Dmagdsxsysz(D);
    Dmagdsxsysz *= (-1 / D.norm());

    V3D vmagdsxsysz = Dmagdsxsysz / peak.getTOF();

    V3D t1dsxsysz = vmagdsxsysz * (L0 / vmag / vmag);
    Matrix<double> Gon = peak.getGoniometerMatrix();
    Gon.Invert();

    // x=0 is deriv wrt SampleXoffset, x=1 is deriv wrt SampleYoffset, etc.
    for (int x = 0; x < 3; x++) {
      V3D pp;
      pp[x] = 1;
      V3D dQlab1 = pp / -t1 - D * (t1dsxsysz[x] / t1 / t1);
      V3D dQlab2 = beamDir * vmagdsxsysz[x];
      V3D dQlab = dQlab2 - dQlab1;
      dQlab *= K;

      V3D dQSamp = Gon * dQlab;
      V3D dhkl = UBinv * dQSamp;

      out->set(i, paramNums[x], dhkl[0]);
      out->set(i + 1, paramNums[x], dhkl[1]);
      out->set(i + 2, paramNums[x], dhkl[2]);
    }
  }
}
Example #2
0
const Vector&
Isolator2spring::getStressResultant(void)
{

  double Fy;
  if (po < 1.0e-10) {
    // No strength degradation
    Fy = Fyo;
  } else {
    // Strength degradation based on bearing axial load
    double p2 = x0(1)/po;
    if (p2<0) {
      p2 = 0.0;
    }
    Fy = Fyo*(1-exp(-p2));
  }
  
  
  // Material stresses using rate independent plasticity, return mapping algorithm
  
  // Compute trial stress using elastic tangent
  double fb_try = k1*(x0(2)-sP_n);
  double xi_try = fb_try - q_n;
  
  // Yield function
  double Phi_try = fabs(xi_try) - Fy;
  
  double fspr;
  double dfsds;
  double del_gam;
  int sign;
  
  // Elastic step
  if (Phi_try <= 0.0) {
    // Stress and tangent, update plastic deformation and back stress
    fspr = fb_try;
    dfsds = k1;
    sP_n1 = sP_n;
    q_n1 = q_n;
  }
  
  // Plastic step
  else {
    // Consistency parameter
    del_gam = Phi_try/(k1+H);
    
    sign = (xi_try < 0) ? -1 : 1;
    // Return stress to yield surface
    fspr = fb_try - del_gam*k1*sign;
    dfsds = kbo;
    // Update plastic deformation and back stress
    sP_n1 = sP_n + del_gam*sign;
    q_n1 = q_n + del_gam*H*sign;
  }
  
  // Nonlinear equilibrium and kinematic equations; want to find the 
  // zeros of these equations.
  f0(0) = x0(0) - fspr + x0(1)*x0(3);
  f0(1) = x0(0)*h - Pe*h*x0(3) + x0(1)*(x0(2)+h*x0(3));
  f0(2) = x0(1) - kvo*x0(4);
  f0(3) = utpt[0] - x0(2) - h*x0(3);
  f0(4) = -utpt[1] - x0(2)*x0(3) - h/2.0*x0(3)*x0(3) - x0(4);
  
  int iter = 0;
  double normf0 = f0.Norm();
  static Matrix dfinverse(5,5);
  
  // Solve nonlinear equations using Newton's method
  while (normf0 > tol) {
    
    iter += 1;
    
    // Formulate Jacobian of nonlinear equations
    df(0,0) = 1.0;
    df(0,1) = x0(3);
    df(0,2) = -dfsds;
    df(0,3) = x0(1);
    df(0,4) = 0.0;
    
    df(1,0) = h;
    df(1,1) = x0(2) + h*x0(3);
    df(1,2) = x0(1);
    df(1,3) = (x0(1) - Pe)*h;
    df(1,4) = 0.0;
    
    df(2,0) = 0.0;
    df(2,1) = 1.0;
    df(2,2) = 0.0;
    df(2,3) = 0.0;
    df(2,4) = -kvo;
    
    df(3,0) = 0.0;
    df(3,1) = 0.0;
    df(3,2) = -1.0;
    df(3,3) = -h;
    df(3,4) = 0.0;
    
    df(4,0) = 0.0;
    df(4,1) = 0.0;
    df(4,2) = -x0(3);
    df(4,3) = -(x0(2) + h*x0(3));
    df(4,4) = -1.0;
    
    df.Invert(dfinverse);
    // Compute improved estimate of solution x0
    x0 -= dfinverse*f0;
    
    if (po > 1.0e-10) { // Update strength according to axial load
      double p2 = x0(1)/po;
      if (p2<0) {
	p2 = 0.0;
      }
      Fy = Fyo*(1-exp(-p2));
    }
    
    // Apply plasticity theory again, return mapping algorithm 
    fb_try = k1*(x0(2) - sP_n);
    xi_try = fb_try - q_n;
    
    Phi_try = fabs(xi_try) - Fy;
    // Elastic step
    if (Phi_try <= 0.0) {
      fspr = fb_try;
      dfsds = k1;
      sP_n1 = sP_n;
      q_n1 = q_n;
    }
    
    // Plastic step
    else {
      del_gam = Phi_try/(k1+H);
      sign = (xi_try < 0) ? -1 : 1;
      fspr = fb_try - del_gam*k1*sign;
      dfsds = kbo;
      sP_n1 = sP_n + del_gam*sign;
      q_n1 = q_n + del_gam*H*sign;
    }
    
    // Estimate the residual
    f0(0) = x0(0) - fspr + x0(1)*x0(3);
    f0(1) = x0(0)*h - Pe*h*x0(3) + x0(1)*(x0(2)+h*x0(3));
    f0(2) = x0(1) - kvo*x0(4);
    f0(3) = utpt[0] - x0(2) - h*x0(3);
    f0(4) = -utpt[1] - x0(2)*x0(3) - h/2.0*x0(3)*x0(3) - x0(4);
    
    normf0 = f0.Norm();
    
    if (iter > 19) {
      opserr << "WARNING! Iso2spring: Newton iteration failed. Norm Resid: " << normf0  << endln;
      break;
    }
  }
  
  // Compute stiffness matrix by three step process
  double denom = h*dfsds*(Pe - x0(1)) - x0(1)*x0(1);
  static Matrix fkin(3,2);
  fkin(0,0) = 1.0;
  fkin(1,0) = h;
  fkin(2,0) = 0.0;
  fkin(0,1) = -x0(3);
  fkin(1,1) = -(x0(2) + h*x0(3));
  fkin(2,1) = -1.0;
  
  static Matrix feq(3,3);
  feq(0,0) = (Pe-x0(1))*h/denom;
  feq(0,1) = feq(1,0) = x0(1)/denom;
  feq(1,1) = dfsds/denom;
  feq(0,2) = feq(1,2) = feq(2,0) = feq(2,1) = 0.0;
  feq(2,2) = 1.0/kvo;
  
  static Matrix ftot(2,2);
  static Matrix ktot(2,2);
  ftot.Zero();
  ftot.addMatrixTripleProduct(0.0,fkin,feq,1.0);
  ftot.Invert(ktot);
  
  ks(0,0) = ktot(0,0);
  ks(1,0) = ktot(1,0);
  ks(0,1) = ktot(0,1);
  ks(1,1) = ktot(1,1);
  ks(0,2) = ks(1,2) = ks(2,2) = ks(2,1) = ks(2,0) = 0.0;
  
  
  // Compute force vector
  s3(0) = x0(0);
  s3(1) = -x0(1);
  s3(2) = (x0(1)*utpt[0] + x0(0)*h)/2.0;
  return s3;
}
LVEDRENDERINGENGINE_API bool __stdcall LvEd_FrustumPick(ObjectGUID renderSurface, float viewxform[], float projxform[],float* rect, HitRecord** hits, int* count)
{
    ErrorHandler::ClearError();
    *hits = 0;
    *count = 0;
    float w = rect[2];
    float h = rect[3];

    if(w == 0 || h == 0)
    {
        return false;
    }


    // init camera.
    Matrix view = viewxform;
    Matrix proj = projxform;
    RenderContext::Inst()->Cam().SetViewProj(view,proj);  
    
    // same code used for rendering.
    s_engineData->pickCollector.ClearLists();
    s_engineData->pickCollector.SetFlags( RenderContext::Inst()->State()->GetGlobalRenderFlags() );

    s_engineData->GameLevel->GetRenderables(&s_engineData->pickCollector, RenderContext::Inst());
   
    RenderSurface* pRenderSurface = reinterpret_cast<RenderSurface*>(renderSurface);

    float3 corners[8];
    float x0 = rect[0];
    float y0 = rect[1];
    float x1 = x0 + w;
    float y1 = y0 + h;       
           
    Matrix viewProj = view * proj;
    Matrix invWVP; // inverse of world view projection matrix.
    s_engineData->HitRecords.clear();
    float3 zeroVector(0,0,0);
    Frustum fr; // frustum in local space.
    for(auto it = s_engineData->pickCollector.GetList().begin(); it != s_engineData->pickCollector.GetList().end(); it++)
    {
        RenderableNode& r = (*it);
        if(r.mesh == NULL) continue;

        invWVP = r.WorldXform * viewProj;
        invWVP.Invert();

        corners[0] = pRenderSurface->Unproject(float3(x0,y1,0),invWVP);
        corners[4] = pRenderSurface->Unproject(float3(x0,y1,1),invWVP);

        corners[1] = pRenderSurface->Unproject(float3(x1,y1,0),invWVP);
        corners[5] = pRenderSurface->Unproject(float3(x1,y1,1),invWVP);

        corners[2] = pRenderSurface->Unproject(float3(x1,y0,0),invWVP);
        corners[6] = pRenderSurface->Unproject(float3(x1,y0,1),invWVP);

        corners[3] = pRenderSurface->Unproject(float3(x0,y0,0),invWVP);
        corners[7] = pRenderSurface->Unproject(float3(x0,y0,1),invWVP);
        fr.InitFromCorners(corners);

        int test = FrustumAABBIntersect(fr,r.mesh->bounds);                
        if(test)
        {
            if(test == 1 
                && r.GetFlag(RenderableNode::kTestAgainstBBoxOnly) == false
                && r.mesh != NULL 
                && r.mesh->primitiveType == PrimitiveType::TriangleList)
            {
                Mesh* mesh = r.mesh;
               
                Triangle tr;                
                bool triHit = FrustumMeshIntersect(fr, 
                     &mesh->pos[0],
                   (uint32_t)mesh->pos.size(),
                   &mesh->indices[0],
                   (uint32_t)mesh->indices.size());
                
                if( triHit == false) continue;               
            }
            
            HitRecord hit;
            hit.objectId = r.objectId;
            hit.index = 0;
            hit.hitPt = zeroVector;
            hit.normal = zeroVector;
            hit.nearestVertex = zeroVector;
            hit.distance = 0;
            hit.hasNormal = false;
            hit.hasNearestVertex = false;
            s_engineData->HitRecords.push_back(hit);
        }
    }

    // return the results to the C#. 
    if(s_engineData->HitRecords.size() > 0)
    {
        *hits = &s_engineData->HitRecords[0];
        *count = (int)s_engineData->HitRecords.size();
    }
    return *count > 0;
}
static void
GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams,
                    float aOpacity, nsStyleContext* aSC,
                    const nsTArray<nsSVGMaskFrame *>& aMaskFrames,
                    const nsPoint& aOffsetToUserSpace,
                    Matrix& aOutMaskTransform,
                    RefPtr<SourceSurface>& aOutMaskSurface)
{
  const nsStyleSVGReset *svgReset = aSC->StyleSVGReset();
  MOZ_ASSERT(aMaskFrames.Length() > 0);

  gfxMatrix cssPxToDevPxMatrix =
    nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aParams.frame);

  gfxContext& ctx = aParams.ctx;

  // There is only one SVG mask.
  if (((aMaskFrames.Length() == 1) && aMaskFrames[0])) {
    aOutMaskSurface =
      aMaskFrames[0]->GetMaskForMaskedFrame(&ctx, aParams.frame,
                                            cssPxToDevPxMatrix, aOpacity,
                                            &aOutMaskTransform,
                                            svgReset->mMask.mLayers[0].mMaskMode);
    return;
  }

  IntRect maskSurfaceRect = ComputeMaskGeometry(aParams, svgReset,
                                                aOffsetToUserSpace,
                                                aMaskFrames);
  if (maskSurfaceRect.IsEmpty()) {
    return;
  }

  // Mask composition result on CoreGraphic::A8 surface is not correct
  // when mask-mode is not add(source over). Switch to skia when CG backend
  // detected.
  RefPtr<DrawTarget> maskDT =
    (ctx.GetDrawTarget()->GetBackendType() == BackendType::COREGRAPHICS ||
     ctx.GetDrawTarget()->GetBackendType() == BackendType::DIRECT2D1_1)
    ? Factory::CreateDrawTarget(BackendType::SKIA, maskSurfaceRect.Size(),
                                SurfaceFormat::A8)
    : ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(),
                                                   SurfaceFormat::A8);
  if (!maskDT || !maskDT->IsValid()) {
    return;
  }

  RefPtr<gfxContext> maskContext = gfxContext::CreateOrNull(maskDT);
  MOZ_ASSERT(maskContext);

  nsPresContext* presContext = aParams.frame->PresContext();
  gfxPoint devPixelOffsetToUserSpace =
    nsLayoutUtils::PointToGfxPoint(aOffsetToUserSpace,
                                   presContext->AppUnitsPerDevPixel());

  // Set ctx's matrix on maskContext, offset by the maskSurfaceRect's position.
  // This makes sure that we combine the masks in device space.
  gfxMatrix maskSurfaceMatrix =
    ctx.CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft());
  maskContext->SetMatrix(maskSurfaceMatrix);

  // Multiple SVG masks interleave with image mask. Paint each layer onto
  // maskDT one at a time.
  for (int i = aMaskFrames.Length() - 1; i >= 0 ; i--) {
    nsSVGMaskFrame *maskFrame = aMaskFrames[i];

    CompositionOp compositionOp = (i == int(aMaskFrames.Length() - 1))
      ? CompositionOp::OP_OVER
      : nsCSSRendering::GetGFXCompositeMode(svgReset->mMask.mLayers[i].mComposite);

    // maskFrame != nullptr means we get a SVG mask.
    // maskFrame == nullptr means we get an image mask.
    if (maskFrame) {
      Matrix svgMaskMatrix;
      RefPtr<SourceSurface> svgMask =
        maskFrame->GetMaskForMaskedFrame(maskContext, aParams.frame,
                                         cssPxToDevPxMatrix, aOpacity,
                                         &svgMaskMatrix,
                                         svgReset->mMask.mLayers[i].mMaskMode);
      if (svgMask) {
        gfxContextMatrixAutoSaveRestore matRestore(maskContext);

        maskContext->Multiply(ThebesMatrix(svgMaskMatrix));
        Rect drawRect = IntRectToRect(IntRect(IntPoint(0, 0), svgMask->GetSize()));
        maskDT->DrawSurface(svgMask, drawRect, drawRect, DrawSurfaceOptions(),
                            DrawOptions(1.0f, compositionOp));
      }
    } else {
      gfxContextMatrixAutoSaveRestore matRestore(maskContext);

      maskContext->Multiply(gfxMatrix::Translation(-devPixelOffsetToUserSpace));
      nsRenderingContext rc(maskContext);
      nsCSSRendering::PaintBGParams  params =
        nsCSSRendering::PaintBGParams::ForSingleLayer(*presContext,
                                                      rc, aParams.dirtyRect,
                                                      aParams.borderArea,
                                                      aParams.frame,
                                                      aParams.builder->GetBackgroundPaintFlags() |
                                                      nsCSSRendering::PAINTBG_MASK_IMAGE,
                                                      i, compositionOp);

      // FIXME We should use the return value, see bug 1258510.
      Unused << nsCSSRendering::PaintBackgroundWithSC(params, aSC,
                                                      *aParams.frame->StyleBorder());
    }
  }

  aOutMaskTransform = ToMatrix(maskSurfaceMatrix);
  if (!aOutMaskTransform.Invert()) {
    return;
  }

  aOutMaskSurface = maskDT->Snapshot();
}
Example #5
0
Pattern*
gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
{
  if (!mPattern) {
    mGfxPattern = new (mSurfacePattern.addr())
      SurfacePattern(mSourceSurface, EXTEND_CLAMP, mTransform);
    return mGfxPattern;
  }

  GraphicsExtend extend = (GraphicsExtend)cairo_pattern_get_extend(mPattern);

  switch (cairo_pattern_get_type(mPattern)) {
  case CAIRO_PATTERN_TYPE_SOLID:
    {
      double r, g, b, a;
      cairo_pattern_get_rgba(mPattern, &r, &g, &b, &a);

      new (mColorPattern.addr()) ColorPattern(Color(r, g, b, a));
      return mColorPattern.addr();
    }
  case CAIRO_PATTERN_TYPE_SURFACE:
    {
      GraphicsFilter filter = (GraphicsFilter)cairo_pattern_get_filter(mPattern);
      cairo_matrix_t mat;
      cairo_pattern_get_matrix(mPattern, &mat);
      gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));

      cairo_surface_t *surf = NULL;
      cairo_pattern_get_surface(mPattern, &surf);

      if (!mSourceSurface) {
        nsRefPtr<gfxASurface> gfxSurf = gfxASurface::Wrap(surf);
        mSourceSurface =
          gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxSurf);
      }

      if (mSourceSurface) {
        Matrix newMat = ToMatrix(matrix);

        AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);

        newMat.Invert();
        double x, y;
        cairo_surface_get_device_offset(surf, &x, &y);
        newMat.Translate(-x, -y);
        mGfxPattern = new (mSurfacePattern.addr())
          SurfacePattern(mSourceSurface, ToExtendMode(extend), newMat, ToFilter(filter));
        return mGfxPattern;
      }
      break;
    }
  case CAIRO_PATTERN_TYPE_LINEAR:
    {
      double x1, y1, x2, y2;
      cairo_pattern_get_linear_points(mPattern, &x1, &y1, &x2, &y2);
      if (!mStops) {
        int count = 0;
        cairo_pattern_get_color_stop_count(mPattern, &count);

        std::vector<GradientStop> stops;

        for (int i = 0; i < count; i++) {
          GradientStop stop;
          double r, g, b, a, offset;
          cairo_pattern_get_color_stop_rgba(mPattern, i, &offset, &r, &g, &b, &a);

          stop.offset = offset;
          stop.color = Color(Float(r), Float(g), Float(b), Float(a));
          stops.push_back(stop);
        }

        mStops = aTarget->CreateGradientStops(&stops.front(), count, ToExtendMode(extend));
      }

      if (mStops) {
        cairo_matrix_t mat;
        cairo_pattern_get_matrix(mPattern, &mat);
        gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));

        Matrix newMat = ToMatrix(matrix);

        AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);

        newMat.Invert();

        mGfxPattern = new (mLinearGradientPattern.addr())
          LinearGradientPattern(Point(x1, y1), Point(x2, y2), mStops, newMat);

        return mGfxPattern;
      }
      break;
    }
  case CAIRO_PATTERN_TYPE_RADIAL:
    {
      if (!mStops) {
        int count = 0;
        cairo_pattern_get_color_stop_count(mPattern, &count);

        std::vector<GradientStop> stops;

        for (int i = 0; i < count; i++) {
          GradientStop stop;
          double r, g, b, a, offset;
          cairo_pattern_get_color_stop_rgba(mPattern, i, &offset, &r, &g, &b, &a);

          stop.offset = offset;
          stop.color = Color(Float(r), Float(g), Float(b), Float(a));
          stops.push_back(stop);
        }

        mStops = aTarget->CreateGradientStops(&stops.front(), count, ToExtendMode(extend));
      }

      if (mStops) {
        cairo_matrix_t mat;
        cairo_pattern_get_matrix(mPattern, &mat);
        gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));

        Matrix newMat = ToMatrix(matrix);

        AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);

        newMat.Invert();

        double x1, y1, x2, y2, r1, r2;
        cairo_pattern_get_radial_circles(mPattern, &x1, &y1, &r1, &x2, &y2, &r2);
        mGfxPattern = new (mRadialGradientPattern.addr())
          RadialGradientPattern(Point(x1, y1), Point(x2, y2), r1, r2, mStops, newMat);

        return mGfxPattern;
      }
      break;
    }
  default:
    /* Reassure the compiler we are handling all the enum values.  */
    break;
  }

  new (mColorPattern.addr()) ColorPattern(Color(0, 0, 0, 0));
  return mColorPattern.addr();
}
void
AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
                                                   Layer* aTransformedSubtreeRoot,
                                                   const Matrix4x4& aPreviousTransformForRoot,
                                                   const Matrix4x4& aCurrentTransformForRoot,
                                                   const LayerMargin& aFixedLayerMargins)
{
  bool isRootFixed = aLayer->GetIsFixedPosition() &&
    !aLayer->GetParent()->GetIsFixedPosition();
  bool isStickyForSubtree = aLayer->GetIsStickyPosition() &&
    aLayer->GetStickyScrollContainerId() ==
      aTransformedSubtreeRoot->GetFrameMetrics().GetScrollId();
  if (aLayer != aTransformedSubtreeRoot && (isRootFixed || isStickyForSubtree)) {
    // Insert a translation so that the position of the anchor point is the same
    // before and after the change to the transform of aTransformedSubtreeRoot.
    // This currently only works for fixed layers with 2D transforms.

    // Accumulate the transforms between this layer and the subtree root layer.
    Matrix ancestorTransform;
    if (!AccumulateLayerTransforms2D(aLayer->GetParent(), aTransformedSubtreeRoot,
                                     ancestorTransform)) {
      return;
    }

    Matrix oldRootTransform;
    Matrix newRootTransform;
    if (!aPreviousTransformForRoot.Is2D(&oldRootTransform) ||
        !aCurrentTransformForRoot.Is2D(&newRootTransform)) {
      return;
    }

    // Calculate the cumulative transforms between the subtree root with the
    // old transform and the current transform.
    Matrix oldCumulativeTransform = ancestorTransform * oldRootTransform;
    Matrix newCumulativeTransform = ancestorTransform * newRootTransform;
    if (newCumulativeTransform.IsSingular()) {
      return;
    }
    Matrix newCumulativeTransformInverse = newCumulativeTransform;
    newCumulativeTransformInverse.Invert();

    // Now work out the translation necessary to make sure the layer doesn't
    // move given the new sub-tree root transform.
    Matrix layerTransform;
    if (!GetBaseTransform2D(aLayer, &layerTransform)) {
      return;
    }

    // Calculate any offset necessary, in previous transform sub-tree root
    // space. This is used to make sure fixed position content respects
    // content document fixed position margins.
    LayerPoint offsetInOldSubtreeLayerSpace = GetLayerFixedMarginsOffset(aLayer, aFixedLayerMargins);

    // Add the above offset to the anchor point so we can offset the layer by
    // and amount that's specified in old subtree layer space.
    const LayerPoint& anchorInOldSubtreeLayerSpace = aLayer->GetFixedPositionAnchor();
    LayerPoint offsetAnchorInOldSubtreeLayerSpace = anchorInOldSubtreeLayerSpace + offsetInOldSubtreeLayerSpace;

    // Add the local layer transform to the two points to make the equation
    // below this section more convenient.
    Point anchor(anchorInOldSubtreeLayerSpace.x, anchorInOldSubtreeLayerSpace.y);
    Point offsetAnchor(offsetAnchorInOldSubtreeLayerSpace.x, offsetAnchorInOldSubtreeLayerSpace.y);
    Point locallyTransformedAnchor = layerTransform * anchor;
    Point locallyTransformedOffsetAnchor = layerTransform * offsetAnchor;

    // Transforming the locallyTransformedAnchor by oldCumulativeTransform
    // returns the layer's anchor point relative to the parent of
    // aTransformedSubtreeRoot, before the new transform was applied.
    // Then, applying newCumulativeTransformInverse maps that point relative
    // to the layer's parent, which is the same coordinate space as
    // locallyTransformedAnchor again, allowing us to subtract them and find
    // out the offset necessary to make sure the layer stays stationary.
    Point oldAnchorPositionInNewSpace =
      newCumulativeTransformInverse * (oldCumulativeTransform * locallyTransformedOffsetAnchor);
    Point translation = oldAnchorPositionInNewSpace - locallyTransformedAnchor;

    if (aLayer->GetIsStickyPosition()) {
      // For sticky positioned layers, the difference between the two rectangles
      // defines a pair of translation intervals in each dimension through which
      // the layer should not move relative to the scroll container. To
      // accomplish this, we limit each dimension of the |translation| to that
      // part of it which overlaps those intervals.
      const LayerRect& stickyOuter = aLayer->GetStickyScrollRangeOuter();
      const LayerRect& stickyInner = aLayer->GetStickyScrollRangeInner();

      translation.y = IntervalOverlap(translation.y, stickyOuter.y, stickyOuter.YMost()) -
                      IntervalOverlap(translation.y, stickyInner.y, stickyInner.YMost());
      translation.x = IntervalOverlap(translation.x, stickyOuter.x, stickyOuter.XMost()) -
                      IntervalOverlap(translation.x, stickyInner.x, stickyInner.XMost());
    }

    // Finally, apply the 2D translation to the layer transform.
    TranslateShadowLayer2D(aLayer, ThebesPoint(translation));

    // The transform has now been applied, so there's no need to iterate over
    // child layers.
    return;
  }

  // Fixed layers are relative to their nearest scrollable layer, so when we
  // encounter a scrollable layer, bail. ApplyAsyncContentTransformToTree will
  // have already recursed on this layer and called AlignFixedAndStickyLayers
  // on it with its own transforms.
  if (aLayer->GetFrameMetrics().IsScrollable() &&
      aLayer != aTransformedSubtreeRoot) {
    return;
  }

  for (Layer* child = aLayer->GetFirstChild();
       child; child = child->GetNextSibling()) {
    AlignFixedAndStickyLayers(child, aTransformedSubtreeRoot,
                              aPreviousTransformForRoot,
                              aCurrentTransformForRoot, aFixedLayerMargins);
  }
}
Example #7
0
void
FillRectWithMask(DrawTarget* aDT,
                 const Rect& aRect,
                 SourceSurface* aSurface,
                 SamplingFilter aSamplingFilter,
                 const DrawOptions& aOptions,
                 ExtendMode aExtendMode,
                 SourceSurface* aMaskSource,
                 const Matrix* aMaskTransform,
                 const Matrix* aSurfaceTransform)
{
  MOZ_ASSERT(!aMaskSource || (aMaskSource && aMaskTransform),
             "aMaskSource must not be passed without a transform");

  if (aMaskSource && aMaskTransform) {
    aDT->PushClipRect(aRect);
    Matrix oldTransform = aDT->GetTransform();

    Matrix inverseMask = *aMaskTransform;
    inverseMask.Invert();

    Matrix transform = oldTransform * inverseMask;
    if (aSurfaceTransform) {
      transform = (*aSurfaceTransform) * transform;
    }

    SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);

    aDT->SetTransform(*aMaskTransform);
    aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);

    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  if (aSurface->GetType() == SurfaceType::RECORDING) {
    MOZ_ASSERT(aOptions.mAlpha == 1.0 &&
               aOptions.mCompositionOp == CompositionOp::OP_OVER);

    aDT->PushClipRect(aRect);
    Matrix oldTransform = aDT->GetTransform();

    Matrix transform = oldTransform;
    if (aSurfaceTransform) {
      transform = (*aSurfaceTransform) * transform;
    }

    InlineTranslator* translator = new InlineTranslator(aDT, transform);
    SourceSurfaceRecording* ss = static_cast<SourceSurfaceRecording*>(aSurface);
    DrawEventRecorderMemory* mr = static_cast<DrawEventRecorderMemory*>(ss->mRecorder.get());

    size_t size = mr->RecordingSize();
    char* buffer = new char[size];
    mr->CopyRecording(buffer, size);
    std::istringstream recording(std::string(buffer, size));

    delete [] buffer;
    translator->TranslateRecording(recording);

    aDT->SetTransform(oldTransform);
    aDT->PopClip();
    return;
  }

  aDT->FillRect(aRect,
                SurfacePattern(aSurface, aExtendMode,
                               aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
                               aSamplingFilter), aOptions);
}
void
LayerManagerComposite::RenderToPresentationSurface()
{
#ifdef MOZ_WIDGET_ANDROID
  if (!AndroidBridge::Bridge()) {
    return;
  }

  void* window = AndroidBridge::Bridge()->GetPresentationWindow();

  if (!window) {
    return;
  }

  EGLSurface surface = AndroidBridge::Bridge()->GetPresentationSurface();

  if (!surface) {
    //create surface;
    surface = GLContextProviderEGL::CreateEGLSurface(window);
    if (!surface) {
      return;
    }

    AndroidBridge::Bridge()->SetPresentationSurface(surface);
  }

  CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get());
  GLContext* gl = compositor->gl();
  GLContextEGL* egl = GLContextEGL::Cast(gl);

  if (!egl) {
    return;
  }

  const IntSize windowSize = AndroidBridge::Bridge()->GetNativeWindowSize(window);

#elif defined(MOZ_WIDGET_GONK)
  CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get());
  nsScreenGonk* screen = static_cast<nsWindow*>(mCompositor->GetWidget())->GetScreen();
  if (!screen->IsPrimaryScreen()) {
    // Only primary screen support mirroring
    return;
  }

  nsWindow* mirrorScreenWidget = screen->GetMirroringWidget();
  if (!mirrorScreenWidget) {
    // No mirroring
    return;
  }

  nsScreenGonk* mirrorScreen = mirrorScreenWidget->GetScreen();
  if (!mirrorScreen->GetTopWindows().IsEmpty()) {
    return;
  }

  EGLSurface surface = mirrorScreen->GetEGLSurface();
  if (surface == LOCAL_EGL_NO_SURFACE) {
    // Create GLContext
    RefPtr<GLContext> gl = gl::GLContextProvider::CreateForWindow(mirrorScreenWidget);
    mirrorScreenWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT,
                                      reinterpret_cast<uintptr_t>(gl.get()));
    surface = mirrorScreen->GetEGLSurface();
    if (surface == LOCAL_EGL_NO_SURFACE) {
      // Failed to create EGLSurface
      return;
    }
  }
  GLContext* gl = compositor->gl();
  GLContextEGL* egl = GLContextEGL::Cast(gl);
  const IntSize windowSize = mirrorScreen->GetNaturalBounds().Size();
#endif

  if ((windowSize.width <= 0) || (windowSize.height <= 0)) {
    return;
  }

  ScreenRotation rotation = compositor->GetScreenRotation();

  const int actualWidth = windowSize.width;
  const int actualHeight = windowSize.height;

  const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize();
  const nsIntRect originalRect = nsIntRect(0, 0, originalSize.width, originalSize.height);

  int pageWidth = originalSize.width;
  int pageHeight = originalSize.height;
  if (rotation == ROTATION_90 || rotation == ROTATION_270) {
    pageWidth = originalSize.height;
    pageHeight = originalSize.width;
  }

  float scale = 1.0;

  if ((pageWidth > actualWidth) || (pageHeight > actualHeight)) {
    const float scaleWidth = (float)actualWidth / (float)pageWidth;
    const float scaleHeight = (float)actualHeight / (float)pageHeight;
    scale = scaleWidth <= scaleHeight ? scaleWidth : scaleHeight;
  }

  const gfx::IntSize actualSize(actualWidth, actualHeight);
  ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize);

  const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0);
  ScopedContextSurfaceOverride overrideSurface(egl, surface);

  Matrix viewMatrix = ComputeTransformForRotation(originalRect,
                                                  rotation);
  viewMatrix.Invert(); // unrotate
  viewMatrix.PostScale(scale, scale);
  viewMatrix.PostTranslate(offset.x, offset.y);
  Matrix4x4 matrix = Matrix4x4::From2D(viewMatrix);

  mRoot->ComputeEffectiveTransforms(matrix);
  nsIntRegion opaque;
  ApplyOcclusionCulling(mRoot, opaque);

  nsIntRegion invalid;
  Rect bounds(0.0f, 0.0f, scale * pageWidth, (float)actualHeight);
  Rect rect, actualBounds;

  mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds);

  // The Java side of Fennec sets a scissor rect that accounts for
  // chrome such as the URL bar. Override that so that the entire frame buffer
  // is cleared.
  ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight);
  egl->fClearColor(0.0, 0.0, 0.0, 0.0);
  egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT);

  const IntRect clipRect = IntRect(0, 0, actualWidth, actualHeight);

  RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect));
  RootLayer()->RenderLayer(clipRect);

  mCompositor->EndFrame();
#ifdef MOZ_WIDGET_GONK
  mCompositor->SetDispAcquireFence(mRoot,
                                   mirrorScreenWidget); // Call after EndFrame()

  RefPtr<Composer2D> composer2D;
  composer2D = mCompositor->GetWidget()->GetComposer2D();
  if (composer2D) {
    composer2D->Render(mirrorScreenWidget);
  }
#endif
}
Example #9
0
int
TFP_Bearing::kt3Drma(double *v, double *vp, double *Fr, double A, double *P, double *vpi) {

  Vector vF (v, 8); 
  Vector vpF (vp, 8); 
  Vector FrF (Fr, 8); 
  Vector PF (P,4);  

  /*
  opserr << "v: " << vF;
  opserr << "vp: " << vpF;
  opserr << "Fr: " << FrF;
  opserr << "A: " << A << endln;
  opserr << "P: " << PF;
  */

  static double Ri[8];
  static double R[8];
  static double N[4];

  static Matrix kcont(8,8);
  static Matrix krot(8,8);

  int cont = 0;

  kthat.Zero(); 
  kt.Zero(); 
  ks.Zero(); 
  Af.Zero(); 
  kcont.Zero(); 
  krot.Zero();
			
  for (int i=0; i<4; i++)
    N[i] = A;
  
  for (int i=0; i<4; i++) {
    int z=4+i;
    Ri[i]=sqrt((r[i]-h[i])*(r[i]-h[i]) - v[z]*v[z]);
    Ri[z]=sqrt((r[i]-h[i])*(r[i]-h[i]) - v[i]*v[i]);
    d[i] = r[i] - sqrt(r[i]*r[i]) - sqrt(v[i]*v[i]+v[z]*v[z]);
    N[i] = A + sqrt((P[0]-P[2])*(P[0]-P[2]) + (P[1]-P[3])*(P[1]-P[3])) * 
      sqrt(v[i]*v[i]+v[z]*v[z])/r[i];
    R[i] = Ri[i];
    R[z] = Ri[z];
  }
  
  double dh =0;
  for (int i=0; i<4; i++) {
    dh += d[i];
  }
  
  //  R[0] = (Ri[0]*Ri[2])/(Ri[2]+fabs(v[2])*Ri[0]);
  //  R[1]=(Ri[1]*Ri[3])/(Ri[3]+fabs(v[3])*Ri[1]);
  //  R[4]=(Ri[4]*Ri[6])/(Ri[6]+fabs(v[4])*Ri[6]);
  //  R[5]=(Ri[5]*Ri[7])/(Ri[7]+fabs(v[5])*Ri[7]);

  double PNorm = 0.0;
  for (int i=0; i<4; i++) {
    PNorm += P[i]*P[i];
  }
  PNorm = sqrt(PNorm);
  
  N[0]=A+PNorm*(sqrt(v[0]*v[0]+v[4]*v[4])/r[0]+sqrt(v[2]*v[2]+v[6]*v[6])/r[2]);
  N[1]=A+PNorm*(sqrt(v[1]*v[1]+v[5]*v[5])/r[1]+sqrt(v[3]*v[3]+v[7]*v[7])/r[3]);

  for (int i=0; i<4; i++) {
    int z=4+i;
    //    double vyield=0.01;
    double qYield=mu[i]*N[i];
    double k0=qYield/vyield;
    
    //get trial shear forces of hysteretic component
    double qTrialx = k0*(v[i] -vs[i]- vp[i]);
    double qTrialy = k0*(v[z] -vs[z]- vp[z]);

    // compute yield criterion of hysteretic component
    double qTrialNorm = sqrt(qTrialx*qTrialx+qTrialy*qTrialy);
    double Y = qTrialNorm - qYield;
 
    // elastic step -> no updates for pastic displacements required
    if (Y <= 0 ) {
      // set tangent stiffnesses
      ks(i,i) = k0 + N[i]/R[i];
      ks(z,z) = k0 + N[i]/R[z];
      vpi[i] = vp[i];
      vpi[z] = vp[z];

    // plastic step -> return mapping
    } else {    
      // compute consistency parameters
      double dGamma = Y/k0;
      // update plastic displacements
      vpi[i] = vp[i] + dGamma*qTrialx/qTrialNorm;
      vpi[z] = vp[z] + dGamma*qTrialy/qTrialNorm;
      //  set tangent stiffnesses
      double qTrialNorm3 = qTrialNorm*qTrialNorm*qTrialNorm;
      ks(i,i) =  qYield*k0*qTrialy*qTrialy/qTrialNorm3 + N[i]/R[i];
      ks(i,z) = -qYield*k0*qTrialx*qTrialy/qTrialNorm3;
      ks(z,i) = -qYield*k0*qTrialx*qTrialy/qTrialNorm3;
      ks(z,z) =  qYield*k0*qTrialx*qTrialx/qTrialNorm3 + N[i]/R[z];
    }

    //opserr << "ks: " << ks;

    // restrainer contact stiffness
    double vt=sqrt(v[i]*v[i]+v[z]*v[z]); //local displacment of surface
    double rt=(dOut[i]-dIn[i])/2.0;  //restrainer distance
    double del=0.1;

    if (vt>rt) {
      cont=1;
      double krim=k0*2;
      // set restrainer stiffnesses
      double vi2 = v[i]*v[i];
      double vz2 = v[z]*v[z];
      kcont(i,i) =  krim*v[i]*v[i]/(vi2+vz2);
      kcont(i,z) =  krim*v[z]*v[i]/(vi2+vz2);
      kcont(z,i) =  krim*v[z]*v[i]/(vi2+vz2);
      kcont(z,z) =  krim*v[z]*v[z]/(vi2+vz2);
       
      //force rotation matrix
      double F=sqrt(Fr[i]*Fr[i]+Fr[z]*Fr[z]);
      krot(i,i) =  F* ((v[i]+del)/sqrt((v[i]+del)*(v[i]+del)+vz2) - (v[i]-del)/sqrt((v[i]-del)*(v[i]-del)+vz2));
      krot(i,z) =  F* (v[i]/sqrt(vi2+(v[z]+del)*(v[z]+del)) - v[i]/sqrt(vi2+(v[z]-del)*(v[z]-del)));
      krot(z,i) =  F* (v[z]/sqrt((v[i]+del)*(v[i]+del)+vz2) - v[z]/sqrt((v[i]-del)*(v[i]-del)+vz2));
      krot(z,z) =  F* ((v[z]+del)/sqrt(vi2+(v[z]+del)*v[z]+del) - (v[z]-del)/sqrt(vi2+(v[z]-del)*v[z]-del));
    }
  }

    
  double del = 0.1;

  for (int i=0; i<8; i++)
    for (int j=0; j<8; j++)
      ksrest(i,j)=kcont(i,j)+krot(i,j)/(del * 2.0);

  //  opserr << "ksrest: " << ksrest;

  Af.Zero();
  Af(0,4) = Ri[0];
  Af(1,5) = Ri[1];
  Af(2,0) = Ri[2]/(Ri[2]+Ri[3]); 
  Af(2,2) = -Ri[2]/(Ri[2]+Ri[3]);
  Af(2,4) = -Ri[2]*(Ri[0]+Ri[3])/(Ri[2]+Ri[3]);
  Af(2,5) = Ri[2]*(-Ri[1]+Ri[3])/(Ri[2]+Ri[3]);
  Af(3,0) = Ri[3]/(Ri[2]+Ri[3]);
  Af(3,2) = -Ri[3]/(Ri[2]+Ri[3]);
  Af(3,4) = Ri[3]*(-Ri[0]+Ri[2])/(Ri[2]+Ri[3]);
  Af(3,5) = Ri[3]*(-Ri[2]-Ri[1])/(Ri[2]+Ri[3]);
  Af(4,6) = Ri[4];
  Af(5,7) = Ri[5];
  Af(6,1) = Ri[6]/(Ri[6]+Ri[7]);
  Af(6,3) = -Ri[6]/(Ri[6]+Ri[7]);
  Af(6,6) = -Ri[6]*(Ri[4]+Ri[7])/(Ri[6]+Ri[7]);
  Af(6,7) = Ri[6]*(-Ri[5]+Ri[7])/(Ri[6]+Ri[7]);
  Af(7,1) = Ri[7]/(Ri[6]+Ri[7]);
  Af(7,3) = -Ri[7]/(Ri[6]+Ri[7]);
  Af(7,6) = Ri[7]*(-Ri[4]+Ri[6])/(Ri[6]+Ri[7]);
  Af(7,7) = Ri[7]*(-Ri[6]-Ri[5])/(Ri[6]+Ri[7]);


  //  opserr << "Af: " << Af;
  //  opserr << "ks: " << ks;
  //  opserr << "ksrest: " << ksrest;

  static Matrix KsPlusKsrest(8,8);


  KsPlusKsrest = ks;
  KsPlusKsrest += ksrest;
  KsPlusKsrest(0,2) = KsPlusKsrest(0,2) + N[0]/R[2];
  KsPlusKsrest(1,3) = KsPlusKsrest(1,3) + N[1]/R[5];
  KsPlusKsrest(4,6) = KsPlusKsrest(4,6) + N[4]/R[6];
  KsPlusKsrest(5,7) = KsPlusKsrest(5,7) + N[5]/R[7];
    
  kt.addMatrixTripleProduct(0.0, Af, KsPlusKsrest,1.0);

  //  opserr << "kt:" << kt;

  static Matrix Kee(4,4);

  for (int i=0; i<4; i++) {
    for (int j=0; j<4; j++) {
      kthat(i,j) = kt(i,j);
      Kee(i,j) = kt(i+4, j+4);
      kei(i,j) = kt(i+4, j);
    }
  }

  Kee.Invert(kee);
  kthat.addMatrixTripleProduct(1.0, kei, kee, -1.0);

  //  opserr << "kthat: " << kthat;

  return cont;
}
Example #10
0
const Matrix&
J2BeamFiber2d::getTangent (void)
{
  double twoG = E/(1.0+nu);
  double G = 0.5*twoG;

  double sig[2];
  sig[0] = E*(Tepsilon(0)-epsPn[0]);
  sig[1] = G*(Tepsilon(1)-epsPn[1]);

  static const double one3 = 1.0/3;
  static const double two3 = 2.0*one3;
  static const double root23 = sqrt(two3);

  double two3Hkin = two3*Hkin;

  double xsi[2];
  //xsi[0] = sig[0] - two3*Hkin*1.5*epsPn[0];
  //xsi[1] = sig[1] - two3*Hkin*0.5*epsPn[1];
  xsi[0] = sig[0] -      Hkin*epsPn[0];
  xsi[1] = sig[1] - one3*Hkin*epsPn[1];

  double q = sqrt(two3*xsi[0]*xsi[0] + 2.0*xsi[1]*xsi[1]);
  double F = q - root23*(sigmaY + Hiso*alphan);

  if (F < -100*DBL_EPSILON) {
    D(0,0) = E;
    D(1,1) = G;
    D(0,1) = D(1,0) = 0.0;

    epsPn1[0] = epsPn[0];
    epsPn1[1] = epsPn[1];
  }
  else {

    // Solve for dg
    double dg = 0.0;

    static Vector R(3);
    R(0) = 0.0; R(1) = 0.0; R(2) = F;
    static Vector x(3);
    x(0) = xsi[0]; x(1) = xsi[1]; x(2) = dg;

    static Matrix J(3,3);
    static Vector dx(3);

    int iter = 0; int maxIter = 25;
    while (iter < maxIter && R.Norm() > sigmaY*1.0e-14) {
        iter++;

        J(0,0) = 1.0 + dg*two3*(E+Hkin); J(0,1) = 0.0;
        J(1,0) = 0.0; J(1,1) = 1.0 + dg*(twoG+two3Hkin);

        J(0,2) = two3*(E+Hkin)*x(0);
        J(1,2) = (twoG+two3Hkin)*x(1);

        //J(2,0) = x(0)*two3/q; J(2,1) = x(1)*2.0/q;
        J(2,0) = (1.0-two3*Hiso*dg)*x(0)*two3/q;
        J(2,1) = (1.0-two3*Hiso*dg)*x(1)*2.0/q;

        //J(2,2) = -root23*Hiso;
	J(2,2) = -two3*Hiso*q;

        J.Solve(R, dx);
        x.addVector(1.0, dx, -1.0);

        dg = x(2);
        dg_n1 = dg;

        q = sqrt(two3*x(0)*x(0) + 2.0*x(1)*x(1));

        R(0) = x(0) - xsi[0] + dg*two3*(E+Hkin)*x(0);
        R(1) = x(1) - xsi[1] + dg*(twoG+two3Hkin)*x(1);
        R(2) = q - root23*(sigmaY + Hiso*(alphan+dg*root23*q));
    }

    if (iter == maxIter) {
      //opserr << "J2BeamFiber2d::getTangent -- maxIter reached " << R.Norm() << endln;
    }

    alphan1 = alphan + dg*root23*q;

    epsPn1[0] = epsPn[0] + dg*two3*x(0);
    epsPn1[1] = epsPn[1] + dg*2.0*x(1);

    //J(2,0) = (1.0-two3*Hiso*dg)*x(0)*two3/q; J(2,1) = (1.0-two3*Hiso*dg)*x(1)*2.0/q;
    //J(2,2) = -two3*Hiso*q;
    //static Matrix invJ(3,3);
    //J.Invert(invJ);

    J(0,0) = 1.0 + dg*two3*E/(1.0+dg*two3Hkin); J(0,1) = 0.0;
    J(1,0) = 0.0; J(1,1) = 1.0 + dg*twoG/(1.0+dg*two3Hkin);

    J(0,2) = (two3*E-dg*two3*E/(1.0+dg*two3Hkin)*two3Hkin)*x(0);
    J(1,2) = (twoG  -dg*  twoG/(1.0+dg*two3Hkin)*two3Hkin)*x(1);

    //J(2,0) = x(0)/q*two3/(1.0+dg*two3Hkin);
    //J(2,1) = x(1)/q* 2.0/(1.0+dg*two3Hkin);
    J(2,0) = (1.0-two3*Hiso*dg)*x(0)/q*two3/(1.0+dg*two3Hkin);
    J(2,1) = (1.0-two3*Hiso*dg)*x(1)/q* 2.0/(1.0+dg*two3Hkin);

    //J(2,2) = -(x(0)/q*two3/(1.0+dg*two3Hkin)*two3Hkin*x(0))
    //         -(x(1)/q* 2.0/(1.0+dg*two3Hkin)*two3Hkin*x(1));
    //J(2,2) = -q*two3Hkin/(1.0+dg*two3Hkin) - root23*Hiso;
    J(2,2) = -q*two3Hkin/(1.0+dg*two3Hkin) - two3*Hiso*q;

    static Matrix invJ(3,3);
    J.Invert(invJ);

    D(0,0) = invJ(0,0)*E;
    D(1,0) = invJ(1,0)*E;
    D(0,1) = invJ(0,1)*G;
    D(1,1) = invJ(1,1)*G;
  }

  return D;
}