void Engine2D::CreateMesh(Mesh2D& mesh)
{
	// Fill side1 length BC -> Left side
	// Fill side2 length BC -> Right side
	// Fill width1 BC ->Top
	// Fill width2 BC ->bottom
	mesh.number_of_nodes = (mesh.spacial_length / mesh.spacial_step_size);
	mesh.all_node_locations.push_back(0);
	for (int i = 0; i < mesh.number_of_nodes; i++)
	{
		mesh.all_node_locations.push_back(mesh.all_node_locations.back() + mesh.spacial_step_size);

	}
	// !Create a boundary condition for each state
	for (int state = 0; state <= number_of_states; state++)
	{
		mesh.left_side_boundary_conditions.push_back(mesh.SideBoundary());
		mesh.right_side_boundary_conditions.push_back(mesh.SideBoundary());
		// !First and last states
		if (state== 0 || state==number_of_states)
		{
			mesh.top_width_boundary_conditions.push_back(mesh.WidthBoundary());
			mesh.bottom_width_boundary_conditions.push_back(mesh.WidthBoundary());
		}
	}


}
示例#2
0
// =============================================================================
  bool Mesh2DUtils::identify_patch_upper_right(const Mesh2D&m, double u, 
					       double v, int& x_ix, int& y_ix)
// =============================================================================
{
  double tol = 1.0e-9;

  x_ix = first_larger_knotvalue_ix(m, XFIXED, u);
  y_ix = first_larger_knotvalue_ix(m, YFIXED, v);
  
  // adjustment of index if positioned _exactly_ at upper bound of grid
  if ((x_ix == m.numDistinctKnots(XFIXED) - 1) && (fabs(u-m.maxParam(XFIXED) < tol)))
    --x_ix;
  if ((y_ix == m.numDistinctKnots(YFIXED) - 1) && (fabs(v-m.maxParam(YFIXED) < tol)))
    --y_ix;

  // checking if a valid corner was found
  if (x_ix == 0 || x_ix >= m.numDistinctKnots(XFIXED)) return false; // u outside domain
  if (y_ix == 0 || y_ix >= m.numDistinctKnots(YFIXED)) return false; // v outside domain

  // We have now found the largest smaller knot in the u and v direction.  From here we
  // can search downwards to the lower-left corner of the containing mesh element, which
  // defines the sought-for "patch" of the surface.

  x_ix = search_upwards_for_nonzero_multiplicity(m, XFIXED, x_ix, y_ix);
  y_ix = search_upwards_for_nonzero_multiplicity(m, YFIXED, y_ix, x_ix);

  return true;
}
示例#3
0
// =============================================================================
int Mesh2DUtils::last_nonlarger_knotvalue_ix(const Mesh2D&m, Direction2D d, 
					     double par)
// =============================================================================
{
  const double* a = m.knotsBegin(d);
  const double* b = m.knotsEnd(d);
  
  double tol = 1.0e-8;
  // if (par < a[0] && par >= a[0]-tol)
  //   par = a[0];
  // if (par > b[-1] && par <= b[-1]+tol)
  //   par = b[-1];

  // searching for last nonlarger knotvalue using bisection
  for (int diff = (b-a)/2; diff != 0; diff = (b-a)/2) {
    if (par < a[0]+tol && par >= a[0]-tol)
      par = a[0];
    if (par > b[-1]-tol && par <= b[-1]+tol)
      par = b[-1];
    const double* mid = a + diff;
    ( (*mid > par) ? b : a) = mid;
  }

  if (b == m.knotsEnd(d))
    --b;
  if (fabs(par-b[0]) < tol && fabs(par-a[0]) > tol)
    return (b - m.knotsBegin(d));
  else
    return (a - m.knotsBegin(d)); // if index becomes negative, it signalizes that 'par' 
                                // is smaller than even the first knot value
}
示例#4
0
//==============================================================================
int Mesh2DUtils::search_upwards_for_nonzero_multiplicity(const Mesh2D& m, 
							 Direction2D d, 
							 int start_ix, int other_ix)
//==============================================================================
{
  // provided that the mesh is a valid LR mesh, a valid index should always be found.
  int ix;
  for (ix = start_ix; ix != m.numDistinctKnots(d) && m.nu(d, ix, other_ix - 1, other_ix) == 0; ++ix);
  return ix;  // @@ not yet tested!
}
示例#5
0
// =============================================================================
  int Mesh2DUtils::first_larger_knotvalue_ix(const Mesh2D& m, Direction2D d, 
					     double par)
// =============================================================================
{
  int ix = last_nonlarger_knotvalue_ix(m, d, par);
  if (ix < m.numDistinctKnots(d)-1)
    ix++;
  return  ix; 
}
示例#6
0
// =============================================================================
int Mesh2DUtils::search_downwards_for_nonzero_multiplicity(const Mesh2D& m, 
							   Direction2D d, 
							   int start_ix, int other_ix)
