示例#1
0
int main(int argc, char *argv[]) {
    
    // Test array-array inner product
    
    double v1 [5] = {0, 1, 2, 3, 4};
    double v2 [5] = {4, 3, 2, 1, 0};
    double result = 10;
    int len       = 5;
    
    assert(innerProduct(v1,v2,len)==result && "tools - innerProduct, array-array gave an unexpected result");
    
    // Test vector-vector inner product
    
    std::vector<double> vv1, vv2;
    for (int i=0;i<len;i++) { vv1.push_back(v1[i]); vv2.push_back(v2[i]); }
    
    assert(innerProduct(vv1,vv2)==result && "tools - innerProduct, vector-vector gave an unexpected result");
    
    // Test Vector-Vector inner product
    
    Vector vvv1, vvv2;
    for (int i=0;i<len;i++) { vvv1.push_back(vv1); vvv2.push_back(vv2); }
    
    assert(innerProduct(vvv1,vvv2)==(len*result) && "tools - innerProduct, Vector-Vector gave an unexpected result");
    
    // Test sparse Vector-Vector inner product
    
    IntVector sparse;
    for (int i=0;i<len;i++) { sparse.push_back(std::vector<int>()); sparse[i].push_back(i); }
    
    assert(innerProduct(vvv1,vvv2,sparse)==result && "tools - innerProduct, sparse Vector-Vector gave an unexpected result");
    
	return 0;

}
示例#2
0
bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t)
{

	float e1[3],e2[3],h[3],s[3],q[3];
	float a,f,u,v;

	vector(e1,v1,v0);
	vector(e2,v2,v0);
	crossProduct(h,d,e2);
	a = innerProduct(e1,h);

	if (a > -0.00001 && a < 0.00001)
		return(false);

	f = 1/a;
	vector(s,p,v0);
	u = f * (innerProduct(s,h));

	if (u < 0.0 || u > 1.0)
		return(false);

	crossProduct(q,s,e1);
	v = f * innerProduct(d,q);
	if (v < 0.0 || u + v > 1.0)
		return(false);
	// at this stage we can compute t to find out where
	// the intersection point is on the line
	t = f * innerProduct(e2,q);
	if (t > 0) // ray intersection
		return(true);
	else // this means that there is a line intersection
		 // but not a ray intersection
		 return (false);
}
示例#3
0
double SCL::flux(const Point<DIM>& p,
                 double u_l, double u_r,
                 const std::vector<double>& n) const 
{
  std::vector<double> f_l((*_f_)(p, u_l));
  std::vector<double> f_r((*_f_)(p, u_r));
  double alpha0 = (*_v_)(p, u_l);
  double alpha1 = (*_v_)(p, u_r);
  double alpha = std::max(alpha0, alpha1);
  return 0.5*((innerProduct(f_l, n) + innerProduct(f_r, n)) -
              alpha*(u_r - u_l));
}
示例#4
0
/** input: n -- normal, v0 -- a point on plane
      p0, p1 -- define a vector
    output: pr -- intersection point

    r = dot(n,(v0-p0))/dot(n,(p1-p0))
    pr = p0+r*(p1-p0)
*/
GLfloat pointOnIntersectsPlaneEllipsoid(GLfloat n[3], GLfloat v0[3],
                                        GLfloat p0[3], GLfloat p1[3], GLfloat pr[3]) {
  GLfloat r;
  GLfloat v1[3], v2[3];
  vector(v1, v0, p0);
  vector(v2, p1, p0);

  r = innerProduct(n, v1) / innerProduct(n, v2);

  pr[0] = r * v2[0] + p0[0];
  pr[1] = r * v2[1] + p0[1];
  pr[2] = r * v2[2] + p0[2];

  return r;
}
示例#5
0
float distancePointLineOnPlane (vector_t const point,
                                const line_t line, const plane_t plane)
{
  vector_t normal_in_plane = normalizeVector(crossProduct(
                               line.direction, plane.normal));
  return innerProduct(subtractVectors(point,line.point),normal_in_plane);
}
示例#6
0
/** input n -- normal, v0 -- a point on plane
    P -- object point
    output P1 --projection point on the plane
*/
void projectionOnPlane(GLfloat n[3], GLfloat V0[3], GLfloat P[3], GLfloat P1[3]) {
  GLfloat V0P[3];
  vector(V0P, P, V0);
  normalize(n);
  productVectorScaler(n, innerProduct(V0P, n) , V0P);
  vector(P1, P, V0P);
}
示例#7
0
void ISOP2P1::getMonitor()
{
	/// 限制最大迭代步数.
	maxStep() = max_step;
	/// 同步网格.
	syncMesh();

	FEMFunction<double, DIM> _u_h(fem_space_p);
	FEMFunction<double, DIM> _v_h(fem_space_p);
	Operator::L2Interpolate(v_h[0], _u_h);
	Operator::L2Interpolate(v_h[1], _v_h);
    
	FEMSpace<double, DIM>::ElementIterator the_element = fem_space_p.beginElement();
	FEMSpace<double, DIM>::ElementIterator end_element = fem_space_p.endElement();
	for (int i = 0; the_element != end_element; ++the_element) 
	{
		double volume = the_element->templateElement().volume();
		const QuadratureInfo<DIM>& quad_info = the_element->findQuadratureInfo(3);
		std::vector<double> jacobian = the_element->local_to_global_jacobian(quad_info.quadraturePoint());
		int n_quadrature_point = quad_info.n_quadraturePoint();
		std::vector<Point<DIM> > q_point = the_element->local_to_global(quad_info.quadraturePoint());
		std::vector<std::vector<double> > basis_value = the_element->basis_function_value(q_point);
		std::vector<double> u_h_value = _u_h.value(q_point, *the_element);
		std::vector<double> v_h_value = _v_h.value(q_point, *the_element);
		std::vector<std::vector<double> > u_h_gradient = _u_h.gradient(q_point, *the_element);
		std::vector<std::vector<double> > v_h_gradient = _v_h.gradient(q_point, *the_element);
		float d = 0, area = 0, norm = 0;
		for (int l = 0; l < n_quadrature_point; ++l) 
		{
			double Jxw = quad_info.weight(l) * jacobian[l] * volume;
			area += Jxw;
			norm += u_h_value[l] * u_h_value[l] + v_h_value[l] * v_h_value[l];
			d += Jxw * (innerProduct(u_h_gradient[l], u_h_gradient[l]) + innerProduct(v_h_gradient[l], v_h_gradient[l]));
		}
		norm = 1.0 / (eps + sqrt(norm));
		monitor(i++) = d / area;
	}
	std::cout << "max monitor=" << *std::max_element(monitor().begin(), monitor().end())
		  << "\tmin monitor=" << *std::min_element(monitor().begin(), monitor().end())
		  << std::endl;
	double max_monitor = *std::max_element(monitor().begin(), monitor().end());
	smoothMonitor(2);
	for (int i = 0; i < n_geometry(2); ++i)
		monitor(i) = 1.0 / sqrt(1.0 + alpha * monitor(i) * monitor(i));
};
示例#8
0
文件: main.cpp 项目: radi9/svm
double kernel(vector<double> a, vector<double> b) {
//	double distance;
//	cout.precision(19);
//	distance = absDistance(a, b);
//	distance = pow(distance, 2);
//	double temp = exp(-sigma * distance);
//	return temp;

	return exp(-sigma*(pow(v_length(a),2) + pow(v_length(b),2)- 2 * innerProduct(a,b)));
}
示例#9
0
static void findCircle3pts(Point2f *pts, Point2f &center, float &radius)
{
    // two edges of the triangle v1, v2
    Point2f v1 = pts[1] - pts[0];
    Point2f v2 = pts[2] - pts[0];

    if (innerProduct(v1, v2) == 0.0f)
    {
        // v1, v2 colineation, can not determine a unique circle
        // find the longtest distance as diameter line
        float d1 = (float)norm(pts[0] - pts[1]);
        float d2 = (float)norm(pts[0] - pts[2]);
        float d3 = (float)norm(pts[1] - pts[2]);
        if (d1 >= d2 && d1 >= d3)
        {
            center = (pts[0] + pts[1]) / 2.0f;
            radius = (d1 / 2.0f);
        }
        else if (d2 >= d1 && d2 >= d3)
        {
            center = (pts[0] + pts[2]) / 2.0f;
            radius = (d2 / 2.0f);
        }
        else if (d3 >= d1 && d3 >= d2)
        {
            center = (pts[1] + pts[2]) / 2.0f;
            radius = (d3 / 2.0f);
        }
    }
    else
    {
        // center is intersection of midperpendicular lines of the two edges v1, v2
        // a1*x + b1*y = c1 where a1 = v1.x, b1 = v1.y
        // a2*x + b2*y = c2 where a2 = v2.x, b2 = v2.y
        Point2f midPoint1 = (pts[0] + pts[1]) / 2.0f;
        float c1 = midPoint1.x * v1.x + midPoint1.y * v1.y;
        Point2f midPoint2 = (pts[0] + pts[2]) / 2.0f;
        float c2 = midPoint2.x * v2.x + midPoint2.y * v2.y;
        float det = v1.x * v2.y - v1.y * v2.x;
        float cx = (c1 * v2.y - c2 * v1.y) / det;
        float cy = (v1.x * c2 - v2.x * c1) / det;
        center.x = (float)cx;
        center.y = (float)cy;
        cx -= pts[0].x;
        cy -= pts[0].y;
        radius = (float)(std::sqrt(cx *cx + cy * cy));
    }
}
void ISOP2P1::updateSolution()
{
	/// 更新插值点.
	fem_space_p.updateDofInterpPoint();
	fem_space_v.updateDofInterpPoint();
	
	/// 备份数值解.
	FEMFunction<double, DIM> _u_h(v_h[0]);
	FEMFunction<double, DIM> _v_h(v_h[1]);
	FEMFunction<double, DIM> _p_h(p_h);
	const double& msl = moveStepLength();
	/// 因为有限元空间插值点变化, 重新构造矩阵.
	buildMatrixStruct();
	buildMatrix();
	/// 因为网格移动量为小量, 因此时间步长可以相对取的大些.
	double _dt = 0.1;
    
	int n_dof_v = fem_space_v.n_dof();
	int n_dof_p = fem_space_p.n_dof();
	int n_total_dof = DIM * n_dof_v + n_dof_p;
	int n_total_dof_v = DIM * n_dof_v;
	
	/// 一步Euler.
	for (int m = 1; m > 0; --m)
	{
		/// 系数矩阵直接使用 Stokes 矩阵结构.
		SparseMatrix<double> mat_moving;
		mat_moving.reinit(sp_stokes);
		/// (0, 0) 
		for (int i = 0; i < sp_vxvx.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_vxvx[i]) = mat_v_mass.global_entry(i); 
		/// (1, 1) 这两个对角块仅有质量块.
		for (int i = 0; i < sp_vyvy.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_vyvy[i]) = mat_v_mass.global_entry(i);
		/// (0, 2) 这个不是方阵. 在矩阵结构定义的时候已经直接排除了对角元优
		/// 先.
		for (int i = 0; i < sp_pvx.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_pvx[i]) = (1.0 / m) * mat_pvx_divT.global_entry(i);

		/// (1, 2)
		for (int i = 0; i < sp_pvy.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_pvy[i]) = (1.0 / m) * mat_pvy_divT.global_entry(i);

		/// (2, 0)
		for (int i = 0; i < sp_vxp.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_vxp[i]) = (1.0 / m) * mat_vxp_div.global_entry(i);
	
		/// (2, 1) 这四块直接复制散度矩阵. 
		for (int i = 0; i < sp_vyp.n_nonzero_elements(); ++i)
			mat_moving.global_entry(index_vyp[i]) = (1.0 / m) * mat_vyp_div.global_entry(i);

		/// 问题的右端项.
		Vector<double> rhs_loc(n_total_dof);
//		rhs.reinit(n_total_dof);
		FEMSpace<double, DIM>::ElementIterator the_element_v = fem_space_v.beginElement();
		FEMSpace<double, DIM>::ElementIterator end_element_v = fem_space_v.endElement();
		/// 遍历速度单元, 拼装相关系数矩阵和右端项.
		for (the_element_v = fem_space_v.beginElement(); 
		     the_element_v != end_element_v; ++the_element_v) 
		{
			/// 当前单元信息.
			double volume = the_element_v->templateElement().volume();
			/// 积分精度至少为2.
			const QuadratureInfo<DIM>& quad_info = the_element_v->findQuadratureInfo(4);
			std::vector<double> jacobian = the_element_v->local_to_global_jacobian(quad_info.quadraturePoint());
			int n_quadrature_point = quad_info.n_quadraturePoint();
			std::vector<Point<DIM> > q_point = the_element_v->local_to_global(quad_info.quadraturePoint());
 			/// 速度单元信息.
			std::vector<std::vector<double> > basis_value_v = the_element_v->basis_function_value(q_point);
			std::vector<double> vx_value = _u_h.value(q_point, *the_element_v);
			std::vector<double> vy_value = _v_h.value(q_point, *the_element_v);
			std::vector<std::vector<double> > vx_gradient = v_h[0].gradient(q_point, *the_element_v);
			std::vector<std::vector<double> > vy_gradient = v_h[1].gradient(q_point, *the_element_v);
			const std::vector<int>& element_dof_v = the_element_v->dof();
			int n_element_dof_v = the_element_v->n_dof();
			/// 速度积分点上的移动方向, 注意是速度单元的积分点, 在压力单元上的移动方向.
			/// 所以下面一行程序, 仔细算过, 没有问题.
			std::vector<std::vector<double> > move_vector = moveDirection(q_point, index_v2p[the_element_v->index()]);
			for (int l = 0; l < n_quadrature_point; ++l)
			{
				double Jxw = quad_info.weight(l) * jacobian[l] * volume;
				for (int i = 0; i < n_element_dof_v; ++i)
				{
					double rhs_cont = (vx_value[l] + (1.0 / m) * msl * innerProduct(move_vector[l], vx_gradient[l])) * basis_value_v[i][l];
					rhs_cont *= Jxw;
					rhs_loc(element_dof_v[i]) += rhs_cont;

					rhs_cont = (vy_value[l] + (1.0 / m) * msl * innerProduct(move_vector[l], vy_gradient[l])) * basis_value_v[i][l];
					rhs_cont *= Jxw;
					rhs_loc(n_dof_v + element_dof_v[i]) += rhs_cont;
				}
			}
		}

		/// 构建系数矩阵和右端项.
		Vector<double> x(n_total_dof);
//		PoiseuilleVx real_vx (-1.0, 1.0);
//		PoiseuilleVy real_vy;
		// Operator::L2Project(real_vx, v_h[0], Operator::LOCAL_LEAST_SQUARE, 3);
		// Operator::L2Project(real_vy, v_h[1], Operator::LOCAL_LEAST_SQUARE, 3);
		
		// /// 边界处理.
		const std::size_t * rowstart = sp_stokes.get_rowstart_indices();
		const unsigned int * colnum = sp_stokes.get_column_numbers();

		/// 遍历全部维度的速度节点.
		for (unsigned int i = 0; i < n_total_dof_v; ++i)
		{
			/// 边界标志.
			int bm = -1;
			/// 判断一下是 x 方向还是 y 方向. 分别读取标志.
			if (i < n_dof_v)
				bm = fem_space_v.dofInfo(i).boundary_mark;
			else
				bm = fem_space_v.dofInfo(i - n_dof_v).boundary_mark;

			if (bm == 0)
				continue;
			/// 方腔流边界条件.
			if (bm == 1 || bm == 2 || bm == 4 || bm == 5)
				x(i) = 0.0;
			if (bm == 3)
				if (i < n_dof_v)
				{
					/// 不包括顶端的两个端点,称为watertight cavity.
					// x(i) = scale * 1.0;
					Regularized regularize;
					x(i) = scale * regularize.value(fem_space_v.dofInfo(i).interp_point);
				}
				else
					x(i) = 0.0;
			// /// poiseuille flow边界条件.
			// if (bm == 1 || bm == 2 || bm == 4 || bm == 5)
			// 	if (i < n_dof_v)
			// 		x(i) = scale * real_vx.value(fem_space_v.dofInfo(i).interp_point);
			// 	else
			// 		x(i) = scale * real_vy.value(fem_space_v.dofInfo(i - n_dof_v).interp_point);
			/// 右端项这样改, 如果该行和列其余元素均为零, 则在迭代中确
			/// 保该数值解和边界一致.
			if (bm == 1 || bm == 2 || bm == 3 || bm == 4 || bm == 5)
				// if (bm == 1 || bm == 2 || bm == 4 || bm == 5)
			{
				rhs_loc(i) = mat_moving.diag_element(i) * x(i);
				/// 遍历 i 行.
				for (unsigned int j = rowstart[i] + 1; j < rowstart[i + 1]; ++j)
				{
					/// 第 j 个元素消成零(不是第 j 列!). 注意避开了对角元.
					mat_moving.global_entry(j) -= mat_moving.global_entry(j);
					/// 第 j 个元素是第 k 列.
					unsigned int k = colnum[j];
					/// 看看第 k 行的 i 列是否为零元.
					const unsigned int *p = std::find(&colnum[rowstart[k] + 1],
									  &colnum[rowstart[k + 1]],
									  i);
					/// 如果是非零元. 则需要将这一项移动到右端项. 因为第 i 个未知量已知.
					if (p != &colnum[rowstart[k + 1]])
					{
						/// 计算 k 行 i 列的存储位置.
						unsigned int l = p - &colnum[rowstart[0]];
						/// 移动到右端项. 等价于 r(k) = r(k) - x(i) * A(k, i).
						rhs_loc(k) -= mat_moving.global_entry(l) * x(i);
						/// 移完此项自然是零.
						mat_moving.global_entry(l) -= mat_moving.global_entry(l);
					}
				}
			}
		}
		std::cout << "boundary values for updateSolution OK!" << std::endl;
		
		// /// debug 边界条件处理部分,已经测试过, 边界处理正确.
		// RegularMesh<DIM> &mesh_v = irregular_mesh_v->regularMesh();
		// for (int i = 0; i < mesh_v.n_geometry(0); ++i)
		// {
		// 	Point<DIM> &p= mesh_v.point(i);
		// 	if (fabs(1 - p[1]) < eps || fabs(1 - p[0]) < eps || fabs(-1 - p[1]) < eps || fabs(-1 - p[0]) < eps)
		// 	{
		// 		std::cout << "point(" << i << ") = (" << p[0] << "," << p[1] << ");" << std::endl;
		// 		std::cout << "uh(" << i << ") = " << v_h[0](i) << std::endl;
		// 		std::cout << "vh(" << i << ") = " << v_h[1](i) << std::endl;
		// 	}
		// }
		// getchar();
		// /// debug

		clock_t t_cost = clock();
		/// 预处理矩阵.
		/// 不完全LU分解.     
		dealii::SparseILU <double> preconditioner;
		preconditioner.initialize(mat_moving);	
		/// 矩阵求解. 
		dealii::SolverControl solver_control (4000000, l_tol, check);

		SolverMinRes<Vector<double> > minres (solver_control);
		minres.solve (mat_moving, x, rhs_loc, PreconditionIdentity());

		t_cost = clock() - t_cost;	
		std::cout << "time cost: " << (((float)t_cost) / CLOCKS_PER_SEC) << std::endl;
		for (int i = 0; i < n_dof_v; ++i)
		{
			v_h[0](i) = x(i);
			v_h[1](i) = x(i + n_dof_v);
		}
		for (int i = 0; i < n_dof_p; ++i)
			p_h(i) = x(i + 2 * n_dof_v);
	
		/// debug
		std::ofstream mat_deb;
		// rowstart = sp_pvx.get_rowstart_indices();
		// colnum = sp_pvx.get_column_numbers();
		mat_deb.open("mat.m", std::ofstream::out);
		mat_deb.setf(std::ios::fixed);
		mat_deb.precision(20);
	    
		for (int i = 0; i < n_total_dof; ++i)
		{
			for (int j = rowstart[i]; j < rowstart[i + 1]; ++j)
			{
				mat_deb << "A(" << i + 1 << ", " << colnum[j] + 1 << ")=" 
					<< mat_moving.global_entry(j) << ";" << std::endl;
			}
			mat_deb << "x(" << i + 1<< ") = " << x(i) << ";" << std::endl;
			mat_deb << "rhs(" << i + 1 << ") = " << rhs_loc(i) << ";" << std::endl;
		}
		// for(int i = 0; i < n_dof_p; ++i)
		// 	mat_deb << "x(" << i + 1<< ") = " << p_h(i) << ";" << std::endl;
		mat_deb.close();
		std::cout << "mat output" << std::endl;
		Vector<double> res(n_total_dof);
		mat_moving.vmult(res, x);
		res *= -1;
		res += rhs_loc;
		std::cout << "res_l2norm =" << res.l2_norm() << std::endl;
		// double error;
		// error = Functional::L2Error(v_h[0], real_vx, 3);
		// std::cout << "|| u - u_h ||_L2 = " << error << std::endl;

		// error = Functional::H1SemiError(v_h[0], real_vx, 3);
		// std::cout << "|| u - u_h ||_H1 = " << error << std::endl;

        /// debug
		RegularMesh<DIM> &mesh_p = irregular_mesh_p->regularMesh();

		for (int i = 0; i < mesh_p.n_geometry(0); ++i)
		{
			(*mesh_p.h_geometry<0>(i))[0] += moveDirection(i)[0];
			(*mesh_p.h_geometry<0>(i))[1] += moveDirection(i)[1];
		}
		
		/// 输出一下.
		outputTecplotP("NS_Euler");
		getchar();
	}
}; 
示例#11
0
int main(int argc, char * argv[])
{
  typedef MPI::HGeometryForest<DIM,DOW> forest_t;
  typedef MPI::BirdView<forest_t> ir_mesh_t;
  typedef FEMSpace<double,DIM,DOW> fe_space_t;  
  typedef MPI::DOF::GlobalIndex<forest_t, fe_space_t> global_index_t;

  MPI_Init(&argc, &argv);

  forest_t forest(MPI_COMM_WORLD);

  ir_mesh_t ir_mesh;
  MPI::load_mesh(argv[1], forest, ir_mesh); /// 从一个目录中读入网格数据

  int round = 0;
  if (argc >= 3) round = atoi(argv[2]);

  ir_mesh.globalRefine(round);
  ir_mesh.semiregularize();
  ir_mesh.regularize(false);

  TemplateGeometry<DIM> tri;
  tri.readData("triangle.tmp_geo");
  CoordTransform<DIM,DIM> tri_ct;
  tri_ct.readData("triangle.crd_trs");
  TemplateDOF<DIM> tri_td(tri);
  tri_td.readData("triangle.1.tmp_dof");
  BasisFunctionAdmin<double,DIM,DIM> tri_bf(tri_td);
  tri_bf.readData("triangle.1.bas_fun");

  std::vector<TemplateElement<double,DIM,DIM> > tmp_ele(1);
  tmp_ele[0].reinit(tri, tri_td, tri_ct, tri_bf);

  RegularMesh<DIM,DOW>& mesh = ir_mesh.regularMesh();
  fe_space_t fem_space(mesh, tmp_ele);
  u_int n_ele = mesh.n_geometry(DIM);
  fem_space.element().resize(n_ele);
  for (int i = 0;i < n_ele;i ++) {
    fem_space.element(i).reinit(fem_space, i, 0);
  }
  fem_space.buildElement();
  fem_space.buildDof();
  fem_space.buildDofBoundaryMark();

  std::cout << "Building global indices ... " << std::flush;
  global_index_t global_index(forest, fem_space);
  global_index.build();
  std::cout << "OK!" << std::endl;

  Epetra_MpiComm comm(forest.communicator());
  Epetra_Map map(global_index.n_global_dof(), global_index.n_primary_dof(), 0, comm);
  global_index.build_epetra_map(map);

  /// 构造 Epetra 的分布式稀疏矩阵模板
  std::cout << "Build sparsity pattern ... " << std::flush;
  Epetra_FECrsGraph G(Copy, map, 10);
  fe_space_t::ElementIterator
    the_ele = fem_space.beginElement(),
    end_ele = fem_space.endElement();
  for (;the_ele != end_ele;++ the_ele) {
    const std::vector<int>& ele_dof = the_ele->dof();
    u_int n_ele_dof = ele_dof.size();

    /**
     * 建立从局部自由度数组到全局自由度数组的映射表,这是实现分布式并行
     * 状态下的数据结构的关键一步。
     */
    std::vector<int> indices(n_ele_dof);
    for (u_int i = 0;i < n_ele_dof;++ i) {
      indices[i] = global_index(ele_dof[i]);
    }
    G.InsertGlobalIndices(n_ele_dof, &indices[0], n_ele_dof, &indices[0]);
  }
  G.GlobalAssemble();
  std::cout << "OK!" << std::endl;

  /// 准备构造 Epetra 的分布式稀疏矩阵和计算分布式右端项
  std::cout << "Build sparse matrix ... " << std::flush;
  Epetra_FECrsMatrix A(Copy, G);
  Epetra_FEVector b(map);
  the_ele = fem_space.beginElement();
  for (;the_ele != end_ele;++ the_ele) {
    double vol = the_ele->templateElement().volume();
    const QuadratureInfo<DIM>& qi = the_ele->findQuadratureInfo(5);
    std::vector<Point<DIM> > q_pnt = the_ele->local_to_global(qi.quadraturePoint());
    int n_q_pnt = qi.n_quadraturePoint();
    std::vector<double> jac = the_ele->local_to_global_jacobian(qi.quadraturePoint());
    std::vector<std::vector<double> > bas_val = the_ele->basis_function_value(q_pnt);
    std::vector<std::vector<std::vector<double> > > bas_grad = the_ele->basis_function_gradient(q_pnt);

    const std::vector<int>& ele_dof = the_ele->dof();
    u_int n_ele_dof = ele_dof.size();
    FullMatrix<double> ele_mat(n_ele_dof, n_ele_dof);
    Vector<double> ele_rhs(n_ele_dof);
    for (u_int l = 0;l < n_q_pnt;++ l) {
      double JxW = vol*jac[l]*qi.weight(l);
      double f_val = _f_(q_pnt[l]);
      for (u_int i = 0;i < n_ele_dof;++ i) {
        for (u_int j = 0;j < n_ele_dof;++ j) {
          ele_mat(i, j) += JxW*(innerProduct(bas_grad[i][l], bas_grad[j][l]));
        }
        ele_rhs(i) += JxW*f_val*bas_val[i][l];
      }
    }
    /**
     * 此处将单元矩阵和单元载荷先计算好,然后向全局的矩阵和载荷向量上
     * 集中,可以提高效率。
     */

    std::vector<int> indices(n_ele_dof);
    for (u_int i = 0;i < n_ele_dof;++ i) {
      indices[i] = global_index(ele_dof[i]);
    }
    A.SumIntoGlobalValues(n_ele_dof, &indices[0], n_ele_dof, &indices[0], &ele_mat(0,0));
    b.SumIntoGlobalValues(n_ele_dof, &indices[0], &ele_rhs(0));
  }
  A.GlobalAssemble();
  b.GlobalAssemble();
  std::cout << "OK!" << std::endl;

  /// 准备解向量。
  Epetra_FEVector x(map);

  /// 加上狄氏边值条件
  u_int n_bnd_dof = 0; /// 首先清点边界上自由度的个数
  for (u_int i = 0;i < fem_space.n_dof();++ i) {
    if (fem_space.dofBoundaryMark(i) > 0) {
      /// 如果不是在主几何体上就不做
      if (! global_index.is_dof_on_primary_geometry(i)) continue;

      n_bnd_dof += 1;
    }
  }

  /// 准备空间存储边界上全局标号、自变量和右端项
  std::vector<int> bnd_idx(n_bnd_dof);
  std::vector<double> x_entry(n_bnd_dof), rhs_entry(n_bnd_dof);

  /// 对自由度做循环
  for (u_int i = 0, j = 0;i < fem_space.n_dof();++ i) {
    if (fem_space.dofBoundaryMark(i) > 0) { /// 边界上的自由度?
      /// 如果不是在主几何体上就不做
      if (! global_index.is_dof_on_primary_geometry(i)) continue;

      const int& idx = global_index(i); /// 行的全局标号
      bnd_idx[j] = idx; 

      /// 修改矩阵
      int lrid = A.LRID(idx);
      int row_nnz, *row_idx;
      double *row_entry, row_diag;
      A.ExtractMyRowView(lrid, row_nnz, row_entry, row_idx); /// 取出矩阵的行
      for (int k = 0;k < row_nnz;++ k) { /// 对矩阵的行进行修改
        if (A.LCID(row_idx[k]) != lrid) {   /// 如果不是对角元
          row_entry[k] = 0.0;      /// 则将矩阵元素清零
        } else {                   /// 而对角元保持不变
          row_diag = row_entry[k]; /// 并记录下对角元
        }
      }

      /// 计算并记下自变量和右端项,假设自由度值为插值量
      double u_b_val = _u_b_(fem_space.dofInfo(i).interp_point);
      x_entry[j] = u_b_val;
      rhs_entry[j] = row_diag*u_b_val;

      j += 1;
    }
  } 
  std::cout << "# DOF on the boundary: " << n_bnd_dof << std::endl;

  /// 修改解变量和右端项
  x.ReplaceGlobalValues(n_bnd_dof, &bnd_idx[0], &x_entry[0]);
  b.ReplaceGlobalValues(n_bnd_dof, &bnd_idx[0], &rhs_entry[0]);

  /// 调用 AztecOO 的求解器。
  std::cout << "Solving the linear system ..." << std::flush;
  Epetra_LinearProblem problem(&A, &x, &b);
  AztecOO solver(problem);
  ML_Epetra::MultiLevelPreconditioner precond(A, true);
  solver.SetPrecOperator(&precond);
  solver.SetAztecOption(AZ_solver, AZ_gmres);
  solver.SetAztecOption(AZ_output, 100);
  solver.Iterate(5000, 1.0e-12);
  std::cout << "OK!" << std::endl;

  Epetra_Map fe_map(-1, global_index.n_local_dof(), &global_index(0), 0, comm);
  FEMFunction<double,DIM> u_h(fem_space);
  Epetra_Import importer(fe_map, map);
  Epetra_Vector X(View, fe_map, &u_h(0));
  X.Import(x, importer, Add);

  char filename[1024];
  sprintf(filename, "u_h%d.dx", forest.rank());
  u_h.writeOpenDXData(filename);

  MPI_Finalize();

  return 0;
}
示例#12
0
float distancePointPlane (const vector_t point, const plane_t plane)
{
  return innerProduct(point, plane.normal) -
         innerProduct(plane.point, plane.normal);
}
示例#13
0
文件: RBEC.cpp 项目: FengYueZJU/Study
void RBEC::stepForward()
{
    int i, j, k, l;
    int n_dof = fem_space.n_dof();
    int n_total_dof = 2 * n_dof;

    mat_RBEC.reinit(sp_RBEC);
    mat_rere.reinit(sp_rere);
    mat_reim.reinit(sp_reim);
    mat_imre.reinit(sp_imre);
    mat_imim.reinit(sp_imim);

    Vector<double> phi(n_total_dof);
    FEMFunction <double, DIM> phi_star(fem_space);
    Vector<double> rhs(n_total_dof);
    Potential V(gamma_x, gamma_y);

/// 准备一个遍历全部单元的迭代器.
    FEMSpace<double, DIM>::ElementIterator the_element = fem_space.beginElement();
    FEMSpace<double, DIM>::ElementIterator end_element = fem_space.endElement();

/// 循环遍历全部单元, 只是为了统计每一行的非零元个数.
    for (; the_element != end_element; ++the_element)
    {
/// 当前单元信息.
	double volume = the_element->templateElement().volume();
	const QuadratureInfo<DIM>& quad_info = the_element->findQuadratureInfo(6);
	std::vector<double> jacobian = the_element->local_to_global_jacobian(quad_info.quadraturePoint());
	int n_quadrature_point = quad_info.n_quadraturePoint();
	std::vector<AFEPack::Point<DIM> > q_point = the_element->local_to_global(quad_info.quadraturePoint());
/// 单元信息.
	std::vector<std::vector<std::vector<double> > > basis_gradient = the_element->basis_function_gradient(q_point);
	std::vector<std::vector<double> >  basis_value = the_element->basis_function_value(q_point);
	std::vector<double> phi_re_value = phi_re.value(q_point, *the_element);
	std::vector<double> phi_im_value = phi_im.value(q_point, *the_element);
	const std::vector<int>& element_dof = the_element->dof();
	int n_element_dof = the_element->n_dof();
/// 实际拼装.
	for (l = 0; l < n_quadrature_point; ++l)
	{
	    double Jxw = quad_info.weight(l) * jacobian[l] * volume;
	    for (j = 0; j < n_element_dof; ++j)
	    {
		for (k = 0; k < n_element_dof; ++k)
		{

		    double cont = Jxw * ((1 / dt) * basis_value[j][l] * basis_value[k][l]
					 + 0.5 * innerProduct(basis_gradient[j][l], basis_gradient[k][l])
					 + V.value(q_point[l]) * basis_value[j][l] * basis_value[k][l]
					 + beta * (phi_re_value[l] * phi_re_value[l]  + phi_im_value[l] * phi_im_value[l]) * basis_value[j][l] * basis_value[k][l]);

		    mat_RBEC.add(element_dof[j], element_dof[k], cont);
		    mat_RBEC.add(element_dof[j] + n_dof, element_dof[k] + n_dof, cont);
		}
		rhs(element_dof[j]) += Jxw * phi_re_value[l] * basis_value[j][l] / dt;
		rhs(element_dof[j] + n_dof) += Jxw * phi_im_value[l] * basis_value[j][l] / dt;
	    }
	}
    }

    FEMFunction<double, DIM> _phi_re(phi_re);
    FEMFunction<double, DIM> _phi_im(phi_im);

    boundaryValue(phi, rhs, mat_RBEC);

//    AMGSolver solver(mat_RBEC);
//    solver.solve(phi, rhs);

    dealii::SolverControl solver_control(4000, 1e-15);
    SolverGMRES<Vector<double> >::AdditionalData para(500, false, true);
    SolverGMRES<Vector<double> > gmres(solver_control, para);
    gmres.solve(mat_RBEC, phi, rhs, PreconditionIdentity());

    for (int i = 0; i < n_dof; ++i)
    {
         phi_re(i) = phi(i);
         phi_im(i) = phi(n_dof + i);
    }
	
    for (int i = 0; i < n_dof; ++i)
        phi_star(i) = sqrt(phi_re(i) * phi_re(i) + phi_im(i) * phi_im(i));

    double L2Phi = Functional::L2Norm(phi_re, 6);

    std::cout << "L2 norm = " << L2Phi << std::endl;
       
    for (int i = 0; i < n_dof; ++i)
    {
	phi_re(i) /= L2Phi;
	phi_im(i) /= L2Phi;
    }

    double e = energy(phi_re, phi_im, 6);
    std::cout << "Energy = " << e << std::endl;

    
    t += dt;
};
vector<vector<double>> computeGramSchmidt(double v1[3], double v2[3],
double v3[3]) {

        double u1[3];
        u1[0] = v1[0];
        u1[1] = v1[1];
        u1[2] = v1[2];

        double projection12 = innerProduct(u1, v2)/innerProduct(u1, u1);
        double projection13 = innerProduct(u1, v3)/innerProduct(u1, u1);

        double u2[3];
        u2[0] = v2[0]-projection12*u1[0];
        u2[1] = v2[1]-projection12*u1[1];
        u2[2] = v2[2]-projection12*u1[2];

        double projection23 = innerProduct(u2, v3)/innerProduct(u2, u2);

        double u3[3];
        u3[0] = v3[0]-projection13*u1[0]-projection23*u2[0];
        u3[1] = v3[1]-projection13*u1[1]-projection23*u2[1];
        u3[2] = v3[2]-projection13*u1[2]-projection23*u2[2];

        vector<double> e1;
        e1.push_back(u1[0]/sqrt(innerProduct(u1,u1)));
        e1.push_back(u1[1]/sqrt(innerProduct(u1,u1)));
        e1.push_back(u1[2]/sqrt(innerProduct(u1,u1)));

        vector<double> e2;
        e2.push_back(u2[0]/sqrt(innerProduct(u2,u2)));
        e2.push_back(u2[1]/sqrt(innerProduct(u2,u2)));
        e2.push_back(u2[2]/sqrt(innerProduct(u2,u2)));

        vector<double> e3;
        e3.push_back(u3[0]/sqrt(innerProduct(u3,u3)));
        e3.push_back(u3[1]/sqrt(innerProduct(u3,u3)));
        e3.push_back(u3[2]/sqrt(innerProduct(u3,u3)));

        vector<vector<double>> orthonormalBasis;
        orthonormalBasis.push_back(e1);
        orthonormalBasis.push_back(e2);
        orthonormalBasis.push_back(e3);

        return orthonormalBasis;

}
示例#15
0
void findPoleAntiPole(int vsize) {
	tVertex site;
	double *pole_vector;
	double avg_normal[3] = { 0, };
	facetT *neighbor, **neighborp;
	tVertex pole_voronoi_vertex = NULL;
	tVertex antipole_voronoi_vertex = NULL;
	vertexT *temp_voronoi_vertexT = NULL;
	tVertex temp_voronoi_vertex;
	tList site_voronoi_vertices;
	double temp_dist = 0;
	double max_dist = 0;
	int neighbor_size = 0;
	int i;
	tVertex temp_vertex;
	tVertex temp_vertices;
	int is_on_convexhull = 0;

	temp_vertex = vertices;
	temp_vertices = vertices;
	site = vertices;
	// for all vertices
	do {
		site_voronoi_vertices = site->vvlist;
		if (!site_voronoi_vertices)	{
			temp_vertex = temp_vertex->next;
			site = site->next;
			continue;
		}
		temp_voronoi_vertexT = (vertexT*)site_voronoi_vertices->p;

		if (!temp_voronoi_vertexT) {	// lies on the CH: compute the average of the outer nomals of the adjacents.
			pole_vector = (double *)calloc(3, sizeof(double));
			neighbor_size = 0;
			FOREACHneighbor_(temp_voronoi_vertexT) {
				neighbor_size++;
				avg_normal[X] += neighbor->normal[X];
				avg_normal[Y] += neighbor->normal[Y];
				avg_normal[Z] += neighbor->normal[Z];
			}

			avg_normal[X] /= neighbor_size;
			avg_normal[Y] /= neighbor_size;
			avg_normal[Z] /= neighbor_size;
			for (i = 0; i < 3; i++) {
				pole_vector[i] = avg_normal[i];
			}
			is_on_convexhull = TRUE;
		}
		else {
			site_voronoi_vertices = site->vvlist;
			do {			// Find the farthest Voronoi vertex from s.
				temp_voronoi_vertex = (tVertex)(site_voronoi_vertices->p);
				temp_dist = pointDist(site, temp_voronoi_vertex);
				if (temp_dist > max_dist) {
					pole_voronoi_vertex = temp_voronoi_vertex;
					max_dist = temp_dist;
				}
			} while (site_voronoi_vertices != site->vvlist);

			if (pole_voronoi_vertex){
				if (max_dist > MAX_DIST) {
					pole_voronoi_vertex = NULL;
				}
				else {
					pole_voronoi_vertex->ispole = TRUE;
					pole_voronoi_vertex->vnum = vsize++;

					ADD(vertices, pole_voronoi_vertex);
					pole_vector = (double *)calloc(3, sizeof(double));
					for (i = 0; i < 3; i++) {
						pole_vector[i] = pole_voronoi_vertex->v[i];
					}
				}
			}

		}

		max_dist = 0;
		temp_dist = 0;

		// find a antipole
		site_voronoi_vertices = site->vvlist;
		
		if (pole_voronoi_vertex != NULL) {
			do {
				temp_voronoi_vertex = (tVertex)(site_voronoi_vertices->p);
				if (temp_voronoi_vertex->ispole) {
					continue;
				}
				temp_dist = innerProduct(site, pole_voronoi_vertex, temp_voronoi_vertex);
				if (temp_dist > max_dist) {
					antipole_voronoi_vertex = temp_voronoi_vertex;
					max_dist = temp_dist;
				}
				site_voronoi_vertices = site_voronoi_vertices->next;
			} while (site_voronoi_vertices != site->vvlist);
		}
		else if (is_on_convexhull) {	// the site is on CH
			do {
				temp_voronoi_vertex = (tVertex)(site_voronoi_vertices->p);
				tVertex temp_vertex = MakeTempVertex(pole_vector);
				temp_dist = innerProduct(site, temp_vertex, temp_voronoi_vertex);
				if (temp_dist > max_dist) {
					antipole_voronoi_vertex = temp_voronoi_vertex;
					max_dist = temp_dist;
				}
				site_voronoi_vertices = site_voronoi_vertices->next;
			} while (site_voronoi_vertices != site->vvlist);
		}
		if (antipole_voronoi_vertex){
			if (max_dist > MAX_DIST) {
				antipole_voronoi_vertex = NULL;
			}
			else {
				antipole_voronoi_vertex->ispole = TRUE;
				antipole_voronoi_vertex->vnum = vsize++;
				ADD(vertices, antipole_voronoi_vertex);
			}
		}
		max_dist = 0;
		avg_normal[0] = 0;
		avg_normal[1] = 0;
		avg_normal[2] = 0;
		pole_vector = NULL;
		pole_voronoi_vertex = NULL;
		antipole_voronoi_vertex = NULL;
		is_on_convexhull = FALSE;
		temp_vertex = temp_vertex->next;
		site = site->next;
	} while (temp_vertex != temp_vertices);
示例#16
0
bool DGKTSD::cr(const DKTS& ai, const DKTS& xi)
 {
    bool value = true;

    DKTVector& w    = attr_w();
    DKTVector& r    = attr_r();
    DKTVector& x    = attr_direction();
    DKTVector& a    = attr_ap();
    DKTVector& aOld = attr_apo();
    DKTVector& b    = attr_b();
    DKTVector& bOld = attr_bo();
    DKTVector& p    = attr_p();
    DKTVector& pOld = attr_po();
    DKTVector& grad = attr_gradientV();

    //Init
    // r=grad - H*d
    evaluateHf(ai, xi, attr_direction, attr_r);
    r *= -1.0;
    r += grad;    

/*
    // po = 0
    attr_po.setAllEntrysNull();
*/

    // p=W^-1*r
    evaluateAinv(attr_r, attr_p);

    // a = H*p
    evaluateHf(ai, xi, attr_p, attr_ap);

    // b = W^-1*ap
    evaluateAinv(attr_ap, attr_b);
          
    // w = A*b
    evaluateHf(ai, xi, attr_b, attr_w);

    LongReal eps    = epsilonCR();
    LongReal error  = innerProduct(a, b);
    LongReal errorO = error;
    LongReal errorE = l2(r);
    
    LongReal lambda = 1.0, a0 = 1.0, a1 = 1.0;

    lambda = innerProduct(r, b)/error;
    a0     = innerProduct(w, b)/error;

    x.update( lambda, p);
    r.update(-lambda, a);

    bOld = p;  
    p *= -a0;
    p.update(1.0, b);
    pOld = bOld;

    bOld = a;
    a *= -a0;
    a.update(1.0, w);
    aOld = bOld;

    bOld = b;
    evaluateAinv(attr_ap, attr_b);
    evaluateHf(ai, xi, attr_b, attr_w);

    errorO = error;
    error  = innerProduct(a, b);

    const LongInt     maxSteps = maxStepsCR();
    LongInt numberOfIterations = 2;

    while(eps<errorE && numberOfIterations <= maxSteps)
     {
        lambda = innerProduct(r, b)/error;
        a0     = innerProduct(w, b)/error;
        a1     = innerProduct(w, bOld)/errorO;

        x.update( lambda, p);
        r.update(-lambda, a);

        bOld = p;  
        p *= -a0;
        p.update(1.0, b);
        p.update(-a1, pOld);
        pOld = bOld;


        bOld = a;
        a *= -a0;
        a.update(1.0, w);
        a.update(-a1, aOld);
        aOld = bOld;

        bOld = b;
        evaluateAinv(attr_ap, attr_b);
        evaluateHf(ai, xi, attr_b, attr_w);

        errorO = error;
        error  = innerProduct(a, b);
        errorE = l2(r);
        
        numberOfIterations++;
     }    

    cout << "l2(p) = " << l2(p) << " " << l2(r);
    
   return value;
 }
示例#17
0
void ISOP2P1::buildMatrix()
{
	/// 计算一下各空间自由度和总自由度.
	int n_dof_v = fem_space_v.n_dof();
	int n_dof_p = fem_space_p.n_dof();
	int n_total_dof =  2 * n_dof_v + n_dof_p;
	if (n_total_dof != sp_stokes.n_rows())
	{
		std::cerr << "ERROR: the demision of matrix is not correct!" << std::endl;
		exit(-1);
	}
	else
		std::cout << "dof no. of v: " << n_dof_v << ", "
		<< "dof no. of p: " << n_dof_p << ", "
		<< "total dof no.: " << n_total_dof << std::endl;

	/// 构建系数矩阵和右端项.
	mat_v_stiff.reinit(sp_vxvx);
	mat_v_mass.reinit(sp_vxvx);
	mat_pvx_divT.reinit(sp_pvx);
	mat_pvy_divT.reinit(sp_pvy);

	FEMSpace<double, DIM>::ElementIterator the_element_v = fem_space_v.beginElement();
	FEMSpace<double, DIM>::ElementIterator end_element_v = fem_space_v.endElement();

	/// 遍历速度单元, 拼装相关系数矩阵和右端项.
	for (the_element_v = fem_space_v.beginElement();
			the_element_v != end_element_v; ++the_element_v)
	{
		/// 当前单元信息.
		double volume = the_element_v->templateElement().volume();
		/// 积分精度, u 和 p 都是 1 次, 梯度和散度 u 都是常数. 因此矩阵拼
		/// 装时积分精度不用超过 1 次. (验证一下!)
		const QuadratureInfo<DIM>& quad_info = the_element_v->findQuadratureInfo(3);
		std::vector<double> jacobian = the_element_v->local_to_global_jacobian(quad_info.quadraturePoint());
		int n_quadrature_point = quad_info.n_quadraturePoint();
		std::vector<Point<DIM> > q_point = the_element_v->local_to_global(quad_info.quadraturePoint());
		/// 速度单元信息.
		std::vector<std::vector<std::vector<double> > > basis_gradient_v = the_element_v->basis_function_gradient(q_point);
		std::vector<std::vector<double> >  basis_value_v = the_element_v->basis_function_value(q_point);
		const std::vector<int>& element_dof_v = the_element_v->dof();
		int n_element_dof_v = the_element_v->n_dof();
		// std::cout << the_element_v->index() << std::endl;
		/// 压力单元信息.
		Element<double, DIM> &p_element = fem_space_p.element(index_ele_v2p[the_element_v->index()]);

		const std::vector<int>& element_dof_p = p_element.dof();
		std::vector<std::vector<double> >  basis_value_p = p_element.basis_function_value(q_point);
		int n_element_dof_p = p_element.n_dof();
		/// 实际拼装.
		for (int l = 0; l < n_quadrature_point; ++l)
		{
			double Jxw = quad_info.weight(l) * jacobian[l] * volume;
			for (int i = 0; i < n_element_dof_v; ++i)
			{
				for (int j = 0; j < n_element_dof_v; ++j)
				{
					double cont = Jxw * innerProduct(basis_gradient_v[i][l], basis_gradient_v[j][l]);
					/// V Stiff
					mat_v_stiff.add(element_dof_v[i], element_dof_v[j], cont);
					cont = Jxw * basis_value_v[i][l] * basis_value_v[j][l];
					/// V Mass
					mat_v_mass.add(element_dof_v[i], element_dof_v[j], cont);
				}
				for (int j = 0; j < n_element_dof_p; ++j)
				{
					/// DivT x
					double cont = -Jxw * (basis_gradient_v[i][l][0] * basis_value_p[j][l]);
					mat_pvx_divT.add(element_dof_v[i], element_dof_p[j], cont);

					/// DivT y
					cont = -Jxw * (basis_gradient_v[i][l][1] * basis_value_p[j][l]);
					mat_pvy_divT.add(element_dof_v[i], element_dof_p[j], cont);
				}
			}
		}
	}

	/// 构建系数矩阵和右端项.
	mat_p_mass.reinit(sp_mass_p);
	mat_p_stiff.reinit(sp_mass_p);
	mat_vxp_div.reinit(sp_vxp);
	mat_vyp_div.reinit(sp_vyp);
	FEMSpace<double, DIM>::ElementIterator the_element_p = fem_space_p.beginElement();
	FEMSpace<double, DIM>::ElementIterator end_element_p = fem_space_p.endElement();

	/// 遍历压力单元. 拼装矩阵和右端项.
	for (the_element_p = fem_space_p.beginElement();
	     the_element_p != end_element_p; ++the_element_p)
	{
		/// 当前单元信息.
		double volume_p = the_element_p->templateElement().volume();
		const QuadratureInfo<DIM>& quad_info_p = the_element_p->findQuadratureInfo(3);
		std::vector<double> jacobian_p = the_element_p->local_to_global_jacobian(quad_info_p.quadraturePoint());
		int n_quadrature_point = quad_info_p.n_quadraturePoint();
		std::vector<Point<DIM> > q_point_p = the_element_p->local_to_global(quad_info_p.quadraturePoint());
		/// 压力单元信息.
		std::vector<std::vector<double> >  basis_value_p = the_element_p->basis_function_value(q_point_p);
		std::vector<std::vector<std::vector<double> > >  basis_gradient_p = the_element_p->basis_function_gradient(q_point_p);
		const std::vector<int>& element_dof_p = the_element_p->dof();
		int n_element_dof_p = the_element_p->n_dof();
		for (int i = 0; i < n_element_dof_p; ++i)
		{
			for (int l = 0; l < n_quadrature_point; ++l)
			{
				for (int j = 0; j < n_element_dof_p; ++j)
				{
					double Jxw = quad_info_p.weight(l) * jacobian_p[l] * volume_p;
					double cont = Jxw * basis_value_p[i][l] * basis_value_p[j][l];
					mat_p_mass.add(element_dof_p[i], element_dof_p[j], cont);
					/// mat_p_stiff.
					cont = Jxw * innerProduct(basis_gradient_p[i][l], basis_gradient_p[j][l]);
					mat_p_stiff.add(element_dof_p[i], element_dof_p[j], cont);
				}
			}
			int idx_p = the_element_p->index();
			int n_chi = index_ele_p2v[idx_p].size();
			for (int k = 0; k < n_chi; k++)
			{
				/// 速度单元信息.
				Element<double, DIM> &v_element = fem_space_v.element(index_ele_p2v[idx_p][k]);

				/// 几何信息.
				double volume = v_element.templateElement().volume();
				const QuadratureInfo<DIM>& quad_info = v_element.findQuadratureInfo(3);
				std::vector<double> jacobian = v_element.local_to_global_jacobian(quad_info.quadraturePoint());
				int n_quadrature_point = quad_info.n_quadraturePoint();
				std::vector<Point<DIM> > q_point = v_element.local_to_global(quad_info.quadraturePoint());

				const std::vector<int>& element_dof_v = v_element.dof();
				std::vector<std::vector<std::vector<double> > > basis_gradient_v = v_element.basis_function_gradient(q_point);
				int n_element_dof_v = v_element.n_dof();

				/// 压力单元信息.
				std::vector<std::vector<std::vector<double> > > basis_gradient_p = the_element_p->basis_function_gradient(q_point);
				std::vector<std::vector<double> >  basis_value_p = the_element_p->basis_function_value(q_point);
				/// 具体拼装.
				for (int l = 0; l < n_quadrature_point; ++l)
				{
					double Jxw = quad_info.weight(l) * jacobian[l] * volume;

					for (int j = 0; j < n_element_dof_v; ++j)
					{
						/// Div x
						double cont = -Jxw * basis_value_p[i][l] * basis_gradient_v[j][l][0];
						mat_vxp_div.add(element_dof_p[i], element_dof_v[j], cont);
						/// Div y
						cont = -Jxw * basis_value_p[i][l] * basis_gradient_v[j][l][1];
						mat_vyp_div.add(element_dof_p[i], element_dof_v[j], cont);
					}
				}
			}
		}
	}

	// 输出测试矩阵, 只限小规模矩阵.
//	outputMat("Axx",mat_v_stiff);
//	outputMat("Mxx",mat_v_mass);
//	outputMat("Apx",mat_pvx_divT);
//	outputMat("Apy",mat_pvy_divT);
//	outputMat("Axp",mat_vxp_div);
//	outputMat("Ayp",mat_vyp_div);

	std::cout << "Basic matrixes builded." << std::endl;
};
示例#18
0
	double Vector::sumSquares () const {
		return innerProduct( *this );
	}
示例#19
0
void ISOP2P1::solveNS(int method)
{
	int n_dof_v = fem_space_v.n_dof();
	int n_dof_p = fem_space_p.n_dof();
	int n_total_dof = n_dof_v * 2 + n_dof_p;

	/// 开始迭代.
	double error_N = 1.0;
	int iteration_times = 0;
	while (error_N > n_tol)
	{
		/// Newton 迭代或 Picard 迭代.
		/// 先更新和速度场有关的矩阵块.
		updateNonlinearMatrix();
		/// 构建迭代矩阵.
		if (method == 1)
			buildNewtonSys4NS();
		else if (method == 2)
			buildPicardSys4NS();
		else if (method == 3)
			if (iteration_times < 2)
				buildPicardSys4NS();
			else
				buildNewtonSys4NS();
		else
		{
			std::cout << "Newton: 1, Picard: 2, Hybrid: 3." << std::endl;
			exit(1);
		}

		/// 建立右端项.
		rhs.reinit(n_total_dof);

		FEMSpace<double, DIM>::ElementIterator the_element_v = fem_space_v.beginElement();
		FEMSpace<double, DIM>::ElementIterator end_element_v = fem_space_v.endElement();
		FEMSpace<double, DIM>::ElementIterator the_element_p = fem_space_p.beginElement();
		FEMSpace<double, DIM>::ElementIterator end_element_p = fem_space_p.endElement();
		/// 遍历速度单元, 拼装相关系数矩阵和右端项.
		for (the_element_v = fem_space_v.beginElement();
		     the_element_v != end_element_v; ++the_element_v)
		{
			/// 当前单元信息.
			double volume = the_element_v->templateElement().volume();
			/// 积分精度, u 和 p 都是 1 次, 梯度和散度 u 都是常数. 因此矩阵拼
			/// 装时积分精度不用超过 1 次. (验证一下!)
			const QuadratureInfo<DIM>& quad_info = the_element_v->findQuadratureInfo(4);
			std::vector<double> jacobian
				= the_element_v->local_to_global_jacobian(quad_info.quadraturePoint());
			int n_quadrature_point = quad_info.n_quadraturePoint();
			std::vector<Point<DIM> > q_point
				= the_element_v->local_to_global(quad_info.quadraturePoint());
			/// 速度单元信息.
			std::vector<std::vector<std::vector<double> > > basis_gradient_v
				= the_element_v->basis_function_gradient(q_point);
			std::vector<std::vector<double> >  basis_value_v
				= the_element_v->basis_function_value(q_point);
			const std::vector<int>& element_dof_v = the_element_v->dof();
			std::vector<double> fx_value = source_v[0].value(q_point, *the_element_v);
			std::vector<double> fy_value = source_v[1].value(q_point, *the_element_v);
			int n_element_dof_v = the_element_v->n_dof();
			std::vector<double> vx_value = v_h[0].value(q_point, *the_element_v);
			std::vector<double> vy_value = v_h[1].value(q_point, *the_element_v);
			std::vector<std::vector<double> > vx_gradient = v_h[0].gradient(q_point, *the_element_v);
			std::vector<std::vector<double> > vy_gradient = v_h[1].gradient(q_point, *the_element_v);
			/// 压力单元信息.
			Element<double, DIM> &p_element = fem_space_p.element(index_ele_v2p[the_element_v->index()]);
			const std::vector<int>& element_dof_p = p_element.dof();
			std::vector<std::vector<std::vector<double> > > basis_gradient_p
				= p_element.basis_function_gradient(q_point);
			std::vector<std::vector<double> >  basis_value_p = p_element.basis_function_value(q_point);
			std::vector<double> p_value = p_h.value(q_point, p_element);
			int n_element_dof_p = p_element.n_dof();
			/// 实际拼装.
			for (int l = 0; l < n_quadrature_point; ++l)
			{
				double Jxw = quad_info.weight(l) * jacobian[l] * volume;
				for (int i = 0; i < n_element_dof_v; ++i)
				{
					double rhs_cont = fx_value[l] * basis_value_v[i][l];
					rhs_cont -= (vx_value[l] * vx_gradient[l][0] +
						     vy_value[l] * vx_gradient[l][1]) * basis_value_v[i][l];
					rhs_cont -= viscosity * innerProduct(basis_gradient_v[i][l], vx_gradient[l]);
					rhs_cont += p_value[l] * basis_gradient_v[i][l][0];
					rhs_cont *= Jxw;
					rhs(element_dof_v[i]) += rhs_cont;

					rhs_cont = fy_value[l] * basis_value_v[i][l];
					rhs_cont -= (vx_value[l] * vy_gradient[l][0] +
						     vy_value[l] * vy_gradient[l][1]) * basis_value_v[i][l];
					rhs_cont -= viscosity * innerProduct(basis_gradient_v[i][l], vy_gradient[l]);
					rhs_cont += p_value[l] * basis_gradient_v[i][l][1];
					rhs_cont *= Jxw;
					rhs(n_dof_v + element_dof_v[i]) += rhs_cont;
				}
			}
		}

		/// 遍历压力单元. 拼装矩阵和右端项.
		for (the_element_p = fem_space_p.beginElement();
		     the_element_p != end_element_p; ++the_element_p)
		{
			const std::vector<int>& element_dof_p = the_element_p->dof();
			int n_element_dof_p = the_element_p->n_dof();
			for (int i = 0; i < n_element_dof_p; ++i)
			{
				int idx_p = the_element_p->index();
				int n_chi = index_ele_p2v[idx_p].size();
				for (int k = 0; k < n_chi; k++)
				{
					/// 速度单元信息.
					Element<double, DIM> &v_element = fem_space_v.element(index_ele_p2v[idx_p][k]);
					/// 几何信息.
					double volume = v_element.templateElement().volume();
					const QuadratureInfo<DIM>& quad_info = v_element.findQuadratureInfo(4);
					std::vector<double> jacobian
						= v_element.local_to_global_jacobian(quad_info.quadraturePoint());
					int n_quadrature_point = quad_info.n_quadraturePoint();
					std::vector<Point<DIM> > q_point
						= v_element.local_to_global(quad_info.quadraturePoint());
					std::vector<std::vector<double> > vx_gradient
						= v_h[0].gradient(q_point, v_element);
					std::vector<std::vector<double> > vy_gradient
						= v_h[1].gradient(q_point, v_element);
					std::vector<double> vx_value = v_h[0].value(q_point, v_element);
					std::vector<double> vy_value = v_h[1].value(q_point, v_element);
					/// 压力单元信息.
					std::vector<std::vector<double> >  basis_value_p
						= the_element_p->basis_function_value(q_point);
					/// 具体拼装.
					for (int l = 0; l < n_quadrature_point; ++l)
					{
						double Jxw = quad_info.weight(l) * jacobian[l] * volume;

						/// 右端项还是零. 源项和 Neumann 条件.
						double rhs_cont = Jxw * basis_value_p[i][l]
							* (vx_gradient[l][0] + vy_gradient[l][1]);
						rhs(2 * n_dof_v + element_dof_p[i]) += rhs_cont;
					}
				}
			}

		}

		/// 初始化未知量.
		Vector<double> x(n_total_dof);

		/// 边界条件处理.
		boundaryValueNS(x);

		std::cout << "nonlinear res:" << std::endl;
		double revx = 0.0;
		for (int i = 0; i < n_dof_v; ++i)
			revx += rhs(i) * rhs(i);
		std::cout << "vx re: " << sqrt(revx) << std::endl;
		double revy = 0.0;
		for (int i = 0; i < n_dof_v; ++i)
			revy += rhs(i + n_dof_v) * rhs(i + n_dof_v);
		std::cout << "vy re: " << sqrt(revy) << std::endl;
		double rep = 0.0;
		for (int i = 0; i < n_dof_p; ++i)
			rep += rhs(i + 2 * n_dof_v) * rhs(i + 2 * n_dof_v);
		std::cout << "p re: " << sqrt(rep) << std::endl;

		double re = revx + revy +rep;
		std::cout << "total re: " << sqrt(re) << std::endl;
		std::cout << "pause ..." << std::endl;
		getchar();
		if (sqrt(re) < n_tol)
		{
			std::cout << "Covergence with residual: " << sqrt(re)
		    		  << " in step " << iteration_times << std::endl;
			break;
		}

		std::cout << "Building precondition matrix ..." << std::endl;

		/// 矩阵求解.
		SparseMatrix<double> mat_Axx(sp_vxvx);
		SparseMatrix<double> mat_Ayy(sp_vyvy);
		SparseMatrix<double> mat_Wxy(sp_vyvx);
		SparseMatrix<double> mat_Wyx(sp_vxvy);
		SparseMatrix<double> mat_BTx(sp_pvx);
		SparseMatrix<double> mat_BTy(sp_pvy);

		for (int i = 0; i < sp_vxvx.n_nonzero_elements(); ++i)
			mat_Axx.global_entry(i) = matrix.global_entry(index_vxvx[i]);
		for (int i = 0; i < sp_vyvy.n_nonzero_elements(); ++i)
			mat_Ayy.global_entry(i) = matrix.global_entry(index_vyvy[i]);
		for (int i = 0; i < sp_vyvx.n_nonzero_elements(); ++i)
			mat_Wxy.global_entry(i) = matrix.global_entry(index_vyvx[i]);
		for (int i = 0; i < sp_vxvy.n_nonzero_elements(); ++i)
			mat_Wyx.global_entry(i) = matrix.global_entry(index_vxvy[i]);
		for (int i = 0; i < sp_pvx.n_nonzero_elements(); ++i)
			mat_BTx.global_entry(i) = matrix.global_entry(index_pvx[i]);
		for (int i = 0; i < sp_pvy.n_nonzero_elements(); ++i)
			mat_BTy.global_entry(i) = matrix.global_entry(index_pvy[i]);
		std::cout << "Precondition matrix builded!" << std::endl;

		/// 矩阵求解.
		dealii::SolverControl solver_control (4000000, l_tol);

		SolverGMRES<Vector<double> >::AdditionalData para(2000, false, true);
		SolverGMRES<Vector<double> > gmres (solver_control, para);
		std::cout << "Begin to solve linear system ..." << std::endl;
		//	gmres.solve (matrix, x, rhs, navierstokes_preconditioner);
		gmres.solve (matrix, x, rhs, PreconditionIdentity());

		/// 调试块: 直接观测真实残量.
		//	Vector<double> tmp(n_total_dof);
		//	matrix.vmult(tmp, x);
		//	tmp -= rhs;
		//	std::cout << "linear residual: " << tmp.l2_norm() << std::endl;
		//	getchar();

		FEMFunction<double, DIM> res_vx(fem_space_v);
		FEMFunction<double, DIM> res_vy(fem_space_v);
		FEMFunction<double, DIM> res_p(fem_space_p);

		/// 更新数值解.
		for (int i = 0; i < n_dof_v; ++i)
		{
			v_h[0](i) += x(i);
			res_vx(i) = x(i);
			v_h[1](i) += x(i + n_dof_v);
			res_vy(i) = x(i+ n_dof_v);
		}
		for (int i = 0; i < n_dof_p; ++i)
		{
			p_h(i) += x(i + 2 * n_dof_v);
			res_p(i) = x(i + 2 * n_dof_v);
		}

		double r_vx = Functional::L2Norm(res_vx, 1);
		double r_vy = Functional::L2Norm(res_vy, 1);
		double r_p = Functional::L2Norm(res_p, 1);
		/// 这个其实是更新...
		error_N = r_vx + r_vy + r_p;

		std::cout.setf(std::ios::fixed);
		std::cout.precision(20);
		std::cout << "updated vx: " << r_vx << std::endl;
		std::cout << "updated vy: " << r_vy << std::endl;
		std::cout << "updated p: " << r_p << std::endl;
		std::cout << "total updated: " << error_N << std::endl;
		std::cout << "step " << iteration_times << ", total updated: " << error_N
			  << ", GMRES stpes: " << solver_control.last_step() << std::endl;

		iteration_times++;
		if (iteration_times > 10)
		{
			std::cout << "Disconvergence at step 10." << std::endl;
			break;
		}
	}

};
示例#20
0
/**
 * Computes Gram matrix of a specified kernel. Given two sets of vectors
 * A (n1 vectors) and B (n2 vectors), it returns Gram matrix K (n1 x n2).
 *
 * @param kernelType 'linear' | 'poly' | 'rbf' | 'cosine'
 *
 * @param kernelParam   --    | degree | sigma |    --
 *
 * @param A a 1D {@code Vector} array
 *
 * @param B a 1D {@code Vector} array
 *
 * @return Gram matrix (n1 x n2)
 */
Matrix& calcKernel(std::string kernelType,
		double kernelParam, Vector** A, int nA, Vector** B, int nB) {

	Matrix* K = null;
	if (kernelType == "linear") {
		double** resData = allocate2DArray(nA, nB, 0);
		double* resRow = null;
		Vector* V = null;
		for (int i = 0; i < nA; i++) {
			resRow = resData[i];
			V = A[i];
			for (int j = 0; j < nB; j++) {
				resRow[j] = innerProduct(*V, *B[j]);
			}
		}
		K = new DenseMatrix(resData, nA, nB);
		// K = A.transpose().mtimes(B);
	} else if (kernelType == "cosine") {
		double* AA = new double[nA];
		Vector* V = null;
		for (int i = 0; i < nA; i++) {
			V = A[i];
			// AA[i] = sum(V->times(*V));
			AA[i] = innerProduct(*V, *V);
		}
		double* BB = new double[nB];
		for (int i = 0; i < nB; i++) {
			V = B[i];
			// BB[i] = sum(V->times(*V));
			BB[i] = innerProduct(*V, *V);
		}
		double** resData = allocate2DArray(nA, nB, 0);
		double* resRow = null;
		for (int i = 0; i < nA; i++) {
			resRow = resData[i];
			V = A[i];
			for (int j = 0; j < nB; j++) {
				resRow[j] = innerProduct(*V, *B[j]) / sqrt(AA[i] * BB[j]);
			}
		}
		K = new DenseMatrix(resData, nA, nB);
		delete[] AA;
		delete[] BB;
		// K = dotMultiply(scalarDivide(1, sqrt(kron(AA.transpose(), BB))), AB);
	} else if (kernelType == "poly") {
		double** resData = allocate2DArray(nA, nB, 0);
		double* resRow = null;
		Vector* V = null;
		for (int i = 0; i < nA; i++) {
			resRow = resData[i];
			V = A[i];
			for (int j = 0; j < nB; j++) {
				resRow[j] = pow(innerProduct(*V, *B[j]), kernelParam);
			}
		}
		K = new DenseMatrix(resData, nA, nB);
		// K = pow(A.transpose().mtimes(B), kernelParam);
	} else if (kernelType == "rbf") {
		K = &l2DistanceSquare(A, nA, B, nB);
		timesAssign(*K, -1 / (2 * pow(kernelParam, 2)));
		expAssign(*K);
		// K = exp(l2DistanceSquare(X1, X2).times(-1 / (2 * Math.pow(kernelParam, 2))));
	}
	return *K;

}
示例#21
0
bool DGKTSD::evaluateWHf(const DKTS& a, const DKTS& xi, const DKTS& v, DKTS& w) const
 {
    bool value = true;

    LongInt d = DGKTSD::d();
    LongInt k = DGKTSD::k();
    LongInt l = DGKTSD::l();
    LongInt m = DGKTSD::m();

    w.setNull();
    attr_w().setNull();

    for(LongInt mu1=0; mu1<d; mu1++)
     {
        for(LongInt j1=0; j1<k; j1++)
         {
            const LongReal& preFactor = W(j1, mu1);

            DKTVector& work_jmu = attr_w(j1, mu1);

            if(mu1!=0)
             {
                //The Matrix G
                const DKTVector& xjm = xi(j1, mu1);
                const DKTVector& vjm = v(j1, mu1);

                work_jmu.update(2.0*innerProduct(xjm, vjm), xjm);

                work_jmu.update((x(j1, j1, mu1) - 1.0), vjm);
                work_jmu *= 4.0*attr_lambda1*preFactor;
             }
            for(LongInt mu2=0; mu2<d; mu2++)
             {
                if(mu2!=mu1)
                 {
                    for(LongInt j2=0; j2<k; j2++)
                     {
                        //The Matrix C and lambda2*G2(C)
                        if(j1==j2)
                         {
                            work_jmu.update((1.0+2.0*attr_lambda2)*psi(j1, j2, mu1, mu2)*innerProduct(xi(j1, mu2), v(j2, mu2))*W(j2, mu2), xi(j2, mu1));

/*                            
                            // The Matrix B = x^mu1 * d_j1,mu1,mu2 * (x^mu2)^t
                            LongReal& vjm = v(j1, mu2)(0);

                            dgemv (&AMatrix::conjTrans, &m, &k, &const_eins, &xi(mu2)(0), &m, &vjm, &const_inc,
                                   &const_null, &attr_workK[0], &const_inc);

                            for(LongInt j=0; j<k; j++)
                             {
                                attr_workK[j] *= psi(j1, j, mu1, mu2);
                             }

                            dgemv (&AMatrix::notConjTrans, &m, &k, &const_eins, &xi(mu1)(0), &m, &attr_workK[0], &const_inc,
                                   &const_eins, &work_jmu(0), &const_inc);

                            // The Matrix D = a^mu1 * da_j1,mu1,mu2 * (a^mu2)^t

                            dgemv (&AMatrix::conjTrans, &m, &l, &const_minus_eins, &a(mu2)(0), &m, &vjm, &const_inc,
                                   &const_null, &attr_workL[0], &const_inc);

                            for(LongInt i=0; i<l; i++)
                             {
                                attr_workL[i] *= phi(j1, i, mu1, mu2);
                             }

                            dgemv (&AMatrix::notConjTrans, &m, &l, &const_eins, &a(mu1)(0), &m, &attr_workL[0], &const_inc,
                                   &const_eins, &work_jmu(0), &const_inc);
*/                                   
                         }
                        else
                         {
                            work_jmu.update(psi(j1, j2, mu1, mu2)*innerProduct(xi(j1, mu2), v(j2, mu2))*W(j2, mu2), xi(j2, mu1));                         
                         }
                     }
                 }                                  
             }  

            work_jmu.update(attr_lambda2*psi(j1, j1, mu1, mu1)*W(j1, mu1), v(j1, mu1));            
            work_jmu *= preFactor;
         }// End for(LongInt j1=0; j1<k; j1++)

        for(LongInt j11=0; j11<k; j11++)
         {
            DKTVector& w_jmu = w(j11, mu1);

            for(LongInt j2=0; j2<k; j2++)
             {
                w_jmu.update(A(j11, j2, mu1), attr_w(j2, mu1));
             }
         }// End for(LongInt j11=0; j11<k; j1++)
     }// End for(LongInt mu1=0; mu1<d; mu1++)
  
    w() += v();

   return value;
 }
示例#22
0
bool DGKTSD::crA(const DKTS& ai, const DKTS& xi)
 {
    bool value = true;

    DKTVector& w    = attr_bo();
    DKTVector& r    = attr_r();
    DKTVector& x    = attr_direction();
    DKTVector& a    = attr_ap();
    DKTVector& c    = attr_po();
    DKTVector& b    = attr_b();
    DKTVector& p    = attr_p();
    DKTVector& grad = attr_gradientV();

    //Init
    // r=grad - H*d
    evaluateHf(ai, xi, attr_direction, attr_r);
    r *= -1.0;
    r += grad;    

    // p=W^-1*r
    evaluateAinv(attr_r, attr_p);

    // a = H*p
    evaluateHf(ai, xi, attr_p, attr_ap);

    // b = W^-1*ap
    evaluateAinv(attr_ap, attr_b);
          
    // w = p
    w = p;
    
    LongReal error  = innerProduct(a, b);
    LongReal errorO = error;
    LongReal errorE = l2(r);
    LongReal eps    = epsilonCR();//*errorE;
    
    LongReal lambda = 1.0, a0 = 1.0;

    const LongInt     maxSteps = maxStepsCR();
    LongInt numberOfIterations = 1;    

    while(eps<errorE && numberOfIterations <= maxSteps)
     {        
        lambda = innerProduct(r, b)/error;

        x.update( lambda, p);
        r.update(-lambda, a);
        w.update(-lambda, b);        

        evaluateWHf(ai, xi, attr_b, attr_po);

        a0 = innerProduct(r, c)/error;

        p *= -a0;
        p.update(1.0, w);
        
        // a = H*p
        evaluateHf(ai, xi, attr_p, attr_ap);
        // b = W^-1*ap
        evaluateAinv(attr_ap, attr_b);

        errorO = error;
        error  = innerProduct(a, b);
        errorE = l2(r);
    
        numberOfIterations++;
     }

    if(attr_printCout)
     {
        cout << "crItr = " << setw(4) << numberOfIterations-1 << " ";
     }
/*
    if(maxSteps < numberOfIterations)
     {
        x = grad;
     }
*/
   return value;
 }
    OrthogonalProjections::OrthogonalProjections(const Matrix& originalVectors,
                                                 Real multiplierCutoff,
                                                 Real tolerance)
    : originalVectors_(originalVectors),
      multiplierCutoff_(multiplierCutoff),
      numberVectors_(originalVectors.rows()),
      dimension_(originalVectors.columns()),
      validVectors_(true,originalVectors.rows()), // opposite way round from vector constructor
      orthoNormalizedVectors_(originalVectors.rows(),
                              originalVectors.columns())
    {
        std::vector<Real> currentVector(dimension_);
        for (Size j=0; j < numberVectors_; ++j)
        {

            if (validVectors_[j])
            {
                for (Size k=0; k< numberVectors_; ++k) // create an orthormal basis not containing j
                {
                    for (Size m=0; m < dimension_; ++m)
                        orthoNormalizedVectors_[k][m] = originalVectors_[k][m];

                    if ( k !=j && validVectors_[k])
                    {


                        for (Size l=0; l < k; ++l)
                        {
                            if (validVectors_[l] && l !=j)
                            {
                                Real dotProduct = innerProduct(orthoNormalizedVectors_, k, orthoNormalizedVectors_,l);
                                for (Size n=0; n < dimension_; ++n)
                                    orthoNormalizedVectors_[k][n] -=  dotProduct*orthoNormalizedVectors_[l][n];
                            }

                        }

                        Real normBeforeScaling= norm(orthoNormalizedVectors_,k);

                        if (normBeforeScaling < tolerance)
                        {
                            validVectors_[k] = false;
                        }
                        else
                        {
                            Real normBeforeScalingRecip = 1.0/normBeforeScaling;
                            for (Size m=0; m < dimension_; ++m)
                                orthoNormalizedVectors_[k][m] *= normBeforeScalingRecip;

                        } // end of else (norm < tolerance)

                    } // end of if k !=j && validVectors_[k])

                }// end of  for (Size k=0; k< numberVectors_; ++k)

                // we now have an o.n. basis for everything except  j

                Real prevNormSquared = normSquared(originalVectors_, j);


                for (Size r=0; r < numberVectors_; ++r)
                    if (validVectors_[r] && r != j)
                    {
                        Real dotProduct = innerProduct(orthoNormalizedVectors_, j, orthoNormalizedVectors_,r);

                        for (Size s=0; s < dimension_; ++s)
                           orthoNormalizedVectors_[j][s] -= dotProduct*orthoNormalizedVectors_[r][s];

                    }

               Real projectionOnOriginalDirection = innerProduct(originalVectors_,j,orthoNormalizedVectors_,j);
               Real sizeMultiplier = prevNormSquared/projectionOnOriginalDirection;

               if (std::fabs(sizeMultiplier) < multiplierCutoff_)
               {
                    for (Size t=0; t < dimension_; ++t)
                        currentVector[t] = orthoNormalizedVectors_[j][t]*sizeMultiplier;

               }
               else
                   validVectors_[j] = false;


            } // end of  if (validVectors_[j])

            projectedVectors_.push_back(currentVector);


        } //end of j loop

        numberValidVectors_ =0;
        for (Size i=0; i < numberVectors_; ++i)
            numberValidVectors_ +=  validVectors_[i] ? 1 : 0;


    } // end of constructor
示例#24
0
文件: Util.cpp 项目: cran/stream
double Util::vectorLengthEuclid(Rcpp::NumericVector x) {
  double val = innerProduct(x,x);
  return sqrt(val);
}
示例#25
0
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    int i, j, k, mc, offset, it, maxit = 0;
    double *A, *x, *r, *r_new, mu, *cd, *Atr_prev, *Av = NULL, *v = NULL, *prev_r = NULL, norml1 = 0;
    size_t *C = NULL, *level_sizes = NULL;
    double *WU, maxDelta = 0, tol, *Atr, coarseningRatio;
	Trace trace;
	
    size_t rowLen = mxGetN(prhs[0]);
    size_t colLen = mxGetM(prhs[0]);
    
	trace.idx = 1;
	
    A 				= mxGetPr(prhs[0]);
    x 				= mxGetPr(prhs[1]);
    r 				= mxGetPr(prhs[2]);
    mu 				= *mxGetPr(prhs[3]);
    maxit 			= (int)*mxGetPr(prhs[4]);
    tol   			= *mxGetPr(prhs[5]);
    coarseningRatio = *mxGetPr(prhs[6]);
    Atr_prev 		= mxGetPr(prhs[7]);
    
    // mu is sometimes called lambda
    // tol - accuracy. The algorithm stops when maximal CD update is below tol.
    // coarseningRatio - the ration that we reduce the dictionary at each level. generally 0.5. 
	
    /*Allocate memory and assign output pointer*/
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(rowLen, 1, mxREAL);
    plhs[2] = mxCreateDoubleMatrix(rowLen, 1, mxREAL);
	plhs[3] = mxCreateDoubleMatrix(colLen, 1, mxREAL);
	plhs[4] = mxCreateDoubleMatrix(maxit * 2, 1, mxREAL);
	plhs[5] = mxCreateDoubleMatrix(maxit * 2, 1, mxREAL);
	plhs[6] = mxCreateDoubleMatrix(1, 1, mxREAL);

	/*Get a pointer to the data space in our newly allocated memory*/
    WU    			 = mxGetPr(plhs[0]);
    cd    			 = mxGetPr(plhs[1]);
    Atr    			 = mxGetPr(plhs[2]);
    r_new   		 = mxGetPr(plhs[3]);
	trace.fx_trace 	 = mxGetPr(plhs[4]);
	trace.time_trace = mxGetPr(plhs[5]);
	
	trace.time_trace[0] = clock();
	
	C = (size_t *) malloc(sizeof(size_t) * rowLen);
    if (C == NULL) {
        mexPrintf("malloc failed: C\n");
		goto out;
    }
    
	level_sizes = (size_t *) malloc(sizeof(size_t) * MAX_NUM_OF_LEVELS);
	if (level_sizes == NULL) {
        mexPrintf("malloc failed: level_sizes\n");
		goto malloc_level_sizes_err;
    }
	
	v = (double *) malloc(sizeof(double) * rowLen);
	if (v == NULL) {
        mexPrintf("malloc failed: v\n");
		goto malloc_v_err;
    }
	
	Av = (double *) malloc(sizeof(double) * colLen);
	if (Av == NULL) {
        mexPrintf("malloc failed: Av\n");
		goto malloc_Av_err;
    }
	
	prev_r = (double *) malloc(sizeof(double) * colLen);
	if (prev_r == NULL) {
        mexPrintf("malloc failed: prev_r\n");
		goto malloc_prev_r_err;
    }
    
    for (i = 0; i < colLen; i++) {
        r_new[i]  = r[i];
		prev_r[i] = r[i];
		Atr[i]    = Atr_prev[i];
		Av[i]     = 0;
    }
	
    for (i = 0; i < rowLen; i++) {
        cd[i]   = x[i];
		v[i]    = 0;
		norml1 += fabs(x[i]);
    }
	
	trace.fx_trace[0] = 0.5 * innerProduct(r, r, colLen) + mu * norml1;
	
	mexPrintf("MLCD: %lf\n", trace.fx_trace[0]);
	
    for (it = 0; it < maxit; ++it) {
        maxDelta = MLCD(A, cd, v, Av, r_new, prev_r, Atr, C, rowLen, colLen, mu, tol, (size_t)(1 / coarseningRatio), level_sizes, &trace);
		
		norml1 = 0;
		for (i = 0; i < rowLen; i++) {
			norml1 += fabs(cd[i]);
		}
		
		trace.fx_trace[trace.idx] = 0.5 * innerProduct(r_new, r_new, colLen) + mu * norml1;
		trace.time_trace[trace.idx] = (clock() - trace.time_trace[0]) / CLOCKS_PER_SEC;
		trace.idx++;
		
        if (maxDelta < tol) {
            break;
        }   
    }
	
	trace.time_trace[0] = 0;
	*mxGetPr(plhs[6]) = trace.idx;

    *WU = it + 1;
	
    // for (; it < maxit ; ++it) {
        // maxDelta = Debiasing(A, cd, Av, Atr, rowLen, colLen, mu);
        // if (maxDelta < 0.2*tol) {
            // break;
        // }   
    // }
	
	free(prev_r);
malloc_prev_r_err:
	free(Av);
malloc_Av_err:
	free(v);
malloc_v_err:
    free(level_sizes);
malloc_level_sizes_err:
	free(C);
out:
	return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])
{
	clock_t t1 = clock();

	double*	C = mxGetPr(prhs[0]);								// Constraint matrix
	int	   c = (int)(mxGetM(prhs[0]));							// number of constraints
	double* X = mxGetPr(prhs[1]);								// data points
	int  npts = (int)(mxGetM(prhs[1]));							// number of data points
	int		d = (int)(mxGetN(prhs[1]));							// number of data points
	double* G0 = mxGetPr(prhs[2]);								// input kernel factor matrix
	int	 r = (int)(mxGetN(prhs[2]));							// dimensionality of factor matrix
	double tol = (double)(*mxGetPr(prhs[3]));					// tolerance
	double gamma = (double)(*mxGetPr(prhs[4]));					// gamma
	int max_iters = (int)(*mxGetPr(prhs[5]));					// maximum number of iterations
	int rank = (int)(*mxGetPr(prhs[6]));						// rank of input kernel matrix



	// allocating memory

	// initialize the low rank matrix as I_{rxr}
	double* B = (double*)mxCalloc(r*r,sizeof(double));
	int B_dim[2] = {r,r};

	for(int i = 0;i<r; i++)
		B[i*r+i] = 1;

	double* bhat   = (double*)mxCalloc(c,sizeof(double));
	double* lambda = (double*)mxCalloc(c,sizeof(double));
	double* lambdaold = (double*)mxCalloc(c,sizeof(double));
	double* v = (double*)mxCalloc(r,sizeof(double));
	double* w = (double*)mxCalloc(r,sizeof(double));
	int v_dim[2] = {r,1};

	memcpy(bhat,C+3*c,sizeof(double)*c);
		

	int delta,iter;
	int cnt = 0;
	double beta,conv;
	iter = 0;

	clock_t t3_temp, t4_temp;
	double t_chol = 0.0;
	double t_chol_update = 0.0;
	while(1)
	{
		int i1 = C[cnt]-1;
		int i2 = C[cnt+c]-1;
		memset(v,0.0,sizeof(double)*r);
		for(int i = 0; i < r; i++)
			v[i] = G0[i*npts + i1] - G0[i*npts + i2];
		innerProduct(B,B_dim,v,v_dim,w);
		
		delta = C[cnt+2*c];
		double p,alpha;
		innerProduct(w,v_dim,w,v_dim,&p);
		alpha = min(lambda[cnt],delta*gamma/(gamma + 1)*(1/p - 1/bhat[cnt]));
		lambdaold[cnt] = lambda[cnt];

		beta = delta*alpha/(1-delta*alpha*p);
		bhat[cnt] = gamma*bhat[cnt]/(gamma + delta*alpha*bhat[cnt]);
		lambda[cnt] = lambda[cnt] - alpha;

		
		t3_temp = clock();
		t_chol_update += cholUpdateMult(beta,w,B,r);
		t4_temp = clock();
		t_chol += ((double)(t4_temp-t3_temp)/((double)(CLOCKS_PER_SEC)));

		//for(int row_i = 0; row_i < r; row_i++)
		//{
		//	mexPrintf("\n");
		//	for(int col_i = 0;col_i < r;col_i++)
		//	{
		//		mexPrintf("%.2f ",B[col_i*r+row_i]);
		//	}
		//}
		if(cnt == c-1)
		{
			double norm_sum, norm_lambda, norm_lambdaold, norm_lambdadiff;
			matrixMultiply(lambda,lambda,&norm_lambda,1,c,1);
			matrixMultiply(lambdaold,lambdaold,&norm_lambdaold,1,c,1);
			norm_lambda = sqrt(norm_lambda);
			norm_lambdaold = sqrt(norm_lambdaold);
			double normsum = norm_lambda + norm_lambdaold;
			if(normsum == 0)
				break;
			else
			{
				norm_lambdadiff = 0.0;
				for(int j = 0; j < c; j++)
					norm_lambdadiff += fabs(lambdaold[j] - lambda[j]);
				conv = norm_lambdadiff/normsum;
				if(conv < tol || iter >= max_iters)
					break;
			}
		}
		cnt = cnt % (c-1) + 1;
		iter++;
		if(iter % max(25000,c) == 0)
		{
			mexPrintf("itml iter: %d of %d, conv = %0.12f\n", iter, max_iters, conv);
			mexEvalString("drawnow;");
		}

	}

	mexPrintf("itml converged to tol: %f, iter: %d\n", conv, iter);
	clock_t t2 = clock();
	mexPrintf("total time taken in C++ =  %.4lf\n", ((double)(t2-t1)/((double)(CLOCKS_PER_SEC))));
//	mexPrintf("total time taken in chol update =  %.4lf, %.4lf\n", t_chol,t_chol_update);

	mxArray* G = mxCreateDoubleMatrix(npts,r,mxREAL);
	matrixMultiply(G0,B,mxGetPr(G),npts,r,r);

	mxArray* mxbhat = mxCreateDoubleMatrix((mwSize)c,1,mxREAL);
	memcpy(mxGetPr(mxbhat),bhat,c*sizeof(double));

	plhs[0] = G;
	plhs[1] = mxbhat;

	mxFree(B);
	mxFree(bhat);
	mxFree(lambda);
	mxFree(lambdaold);
	mxFree(v);
}
示例#27
0
double NOX::Epetra::Vector::innerProduct(const NOX::Abstract::Vector& y) const
{
  return innerProduct(dynamic_cast<const NOX::Epetra::Vector&>(y));
}
示例#28
0
int main(int argc, char * argv[])
{
  typedef MPI::HGeometryForest<DIM,DOW> forest_t;
  typedef MPI::BirdView<forest_t> ir_mesh_t;
  typedef FEMSpace<double,DIM,DOW> fe_space_t;  
  typedef MPI::DOF::GlobalIndex<forest_t, fe_space_t> global_index_t;

  MPI_Init(&argc, &argv);

  forest_t forest(MPI_COMM_WORLD);
  ir_mesh_t ir_mesh;
  MPI::load_mesh(argv[1], forest, ir_mesh); /// 从一个目录中读入网格数据

  int round = 0;
  if (argc >= 3) round = atoi(argv[2]);

  ir_mesh.globalRefine(round);
  ir_mesh.semiregularize();
  ir_mesh.regularize(false);

  TemplateGeometry<DIM> tri;
  tri.readData("triangle.tmp_geo");
  CoordTransform<DIM,DIM> tri_ct;
  tri_ct.readData("triangle.crd_trs");
  TemplateDOF<DIM> tri_td(tri);
  tri_td.readData("triangle.1.tmp_dof");
  BasisFunctionAdmin<double,DIM,DIM> tri_bf(tri_td);
  tri_bf.readData("triangle.1.bas_fun");

  std::vector<TemplateElement<double,DIM,DIM> > tmp_ele(1);
  tmp_ele[0].reinit(tri, tri_td, tri_ct, tri_bf);

  RegularMesh<DIM,DOW>& mesh = ir_mesh.regularMesh();
  fe_space_t fem_space(mesh, tmp_ele);
  u_int n_ele = mesh.n_geometry(DIM);
  fem_space.element().resize(n_ele);
  for (int i = 0;i < n_ele;i ++) {
    fem_space.element(i).reinit(fem_space, i, 0);
  }
  fem_space.buildElement();
  fem_space.buildDof();
  fem_space.buildDofBoundaryMark();

  std::cout << "Building global indices ... " << std::flush;
  global_index_t global_index(forest, fem_space);
  global_index.build();
  std::cout << "OK!" << std::endl;

  Epetra_MpiComm comm(forest.communicator());
  Epetra_Map map(global_index.n_global_dof(), global_index.n_primary_dof(), 0, comm);
  global_index.build_epetra_map(map);
  
  /// 构造 Epetra 的分布式稀疏矩阵模板
  std::cout << "Build sparsity pattern ... " << std::flush;
  Epetra_FECrsGraph G(Copy, map, 10);
  fe_space_t::ElementIterator
    the_ele = fem_space.beginElement(),
    end_ele = fem_space.endElement();
  for (;the_ele != end_ele;++ the_ele) {
    const std::vector<int>& ele_dof = the_ele->dof();
    u_int n_ele_dof = ele_dof.size();

    /**
     * 建立从局部自由度数组到全局自由度数组的映射表,这是实现分布式并行
     * 状态下的数据结构的关键一步。
     */
    std::vector<int> indices(n_ele_dof);
    for (u_int i = 0;i < n_ele_dof;++ i) {
      indices[i] = global_index(ele_dof[i]);
    }
    G.InsertGlobalIndices(n_ele_dof, &indices[0], n_ele_dof, &indices[0]);
  }
  G.GlobalAssemble();
  std::cout << "OK!" << std::endl;

  /// 准备构造 Epetra 的分布式稀疏矩阵和计算分布式右端项
  std::cout << "Build sparse matrix ... " << std::flush;
  Epetra_FECrsMatrix A(Copy, G);
  Epetra_FEVector b(map);
  the_ele = fem_space.beginElement();
  for (;the_ele != end_ele;++ the_ele) {
    double vol = the_ele->templateElement().volume();
    const QuadratureInfo<DIM>& qi = the_ele->findQuadratureInfo(5);
    std::vector<Point<DIM> > q_pnt = the_ele->local_to_global(qi.quadraturePoint());
    int n_q_pnt = qi.n_quadraturePoint();
    std::vector<double> jac = the_ele->local_to_global_jacobian(qi.quadraturePoint());
    std::vector<std::vector<double> > bas_val = the_ele->basis_function_value(q_pnt);
    std::vector<std::vector<std::vector<double> > > bas_grad = the_ele->basis_function_gradient(q_pnt);

    const std::vector<int>& ele_dof = the_ele->dof();
    u_int n_ele_dof = ele_dof.size();
    FullMatrix<double> ele_mat(n_ele_dof, n_ele_dof);
    Vector<double> ele_rhs(n_ele_dof);
    for (u_int l = 0;l < n_q_pnt;++ l) {
      double JxW = vol*jac[l]*qi.weight(l);
      double f_val = _f_(q_pnt[l]);
      for (u_int i = 0;i < n_ele_dof;++ i) {
        for (u_int j = 0;j < n_ele_dof;++ j) {
          ele_mat(i, j) += JxW*(bas_val[i][l]*bas_val[j][l] +
                                innerProduct(bas_grad[i][l], bas_grad[j][l]));
        }
        ele_rhs(i) += JxW*f_val*bas_val[i][l];
      }
    }
    /**
     * 此处将单元矩阵和单元载荷先计算好,然后向全局的矩阵和载荷向量上
     * 集中,可以提高效率。
     */

    std::vector<int> indices(n_ele_dof);
    for (u_int i = 0;i < n_ele_dof;++ i) {
      indices[i] = global_index(ele_dof[i]);
    }
    A.SumIntoGlobalValues(n_ele_dof, &indices[0], n_ele_dof, &indices[0], &ele_mat(0,0));
    b.SumIntoGlobalValues(n_ele_dof, &indices[0], &ele_rhs(0));
  }
  A.GlobalAssemble();
  b.GlobalAssemble();
  std::cout << "OK!" << std::endl;

  /// 准备解向量。
  Epetra_Vector x(map);

  /// 调用 AztecOO 的求解器。
  std::cout << "Solving the linear system ..." << std::flush;
  Epetra_LinearProblem problem(&A, &x, &b);
  AztecOO solver(problem);
  ML_Epetra::MultiLevelPreconditioner precond(A, true);
  solver.SetPrecOperator(&precond);
  solver.SetAztecOption(AZ_solver, AZ_cg);
  solver.SetAztecOption(AZ_output, 100);
  solver.Iterate(5000, 1.0e-12);
  std::cout << "OK!" << std::endl;

  Epetra_Map fe_map(-1, global_index.n_local_dof(), &global_index(0), 0, comm);
  FEMFunction<double,DIM> u_h(fem_space);
  Epetra_Import importer(fe_map, map);
  Epetra_Vector X(View, fe_map, &u_h(0));
  X.Import(x, importer, Add);

  char filename[1024];
  sprintf(filename, "u_h%d.dx", forest.rank());
  u_h.writeOpenDXData(filename);

  MPI_Finalize();

  return 0;
}
示例#29
0
void testFileInnerProduct(){
	printf("\nTest file inner product:\n");
	
	FILE *fr;
	const int maxLineLength = 20000;
	char line[maxLineLength];
	int totalTests = 0, successTests = 0;
	
    time_t start_t, end_t;
    double diff_t;
    time(&start_t);

	fr = fopen("tests/tests-c/innerProductTests.txt", "rt");
	
	while(1){
		struct StabilizerState state1;
		struct StabilizerState state2;
		int eps, outEps, p, outP, m, outM;
		gsl_complex ans;
		
		//populate state1: 
		
		//read n
		if(!readInt(fr, line, maxLineLength, &state1.n)){
			break;
		}
		
		//read k
		if(!readInt(fr, line, maxLineLength, &state1.k)){
			break;
		}
		
		//read Q
		if(!readInt(fr, line, maxLineLength, &state1.Q)){
			break;
		}
		
		//read h
		double vectorDatah1[state1.n];
		if(!readArray(fr, line, maxLineLength, vectorDatah1)){
			break;
		}
		gsl_vector_view vectorViewh1 = gsl_vector_view_array(vectorDatah1, state1.n);
		state1.h = &vectorViewh1.vector;
		
		//read D
		double vectorDataD1[state1.n];
		if(!readArray(fr, line, maxLineLength, vectorDataD1)){
			break;
		}
		gsl_vector_view vectorViewD1 = gsl_vector_view_array(vectorDataD1, state1.n);
		state1.D = &vectorViewD1.vector;
		
		//read G
		double matrixDataG1[state1.n*state1.n];
		if(!readArray(fr, line, maxLineLength, matrixDataG1)){
			break;
		}
		gsl_matrix_view matrixViewG1 = gsl_matrix_view_array(matrixDataG1, state1.n, state1.n);
		state1.G = &matrixViewG1.matrix;
		
		//read Gbar
		double matrixDataGbar1[state1.n*state1.n];
		if(!readArray(fr, line, maxLineLength, matrixDataGbar1)){
			break;
		}
		gsl_matrix_view matrixViewGbar1 = gsl_matrix_view_array(matrixDataGbar1, state1.n, state1.n);
		state1.Gbar = &matrixViewGbar1.matrix;
		
		//read J
		double matrixDataJ1[state1.n*state1.n];
		if(!readArray(fr, line, maxLineLength, matrixDataJ1)){
			break;
		}
		gsl_matrix_view matrixViewJ1 = gsl_matrix_view_array(matrixDataJ1, state1.n, state1.n);
		state1.J = &matrixViewJ1.matrix;
		
		//populate state2: 
		
		//read n
		if(!readInt(fr, line, maxLineLength, &state2.n)){
			break;
		}
		
		//read k
		if(!readInt(fr, line, maxLineLength, &state2.k)){
			break;
		}
		
		//read Q
		if(!readInt(fr, line, maxLineLength, &state2.Q)){
			break;
		}
		
		//read h
		double vectorDatah2[state2.n];
		if(!readArray(fr, line, maxLineLength, vectorDatah2)){
			break;
		}
		gsl_vector_view vectorViewh2 = gsl_vector_view_array(vectorDatah2, state2.n);
		state2.h = &vectorViewh2.vector;
		
		//read D
		double vectorDataD2[state2.n];
		if(!readArray(fr, line, maxLineLength, vectorDataD2)){
			break;
		}
		gsl_vector_view vectorViewD2 = gsl_vector_view_array(vectorDataD2, state2.n);
		state2.D = &vectorViewD2.vector;
		
		//read G
		double matrixDataG2[state2.n*state2.n];
		if(!readArray(fr, line, maxLineLength, matrixDataG2)){
			break;
		}
		gsl_matrix_view matrixViewG2 = gsl_matrix_view_array(matrixDataG2, state2.n, state2.n);
		state2.G = &matrixViewG2.matrix;
		
		//read Gbar
		double matrixDataGbar2[state2.n*state2.n];
		if(!readArray(fr, line, maxLineLength, matrixDataGbar2)){
			break;
		}
		gsl_matrix_view matrixViewGbar2 = gsl_matrix_view_array(matrixDataGbar2, state2.n, state2.n);
		state2.Gbar = &matrixViewGbar2.matrix;
		
		//read J
		double matrixDataJ2[state2.n*state2.n];
		if(!readArray(fr, line, maxLineLength, matrixDataJ2)){
			break;
		}
		gsl_matrix_view matrixViewJ2 = gsl_matrix_view_array(matrixDataJ2, state2.n, state2.n);
		state2.J = &matrixViewJ2.matrix;
		
		//read outEps
		if(!readInt(fr, line, maxLineLength, &outEps)){
			break;
		}
		
		//read outP
		if(!readInt(fr, line, maxLineLength, &outP)){
			break;
		}
		
		//read outM
		if(!readInt(fr, line, maxLineLength, &outM)){
			break;
		}
		
		innerProduct(&state1, &state2, &eps, &p, &m, &ans, 1);
		
		int isEpsWorking = eps == outEps ? 1 : 0;
		int isPWorking = p == outP ? 1 : 0;
		int isMWorking = mod(m, 8) == mod(outM, 8) ? 1 : 0;
		
		totalTests++;
		if((eps==0&&isEpsWorking) || isEpsWorking*isPWorking*isMWorking > 0){
			successTests++;
		}
		else{
			printf("eps: %d, outEps: %d, p: %d, outP: %d, m: %d, outM: %d", eps, outEps, p, outP, m, outM);
			printf("Test number %d failed.\n", totalTests);
		}

        /*
        if (totalTests == 100) {
            break;
        }*/
	}
	
	fclose(fr);
	
	printf("%d out of %d tests successful.\n", successTests, totalTests);

    time(&end_t);
    diff_t = difftime(end_t, start_t);
    printf("Time elapsed: %f s\n", diff_t);

	printf("----------------------\n");
}
示例#30
0
void ISOP2P1::computeMonitor()
{
	if (isMoving == 0)
	{
		/// 将速度有限元空间的数值解插值到压力有限元空间中,
		/// 为了方便计算压力网格单元上的monitor的值.
		FEMFunction<double, DIM> _u_h(fem_space_p);
		FEMFunction<double, DIM> _v_h(fem_space_p);
		Operator::L2Interpolate(v_h[0], _u_h);
		Operator::L2Interpolate(v_h[1], _v_h);

		RegularMesh<DIM> &mesh_p = irregular_mesh_p->regularMesh();

		int n_ele = mesh_p.n_geometry(DIM);
		Monitor.resize(n_ele, 0.0);

		/// 选取速度数值解的梯度做monitor, 跟文章中的monitor一致.
		FEMSpace<double, DIM>::ElementIterator the_element = fem_space_p.beginElement();
		FEMSpace<double, DIM>::ElementIterator end_element = fem_space_p.endElement();
		for(; the_element != end_element; ++the_element)
		{
			double volume = the_element->templateElement().volume();
			const QuadratureInfo<DIM> &quad_info = the_element->findQuadratureInfo(3);
			std::vector<double> jacobian = the_element->local_to_global_jacobian(quad_info.quadraturePoint());
			int n_quadrature_point = quad_info.n_quadraturePoint();
			std::vector<Point<DIM> > q_point = the_element->local_to_global(quad_info.quadraturePoint());
			std::vector<std::vector<double> >  basis_value = the_element->basis_function_value(q_point);
			std::vector<double> u_h_value = _u_h.value(q_point, *the_element);
			std::vector<double> v_h_value = _v_h.value(q_point, *the_element);
			std::vector<std::vector<double> > u_h_gradient = _u_h.gradient(q_point, *the_element);
			std::vector<std::vector<double> > v_h_gradient = _v_h.gradient(q_point, *the_element);
			float d = 0.0, area = 0.0, cont = 0.0;
			for(int l = 0; l < n_quadrature_point; ++l)
			{
				double Jxw = quad_info.weight(l) * jacobian[l] * volume;
				area += Jxw;
				d += Jxw * (innerProduct(u_h_gradient[l], u_h_gradient[l]) + innerProduct(v_h_gradient[l], v_h_gradient[l]));
			}
			Monitor[the_element->index()] = d / area;
		}
		for (int i = 0; i < n_ele; ++i)
			Monitor[i] = sqrt(1.0 + alpha * pow(Monitor[i], beta));

		/* 后验误差做monitor。
		std::vector<double> side_length(n_face);
	        std::vector<bool> flag(n_face, false);
	        std::vector<double> jump_ux(n_face);
	        std::vector<double> jump_uy(n_face);

	        FEMSpace<double,DIM>::ElementIterator the_element_p = fem_space_p.beginElement();
	        FEMSpace<double,DIM>::ElementIterator end_element_p = fem_space_p.endElement();
	        /// 遍历所有速度单元,计算每条边上的 jump / ||v||_L2.
	        for (; the_element_p != end_element_p; ++the_element_p)
	        {
	        	/// 几何信息.
	        	double volume = the_element_p->templateElement().volume();
	        	const QuadratureInfo<2>& quad_info = the_element_p->findQuadratureInfo(4);
	        	std::vector<double> jacobian = the_element_p->local_to_global_jacobian(quad_info.quadraturePoint());
	        	int n_quadrature_point = quad_info.n_quadraturePoint();
	        	std::vector<Point<2> > q_point = the_element_p->local_to_global(quad_info.quadraturePoint());

	        	const GeometryBM& geometry = the_element_p->geometry();

	        	for (int i = 0; i < geometry.n_boundary(); ++i)
	        	{
	        		int j = geometry.boundary(i);
	        		const GeometryBM& side = mesh_p.geometry(1, j);
	        		const Point<DIM>& p0 = mesh_p.point(mesh_p.geometry(0, side.boundary(0)).vertex(0));
	        		const Point<DIM>& p1 = mesh_p.point(mesh_p.geometry(0, side.boundary(1)).vertex(0));
	        		std::vector<double> vx_gradient = _u_h.gradient(midpoint(p0, p1), *the_element_p);
	        		std::vector<double> vy_gradient = _v_h.gradient(midpoint(p0, p1), *the_element_p);
	        		double vx_value = _u_h.value(midpoint(p0, p1), *the_element_p);
	        		double vy_value = _v_h.value(midpoint(p0, p1), *the_element_p);

	        		double v_L2norm = sqrt(vx_value * vx_value + vy_value * vy_value + eps);
	        		side_length[j] = distance(p0, p1);
	        		if (flag[j])
	        		{
	        			jump_ux[j] -= (vx_gradient[0] * (p0[1] - p1[1]) + vx_gradient[1] * (p1[0] - p0[0]));
	        			jump_uy[j] -= (vy_gradient[0] * (p0[1] - p1[1]) + vy_gradient[1] * (p1[0] - p0[0]));
	        			flag[j] = false;
	        		}
	        		else
	        		{
	        			jump_ux[j] = (vx_gradient[0] * (p0[1] - p1[1]) + vx_gradient[1] * (p1[0] - p0[0]));
	        			jump_uy[j] = (vy_gradient[0] * (p0[1] - p1[1]) + vy_gradient[1] * (p1[0] - p0[0]));
	        			flag[j] = true;
	        		}
	        	}
	        }
	        the_element_p = fem_space_p.beginElement();
	        for(int i = 0; the_element_p != end_element_p; ++the_element_p, ++i)
	        {
	        	const GeometryBM &geometry = the_element_p->geometry();
	        	double cont = 0.0, total_ele_side_length = 0.0;
	        	for (int l = 0; l < geometry.n_boundary(); ++l)
	        	{
	        		int j = geometry.boundary(l);
	        		/// 如果编号是j的边是边界.
	        		if (flag[j])
	        			continue;
	        		/// 将DIM个梯度沿法向方向上的跳跃平方值累加.
	        		cont += (jump_ux[j] * jump_ux[j] + jump_uy[j] * jump_uy[j]) * side_length[j];
	        		total_ele_side_length += side_length[j];
	        	}
	        	Monitor[i] = sqrt(cont / total_ele_side_length);
	        }
//		for (int i = 0; i < n_geometry(DIM); ++i)
//		        monitor(i) = 1.0 / sqrt(1.0 + alpha * pow(monitor(i) / max_monitor, 2));
		 */
	}
}