示例#1
0
inline void CreateOpenLineList(IntCoord *cpx, IntCoord *cpy, int cpcount) {
    int cpi;
    
    llcount = 0;
    CalcBSpline(
	cpx[0], cpy[0], cpx[0], cpy[0], cpx[0], cpy[0], cpx[1], cpy[1]
    );
    CalcBSpline(
	cpx[0], cpy[0], cpx[0], cpy[0], cpx[1], cpy[1], cpx[2], cpy[2]
    );

    for (cpi = 1; cpi < cpcount - 2; ++cpi) {
	CalcBSpline(
	    cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
	    cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 2], cpy[cpi + 2]
        );
    }
    CalcBSpline(
	cpx[cpi - 1], cpy[cpi - 1], cpx[cpi], cpy[cpi],
	cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 1], cpy[cpi + 1]
    );
    CalcBSpline(
	cpx[cpi], cpy[cpi], cpx[cpi + 1], cpy[cpi + 1],
	cpx[cpi + 1], cpy[cpi + 1], cpx[cpi + 1], cpy[cpi + 1]
    );
}
示例#2
0
PetscErrorCode BSSPsi(BSS self, Vec c, Vec xs, Vec ys) {
  
  // yj = sum(i) ci ui(xj)

  //  PetscErrorCode ierr;
  //  ierr = BSSChcek(self); CHKERRQ(ierr);
  PetscErrorCode ierr;  
  int nc; VecGetSize(c, &nc);
  int nb; BSSGetSize(self, &nb);
  int nx; VecGetSize(xs, &nx);
  int ny; VecGetSize(ys, &ny);
  if(nc != nb) {
    SETERRQ(self->comm, 1, "size of c must be same as basis size");
  }
  if(nx != ny) {
    SETERRQ(self->comm, 1, "xs and ys must be same size");
  }

  Mat f_jx_ib;
  ierr = MatCreate(self->comm, &f_jx_ib); CHKERRQ(ierr);
  ierr = MatSetSizes(f_jx_ib, PETSC_DECIDE, PETSC_DECIDE, nx, nb); CHKERRQ(ierr);
  ierr = MatSetUp(f_jx_ib);               CHKERRQ(ierr);

  PetscScalar *x_ptr;
  VecGetArray(xs, &x_ptr);

  PetscReal *x_r_ptr; PetscMalloc1(nx, &x_r_ptr);
  for(int ix = 0; ix < nx; ix++)
    x_r_ptr[ix] = creal(x_ptr[ix]);

  PetscScalar *x_c_ptr; PetscMalloc1(nx, &x_c_ptr);
  ierr = CScalingCalc(self->c_scaling, x_r_ptr, nx, NULL, x_c_ptr); CHKERRQ(ierr);

  for(int jx = 0; jx < nx; jx++) {
    for(int ib = 0; ib < nb; ib++) {
      PetscScalar y;
      PetscBool zeroq;
      ierr = CalcBSpline(self->order, self->ts_r, self->ts_s, self->b_idx_list[ib],
			 x_r_ptr[jx], x_c_ptr[jx], &y, &zeroq); CHKERRQ(ierr);
      if(!zeroq) {
	ierr = MatSetValue(f_jx_ib, jx, ib, y, INSERT_VALUES); CHKERRQ(ierr);
      }
    }
  }  
  MatAssemblyBegin(f_jx_ib, MAT_FINAL_ASSEMBLY);
  MatAssemblyEnd(f_jx_ib, MAT_FINAL_ASSEMBLY);

  ierr = MatMult(f_jx_ib, c, ys); CHKERRQ(ierr);

  MatDestroy(&f_jx_ib);
  VecRestoreArray(xs, &x_ptr);
  PetscFree(x_r_ptr);
  PetscFree(x_c_ptr);
  return 0;
}
示例#3
0
PetscErrorCode CalcDerivBSpline(int order, PetscReal* ts_r, PetscScalar *ts, 
				int i, double x_r, PetscScalar x, PetscScalar* y,
				PetscBool *zeroq) {
  
  if(order < 1) {
    SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, 
	    "order must be positive integer\n");
  }
  
  PetscBool _zeroq;  

  if(order == 1) {
    *y = 0.0;
    _zeroq = PETSC_TRUE;
  } else {

    int k = order;
    PetscScalar bs0;
    PetscBool zeroq0;
    CalcBSpline(k-1, ts_r, ts, i, x_r, x, &bs0, &zeroq0);
    PetscScalar bs1;
    PetscBool zeroq1;
    CalcBSpline(k-1, ts_r, ts, i+1, x_r, x, &bs1, &zeroq1);
    double eps = 0.000000001;
    PetscScalar acc = 0.0;
    if(ScalarAbs(bs0) > eps && !zeroq0)
    acc += (k-1)/(ts[i+k-1]-ts[i]) * bs0;
    if(ScalarAbs(bs1) > eps && !zeroq1)
      acc -= (k-1)/(ts[i+k]-ts[i+1]) * bs1;
    *y = acc;
    _zeroq = (zeroq0 && zeroq1);
  }
  if(zeroq != NULL) 
    *zeroq = _zeroq;
  return 0;
}
示例#4
0
PetscErrorCode BSSBasisPsi(BSS self, int i, PetscReal x, PetscScalar *y) {

  PetscErrorCode ierr;
  ierr = BSSCheck(self); CHKERRQ(ierr);
  PetscScalar z;

  PetscReal xs[1] = {x};
  PetscScalar Rxs[1];
  CScalingCalc(self->c_scaling, xs, 1, NULL, Rxs);
  
  CalcBSpline(self->order, 
	      self->ts_r, 
	      self->ts_s, 
	      self->b_idx_list[i], 
	      xs[0], 
	      Rxs[0],
	      &z,
	      NULL);
  *y = z;
  return 0;
}
示例#5
0
int testCalcBSpline() {
  PrintTimeStamp(PETSC_COMM_SELF, "calc", NULL);

  // see paper
  int order = 3;
  
  // overlaped knot points list
  double ts_r[10] = {0.0, 0.0, 0.0, 
		   1.0, 2.0, 3.0, 4.0,
		   5.0, 5.0, 5.0};
  PetscScalar ts_s[10];
  for(int i = 0; i < 10; i++)
    ts_s[i] = ts_r[i];
  
  // non overlaped points list
  //double zs[6] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}; 

  PetscBool zeroq;
  PetscScalar y = 777.0;
  CalcBSpline(order, ts_r, ts_s, 0, 0.0, 0.0, &y, &zeroq); 
  ASSERT_DOUBLE_EQ(1.0, y); ASSERT_FALSE(zeroq);
  CalcBSpline(order, ts_r, ts_s, 0, 1.0, 1.0, &y, &zeroq);
  ASSERT_DOUBLE_EQ(0.0, y); ASSERT_TRUE(zeroq);
  CalcBSpline(order, ts_r, ts_s, 6, 4.0, 4.0, &y, &zeroq); 
  ASSERT_DOUBLE_EQ(0.0, y); ASSERT_TRUE(zeroq);
  
  PetscScalar x = 0.34;
  CalcBSpline(     order, ts_r, ts_s, 2, x, x, &y, &zeroq);
  ASSERT_DOUBLE_EQ(0.5*x*x, y); ASSERT_FALSE(zeroq);
  CalcDerivBSpline(order, ts_r, ts_s, 2, x, x, &y, &zeroq);
  ASSERT_DOUBLE_EQ(x, y); ASSERT_FALSE(zeroq);

  x = 2.44;
  CalcBSpline(     order, ts_r, ts_s, 2, x, x, &y, &zeroq);
  ASSERT_DOUBLE_EQ(0.5*x*x-3*x+4.5, y); ASSERT_FALSE(zeroq);
  CalcDerivBSpline(order, ts_r, ts_s, 2, x, x, &y, &zeroq);
  ASSERT_DOUBLE_EQ(x-3.0, y); ASSERT_FALSE(zeroq);

  x = 3.44;
  CalcBSpline(     order, ts_r, ts_s, 2, x, x, &y, &zeroq);
  ASSERT_DOUBLE_EQ(0.0, y); ASSERT_TRUE(zeroq);
  CalcDerivBSpline(order, ts_r, ts_s, 2, x, x, &y, &zeroq); 
  ASSERT_DOUBLE_EQ(0.0, y); ASSERT_TRUE(zeroq);

  return 0;
}
示例#6
0
PetscErrorCode CalcBSpline(int k, double* ts_r, PetscScalar* ts, 
			   int i, double x_r,   PetscScalar x, PetscScalar* y,
			   PetscBool *zeroq) {

  if(k < 1) {
    SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, 
	    "order must be positive integer\n");
  }

  PetscBool _zeroq;

  if(x_r < ts_r[i] || ts_r[i+k] < x_r) {
    *y = 0.0; 
    if(zeroq != NULL)
      *zeroq = PETSC_TRUE;
    return 0;
  }

  if(k == 1) {
    if(ts_r[i] <= x_r && x_r < ts_r[i+1]) {
      *y = 1.0;
      _zeroq = PETSC_FALSE;
    } else {
      *y = 0.0;
      _zeroq = PETSC_TRUE;
    }
  } else {
    PetscScalar ti    = ts[i];
    PetscScalar ti1   = ts[i+1];
    PetscScalar tidm1 = ts[i+k-1];
    PetscScalar tid   = ts[i+k];
    PetscBool zeroq0, zeroq1;
    PetscScalar bs0; CalcBSpline(k-1, ts_r, ts, i,   x_r, x, &bs0, &zeroq0);
    PetscScalar bs1; CalcBSpline(k-1, ts_r, ts, i+1, x_r, x, &bs1, &zeroq1);
    
    _zeroq = PETSC_TRUE;
    PetscScalar acc = 0.0;
    //if(ScalarAbs(bs0) > 0.000000001 && !zeroq0) {
    if(!zeroq0) {
      PetscScalar x_minus_ti = x - ti;
      if(ScalarAbs(x_minus_ti) > 0.00000000001) {
	acc += x_minus_ti / (tidm1 - ti) * bs0;
      } else {
	zeroq0 = PETSC_TRUE;
      }
    }
    //    if(ScalarAbs(bs1) > 0.000000001 && !zeroq1) {
    if( !zeroq1) {
      if(ScalarAbs(tid-x) > 0.00000000001) {
	acc += (tid - x) / (tid - ti1) * bs1;
      } else {
	zeroq1 = PETSC_TRUE;
      }
    }
    *y = acc;
    _zeroq = zeroq1 && zeroq0;
  }
  if(zeroq != NULL)
    *zeroq = _zeroq;
  return 0;
}
示例#7
0
PetscErrorCode BSSSetUp(BSS self) {

  PetscErrorCode ierr;

  // check knots are setted
  if(!self->set_knots)
    SETERRQ(self->comm, 1, "Knots information is not setted. Call BSSSetKnots first.");

  //  set default scaler
  if(self->c_scaling == NULL) 
    BSSSetCScaling(self, NULL);
  
  // copy ts_r and  ts_s
  PetscReal *zs; PetscInt num_zs;
  BPSGetZs(self->bps, &zs, &num_zs);

  for(int i = 0; i < self->order-1; i++) {
    self->ts_r[i] = zs[0];
    self->ts_r[self->order-1+num_zs+i] = zs[num_zs-1];
  }
  for(int i = 0; i < num_zs; i++) 
    self->ts_r[i+self->order-1] = zs[i];
  PetscFree(zs);
  CScalingCalc(self->c_scaling, self->ts_r, self->num_ts, NULL, self->ts_s);
  //  for(int i = 0; i < self->num_ts; i++)
  //    self->ts_s[i] = self->ts_r[i];

  // index of basis
  for(int ib = 0; ib < self->num_basis; ib++)
    self->b_idx_list[ib] = ib + 1;

  // each element
  for(int ie = 0; ie < self->num_ele; ie++) {
    PetscScalar a, b; a = self->bps->zs[ie]; b = self->bps->zs[ie+1];
    for(int iq = 0; iq < self->order; iq++) {
      PetscReal x_r[1], w_r[1];
      PetscScalar x_c[1];
      int ix = ie*self->order+iq;
      PetscScalar quad_x, quad_w;
      LegGauss(self->order, iq, &quad_x, &quad_w);
      x_r[0] = creal(quad_x); w_r[0] = creal(quad_w);
      x_r[0] = (b+a)/2.0  + (b-a)/2.0 * x_r[0]; w_r[0] = (b-a)/2.0*w_r[0];
      CScalingCalc(self->c_scaling, x_r, 1, NULL, x_c);
      self->xs[ix] = x_r[0]; 
      self->ws[ix] = w_r[0];
      self->xs_s[ix] = x_c[0];
            
      for(int ib = 0; ib < self->num_basis; ib++) {
	PetscScalar y;
	PetscScalar dy;
	PetscReal *ts_r = self->ts_r;
	PetscScalar *ts_s = self->ts_s;
	int idx = self->b_idx_list[ib];
	CalcBSpline(     self->order, ts_r, ts_s, idx, x_r[0], x_c[0], &y,  NULL);
	CalcDerivBSpline(self->order, ts_r, ts_s, idx, x_r[0], x_c[0], &dy, NULL);
	int iy = ib*(self->num_ele*self->order) + ie*self->order + iq;
	self->vals[iy] = y;  
	self->derivs[iy] = dy;
      }
    }
  }

  int n_xs = self->num_ele * self->order;
  ierr = CScalingCalc(self->c_scaling, self->xs, n_xs,
		      self->qrs, self->Rrs); CHKERRQ(ierr);
  self->setup = PETSC_TRUE;
  
  return 0;
}