// =============================================================================
{
  // provided that the mesh is a valid LR mesh, a valid index should always be found.
  int ix;
  for (ix = start_ix; ix != 0 && m.nu(d, ix, other_ix, other_ix + 1) == 0; --ix);
  return ix;
}
示例#7
0
// Derive the knotvector resulting from moving along the u-direction (if d == XFIXED) or
// v-direction (if d == YFIXED) from 'beg' to 'end', and  with multiplicities equal to
// the 'nu' value of the segment in the ortogonal direction, starting at 'orto_min' and
// extending to 'orto_max'.
//------------------------------------------------------------------------------
vector<int>
LRBSpline2DUtils::derive_knots(const Mesh2D& m, Direction2D d, int beg, int end,
                               int orto_min, int orto_max)
//------------------------------------------------------------------------------
{
    vector<int> result;
    for (int pos = beg; pos <= end; ++pos)
        result.insert(result.end(), m.nu(d, pos, orto_min, orto_max), pos); // 0 multiplicities will not be inserted

    return result;
}
示例#8
0
//==============================================================================
// if 'b' can be split at least once in the mesh 'm', split it once, and return the
// result through 'b1' and 'b2'.  The function never carries out more than one split,
// even when several splits are possible.
bool LRBSpline2DUtils::try_split_once(const LRBSpline2D& b, const Mesh2D& mesh,
                                      LRBSpline2D*& b1,
                                      LRBSpline2D*& b2)
//==============================================================================
{
    const int umin = b.suppMin(XFIXED);
    const int vmin = b.suppMin(YFIXED);
    const int umax = b.suppMax(XFIXED);
    const int vmax = b.suppMax(YFIXED);
    const vector<int> m_kvec_u = derive_knots(mesh, XFIXED, umin, umax, vmin, vmax);
    const vector<int> m_kvec_v = derive_knots(mesh, YFIXED, vmin, vmax, umin, umax);

    // @@ The assertions below should always hold if function is called with correct
    // argument. When code is properly debugged and tested, they can be taken away for
    // efficiency (asserts should go away anyway when compiling in optimized mode).
    // Alternatively, if it is a concern that users might call this function with wrong
    // argument, the assertions could be replaced by exception-throwing 'if'-statements.
    assert(std::includes(m_kvec_u.begin(), m_kvec_u.end(), b.kvec(XFIXED).begin(), b.kvec(XFIXED).end()));
    assert(std::includes(m_kvec_v.begin(), m_kvec_v.end(), b.kvec(YFIXED).begin(), b.kvec(YFIXED).end()));

    if (num_inner_knots(m_kvec_u) > num_inner_knots(b.kvec(XFIXED))) {
        // Since we know that m_kvec_u contains more elements than b.kvec(XFIXED) and since
        // we know that the latter is included in the former, we know that there must be at least
        // one knot in 'm_kvec_u' that is not found in b.kvec(XFIXED).  We can therefore call
        // the following function without risking an exception to be thrown.
        const int new_ix = find_uncovered_inner_knot(m_kvec_u, b.kvec(XFIXED));

        // @@@ VSK. Cannot set pointers to the new bsplines before it is placed in the
        // global array. Will the position of the element change when a bspline is removed?
        split_function(b, mesh, XFIXED, mesh.knotsBegin(XFIXED), new_ix, b1, b2);
        return true;

    } else if (num_inner_knots(m_kvec_v) > num_inner_knots(b.kvec(YFIXED))) {
        // same comment as above
        const int new_ix = find_uncovered_inner_knot(m_kvec_v, b.kvec(YFIXED));
        split_function(b, mesh, YFIXED, mesh.knotsBegin(YFIXED), new_ix, b1, b2);
        return true;
    }
    // No splits possible
    return false;
}
void Engine2D::CreateInitialState(Mesh2D &mesh)
{
	vector<vector<tuple<double, double>>> instance_container;
	for (int i = 0; i < (mesh.spacial_length / mesh.spacial_step_size); i++)
	{
		this->current_configuration.push_back(std::make_tuple(mesh.all_node_locations.front(), mesh.left_side_boundary_conditions.at(0))); //Put the first I.C in.
		for (float j = 1; j <= mesh.number_of_nodes - 1; ++j) // Iterate over the nodes which are not boundary conditions. (starts at node 1 and stops at # of nodes-1
		{
			this->current_configuration.push_back(std::make_tuple(mesh.all_node_locations.at(j), mesh.InitialDistribution(0)));
		}
		this->current_configuration.push_back(std::make_tuple(mesh.all_node_locations.back(), mesh.right_side_boundary_conditions.at(0))); // Once filled, set the last B.C.
		Instance.push_back(current_configuration);
		this->current_configuration.clear(); // Clear the current state
	}

	this->Results.push_back(Instance); // Add to the vector of states
	Instance.clear();

}