Exemplo n.º 1
0
void MovingMeshFB::readDomain(const std::string& filename)
{
  int i, j, k, l, l0, l1;
  double d;

  readData(filename);
  index.resize(n_geometry(0));
  n_interior_node = 0;
  n_boundary_node = 0;
  for (i = 0;i < n_geometry(0);i ++) {
    Assert(geometry(0,i).vertex(0) == i, ExcInternalError());
    if (geometry(0, i).boundaryMark() != 0)
      index[i] = n_boundary_node ++;
    else
      index[i] = n_interior_node ++;
  }
  interior_node_index.resize(n_interior_node);
  boundary_node_index.resize(n_boundary_node);
  for (i = 0,j = 0, k = 0;i < n_geometry(0);i ++) {
    if (geometry(0, i).boundaryMark() != 0)
      boundary_node_index[j ++] = i;
    else
      interior_node_index[k ++] = i;
  }

  logical_node.resize(n_geometry(0));
  move_direction.resize(n_geometry(0));
  logical_move_direction.resize(n_geometry(0));
  monitor().resize(n_geometry(2));

  std::vector<int> n_coupling_node(n_geometry(0), 0);
  for (i = 0;i < n_geometry(1);i ++) {
    n_coupling_node[geometry(1,i).vertex(0)] ++;
    n_coupling_node[geometry(1,i).vertex(1)] ++;
  }
  int n_max_coupling_node = *std::max_element(n_coupling_node.begin(), n_coupling_node.end());
  n_max_coupling_node ++;
  spM.reinit(n_interior_node, n_interior_node, n_max_coupling_node);
  spN.reinit(n_interior_node, n_boundary_node, n_max_coupling_node);
  for (i = 0;i < n_geometry(2);i ++) {
    for (j = 0;j < 3;j ++) {
      l0 = geometry(2,i).vertex(j);
      if (geometry(0,l0).boundaryMark() == 0) {
	for (k = 0;k < 3;k ++) {
	  l1 = geometry(2,i).vertex(k);
	  if (geometry(0,l1).boundaryMark())
	    spN.add(index[l0], index[l1]);
	  else
	    spM.add(index[l0], index[l1]);
	}
      }
    }
  }
  spM.compress();
  spN.compress();

  getLogicalMesh();
}
Exemplo n.º 2
0
void MovingMeshFB::moveMesh()
{
  int i, j, k, m;
  double epsilon = 0.2;
  double error = 1.;
  double area, h, l[3], d[3];
  while (error > epsilon) {
    getMoveDirection();
    error = 0;
    for (i = 0;i < n_geometry(2);i ++) {
      const Point<2>& x0 = point(geometry(2,i).vertex(0));
      const Point<2>& x1 = point(geometry(2,i).vertex(1)); 
      const Point<2>& x2 = point(geometry(2,i).vertex(2));
      l[0] = (x2[0] - x1[0])*(x2[0] - x1[0]) + (x2[1] - x1[1])*(x2[1] - x1[1]);
      l[1] = (x0[0] - x2[0])*(x0[0] - x2[0]) + (x0[1] - x2[1])*(x0[1] - x2[1]);
      l[2] = (x1[0] - x0[0])*(x1[0] - x0[0]) + (x1[1] - x0[1])*(x1[1] - x0[1]);
      area = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x2[0] - x0[0])*(x1[1] - x0[1]);
      h = 0.5*area/sqrt(*std::max_element(&l[0], &l[3]));
      for (k = 0;k < 3;++ k) {
	m = geometry(2,i).vertex(k);
	for (d[k] = 0.0, j = 0;j < 2;j ++) {
	  d[k] += move_direction[m][j]*move_direction[m][j];
	}
      }
      h = sqrt(*std::max_element(&d[0], &d[3]))/h;
      if (error < h) error = h;
    }
    std::cerr << "mesh moving error = " << error << std::endl;
    getMoveStepLength();
    for (i = 0;i < n_move_step;i ++) {
      updateSolution();
      updateMesh();
    };
  };
}
Exemplo n.º 3
0
void MovingMeshFB::updateMesh()
{
  for (int i = 0;i < n_geometry(0);i ++) {
    point(i)[0] += move_step_length * move_direction[i][0];
    point(i)[1] += move_step_length * move_direction[i][1];
  }
}
Exemplo n.º 4
0
void MovingMeshFB::outputLogicalMesh(const std::string& filename)
{
  Mesh<2,2> mesh = Mesh<2,2>(*this);
  for (int i = 0;i < n_geometry(0);i ++)
    mesh.point(i) = logical_node[i];
  mesh.writeData(filename);
}
Exemplo n.º 5
0
void MovingMeshFB::smoothMonitor(int s)
{
  int i, j, k;
  std::vector<float> area(n_geometry(2));
  std::vector<float> mass_lumping(n_geometry(0), 0);
  std::vector<float> monitor1(n_geometry(0));
  for (i = 0;i < n_geometry(2);i ++) {
    const Point<2>& x0 = point(geometry(2,i).vertex(0));
    const Point<2>& x1 = point(geometry(2,i).vertex(1)); 
    const Point<2>& x2 = point(geometry(2,i).vertex(2));
    area[i] = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x2[0] - x0[0])*(x1[1] - x0[1]);
    for (j = 0;j < 3;j ++) {
      mass_lumping[geometry(2,i).vertex(j)] += area[i];
    }
  }
  for (i = 0;i < s;i ++) {
    std::fill(monitor1.begin(), monitor1.end(), 0);
    for (j = 0;j < n_geometry(2);j ++) {
      for (k = 0;k < 3;k ++) {
	monitor1[geometry(2,j).vertex(k)] += monitor(j)*area[j];
      }
    }
    for (j = 0;j < n_geometry(0);j ++)
      monitor1[j] /= 3*mass_lumping[j];
    std::fill(monitor().begin(), monitor().end(), 0);
    for (j = 0;j < n_geometry(2);j ++) {
      for (k = 0;k < 3;k ++) {
	monitor(j) += monitor1[geometry(2,j).vertex(k)];
      }
    }
  }
}
Exemplo n.º 6
0
void MovingMeshFB::getLogicalMesh()
{
  std::cout << "Computing logical mesh ..." << std::endl;
  int i, j, k, l0, l1;

  for (i = 0;i < n_geometry(0);i ++) {
    logical_node[i][0] = point(i)[0];
    logical_node[i][1] = point(i)[1];
  }
}
Exemplo n.º 7
0
void MovingMeshFB::getMoveStepLength()
{
  int i, j;
  double a, b, c;
  n_move_step = 1;
  move_step_length = 1.;
  for (i = 0;i < n_geometry(2);i ++) {
    const Point<2>& x0 = point(geometry(2,i).vertex(0));
    const Point<2>& x1 = point(geometry(2,i).vertex(1)); 
    const Point<2>& x2 = point(geometry(2,i).vertex(2));
    a = (move_direction[geometry(2,i).vertex(1)][0] - move_direction[geometry(2,i).vertex(0)][0])
      * (move_direction[geometry(2,i).vertex(2)][1] - move_direction[geometry(2,i).vertex(0)][1])
      - (move_direction[geometry(2,i).vertex(1)][1] - move_direction[geometry(2,i).vertex(0)][1])
      * (move_direction[geometry(2,i).vertex(2)][0] - move_direction[geometry(2,i).vertex(0)][0]);
    b = move_direction[geometry(2,i).vertex(0)][0] * (x1[1] - x2[1])
      - move_direction[geometry(2,i).vertex(0)][1] * (x1[0] - x2[0])
      + move_direction[geometry(2,i).vertex(1)][0] * (x2[1] - x0[1])
      - move_direction[geometry(2,i).vertex(1)][1] * (x2[0] - x0[0])
      + move_direction[geometry(2,i).vertex(2)][0] * (x0[1] - x1[1])
      - move_direction[geometry(2,i).vertex(2)][1] * (x0[0] - x1[0]);
    c = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x1[1] - x0[1])*(x2[0] - x0[0]);
    if (fabs(a)/(fabs(b) + fabs(c)) < 1.0e-4) {
      if (fabs(b) < 1.0e-4*fabs(c))
	; //do nothing
      else if (c/b > 0)
	; //do nothing
      else
	move_step_length = std::min(move_step_length, -c/b);
    }
    else if (b*b - 4*a*c < 0)
      ; //do nothing
    else {
      if (a < 0) {
	a = -a;
	b = -b;
	c = -c;
      }
      double d = (-b - sqrt(b*b - 4*a*c))/(2*a);
      if (d < 0) {
	d = (-b + sqrt(b*b - 4*a*c))/(2*a);
	if (d > 0)
	  move_step_length = std::min(move_step_length, d);
      }
      else
	move_step_length = std::min(move_step_length, d);
    }
  }
  move_step_length *= 0.5;
}
Exemplo n.º 8
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]));
		}
		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));
};
Exemplo n.º 9
0
void MovingMeshFB::getMoveDirection()
{
  int i, j, k, l, l0, l1;
  getMonitor();
  M.reinit(spM);
  N.reinit(spN);
  for (i = 0;i < n_geometry(2);i ++) {
    const Point<2>& x0 = point(geometry(2,i).vertex(0));
    const Point<2>& x1 = point(geometry(2,i).vertex(1)); 
    const Point<2>& x2 = point(geometry(2,i).vertex(2));
    double omega[2][3];
    double area = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x2[0] - x0[0])*(x1[1] - x0[1]);
    omega[0][0] = x2[0] - x1[0]; omega[0][1] = x0[0] - x2[0];
    omega[0][2] = x1[0] - x0[0]; omega[1][0] = x2[1] - x1[1];
    omega[1][1] = x0[1] - x2[1]; omega[1][2] = x1[1] - x0[1];
    for (j = 0;j < 3;j ++) {
      l0 = geometry(2,i).vertex(j);
      if (boundaryMark(0,l0) == 0) {
	for (k = 0;k < 3;k ++) {
	  double d = monitor(i)*(omega[0][j]*omega[0][k] + omega[1][j]*omega[1][k])/area;
	  l1 = geometry(2,i).vertex(k);
	  if (boundaryMark(0,l1))
	    N.add(index[l0], index[l1], d);
	  else
	    M.add(index[l0], index[l1], d);
	}
      }
    }
  }
  solver.lazyReinit(M);

  Vector<double> b(n_boundary_node);
  Vector<double> r(n_interior_node);
  Vector<double> x(n_interior_node);
  for (k = 0;k < 2;++ k) {
    for (i = 0;i < n_boundary_node;i ++) {
      j = boundary_node_index[i];
      b(i) = -logical_node[j][k];
      logical_move_direction[j][k] = 0.0;
    }
    N.vmult(r, b);
    for (i = 0;i < n_interior_node;i ++)
      x(i) = logical_node[interior_node_index[i]][k];
    solver.solve(x, r);
    for (i = 0;i < n_interior_node;i ++) {
      j = interior_node_index[i];
      logical_move_direction[j][k] = logical_node[j][k] - x(i);
      move_direction[j] = 0.0;
    }
  }

  std::vector<double> mass_lumping(n_geometry(0), 0.);
  for (i = 0;i < n_geometry(2);i ++) {
    const int& v0 = geometry(2,i).vertex(0);
    const int& v1 = geometry(2,i).vertex(1);
    const int& v2 = geometry(2,i).vertex(2);
    const Point<2>& x0 = point(v0);
    const Point<2>& x1 = point(v1); 
    const Point<2>& x2 = point(v2);
    double jacobi[2][2];
    double area = ((logical_node[v1][0] - logical_node[v0][0])*(logical_node[v2][1] - logical_node[v0][1]) -
                   (logical_node[v1][1] - logical_node[v0][1])*(logical_node[v2][0] - logical_node[v0][0]));
    jacobi[0][0] = ((x1[0] - x0[0])*(logical_node[v2][1] - logical_node[v0][1]) -
                    (logical_node[v1][1] - logical_node[v0][1])*(x2[0] - x0[0]));
    jacobi[1][0] = ((x1[1] - x0[1])*(logical_node[v2][1] - logical_node[v0][1]) -
                    (logical_node[v1][1] - logical_node[v0][1])*(x2[1] - x0[1]));
    jacobi[0][1] = ((logical_node[v1][0] - logical_node[v0][0])*(x2[0] - x0[0]) -
                    (x1[0] - x0[0])*(logical_node[v2][0] - logical_node[v0][0]));
    jacobi[1][1] = ((logical_node[v1][0] - logical_node[v0][0])*(x2[1] - x0[1]) -
                    (x1[1] - x0[1]) * (logical_node[v2][0] - logical_node[v0][0]));
    for (j = 0;j < 3;j ++) {
      k = geometry(2,i).vertex(j);
      move_direction[k][0] += jacobi[0][0]*logical_move_direction[k][0] + jacobi[0][1]*logical_move_direction[k][1];
      move_direction[k][1] += jacobi[1][0]*logical_move_direction[k][0] + jacobi[1][1]*logical_move_direction[k][1];
      mass_lumping[k] += area;
    }
  }
  for (i = 0;i < n_geometry(0);i ++) {
    move_direction[i][0] /= mass_lumping[i];
    move_direction[i][1] /= mass_lumping[i];
  }

  for (i = 0;i < n_boundary_node;i ++) {
    j = boundary_node_index[i];
    move_direction[j][0] = 0.0;
    move_direction[j][1] = 0.0;
  }
}