예제 #1
0
void
PolycrystalReducedIC::initialSetup()
{
 //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  MooseRandom::seed(_rand_seed);

  //Randomly generate the centers of the individual grains represented by the Voronoi tesselation
  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);
  std::vector<Real> distances(_grain_num);

  //Assign actual center point positions
  for (unsigned int grain = 0; grain < _grain_num; grain++)
  {
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
      _centerpoints[grain](i) = _bottom_left(i) + _range(i) * MooseRandom::rand();
    if (_columnar_3D)
      _centerpoints[grain](2) = _bottom_left(2) + _range(2) * 0.5;
  }

  //Assign grains to specific order parameters in a way that maximizes the distance
  _assigned_op = PolycrystalICTools::assignPointsToVariables(_centerpoints, _op_num, _mesh, _var);
}
예제 #2
0
Real
RndBoundingBoxIC::value(const Point & p)
{
    //Random number between 0 and 1
    Real rand_num = MooseRandom::rand();

    for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
        if (p(i) < _bottom_left(i) || p(i) > _top_right(i))
            return rand_num * _range_outvalue + _mn_outvalue;

    return rand_num * _range_invalue + _mn_invalue;
}
예제 #3
0
void
BimodalSuperellipsoidsIC::initialSetup()
{
  // Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_size_variation_type == 2 && _size_variation > 0.0)
    mooseError("If size_variation > 0.0, you must pass in a size_variation_type in "
               "BimodalSuperellipsoidsIC");

  SmoothSuperellipsoidBaseIC::initialSetup();
}
예제 #4
0
void
LatticeSmoothCircleIC::initialSetup()
{
  // pad circles per side vector to size 3 (with 0)
  _circles_per_side.resize(3);

  //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  //Error checks
  if (_range(0) != 0.0 && _range(1) != 0.0 && _circles_per_side[1] == 0)
    mooseError("If domain is > 1D, circles_per_side must have more than one value");

  if (_range(2) != 0.0 && _circles_per_side[2] == 0)
    mooseError("If domain is 3D, circles_per_side must have three values");

  if (_range(1) == 0.0 && _range(2) == 0.0)
  {
    _circles_per_side[1] = 0;
    _circles_per_side[2] = 0;
  }

  //Set _numbub
  if (_range(2) == 0.0)
  {
    _circles_per_side[2] = 0;
    _numbub = _circles_per_side[0] * _circles_per_side[1];
  }
  else
    _numbub = _circles_per_side[0] * _circles_per_side[1] * _circles_per_side[2];

  switch (_radius_variation_type)
  {
    case 2: //No variation
      if (_radius_variation > 0.0)
        mooseError("If radius_variation > 0.0, you must pass in a radius_variation_type in LatticeSmoothCircleIC");
      break;
  }
  SmoothCircleBaseIC::initialSetup();
}
예제 #5
0
void
MultiSmoothCircleIC::initialSetup()
{
  // Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  // a variation is provided, but the type is set to 'none'
  if (_radius_variation > 0.0 && _radius_variation_type == 2)
    mooseError("If radius_variation > 0.0, you must pass in a radius_variation_type in "
               "MultiSmoothCircleIC");

  SmoothCircleBaseIC::initialSetup();
}
예제 #6
0
Tricrystal2CircleGrainsIC::Tricrystal2CircleGrainsIC(const std::string & name,
        InputParameters parameters) :
    InitialCondition(name, parameters),
    _mesh(_fe_problem.mesh()),
    _nl(_fe_problem.getNonlinearSystem()),
    _op_num(getParam<unsigned int>("op_num")),
    _op_index(getParam<unsigned int>("op_index"))
{
    if (_op_num != 3)
        mooseError("Tricrystal ICs must have op_num = 3");

    //Set up domain bounds with mesh tools
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
        _bottom_left(i) = _mesh.getMinInDimension(i);
        _top_right(i) = _mesh.getMaxInDimension(i);
    }
    _range = _top_right - _bottom_left;
}
예제 #7
0
Real
PFCFreezingIC::value(const Point & p)
{
  // If out of bounds, set random value
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    if (p(i) < _bottom_left(i) || p(i) > _top_right(i))
      return _min + _val_range * MooseRandom::rand();

  // If in bounds, set sinusoid IC to make atoms
  Real val = 0.0;
  if (_crystal_structure == "FCC")
  {
    // Note: this effectively (and now explicitly) returns 0.0 for FCC.
    return 0.0;

    for (unsigned int i = 0; i < _icdim; i++)
      val += std::cos((2.0 / _lc * p(i)) * libMesh::pi);
  }
  else
  {
    if (_icdim > 2)
    {
      for (unsigned int i = 0; i < _icdim; i++)
        // one mode approximation for initial condition
        val += (std::cos((2.0 / _lc * p(i % 3)) * libMesh::pi) *
                std::cos((2.0 / _lc * p((i + 1) % 3)) * libMesh::pi)) /
               4.0; // Doesn't work in 2D
    }
    else
    {
      for (unsigned int i = 0; i < _icdim; i++)
        val *= std::cos((2.0 / _lc * p(i)) * libMesh::pi); // 2D IC for 111 plane

      val = val / 2.0 + 0.5;
    }
  }

  Real amp = _inside - _outside;
  val = amp * val + _outside;

  return val;
}
예제 #8
0
void
MultiSmoothCircleIC::initialSetup()
{

  //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  switch (_radius_variation_type)
  {
  case 2: //No variation
    if (_radius_variation > 0.0)
      mooseError("If radius_variation > 0.0, you must pass in a radius_variation_type in MultiSmoothCircleIC");
    break;
  }

  SmoothCircleBaseIC::initialSetup();
}
void
MultiSmoothSuperellipsoidIC::initialSetup()
{
  unsigned int nv = _numbub.size();

  if (nv != _bubspac.size() || nv != _exponent.size() || nv != _semiaxis_a.size() ||
      nv != _semiaxis_b.size() || nv != _semiaxis_c.size())
    mooseError("Vectors for numbub, bubspac, exponent, semiaxis_a, semiaxis_b, and semiaxis_c must "
               "be the same size.");

  if (_semiaxis_variation_type != 2 &&
      (nv != _semiaxis_a_variation.size() || nv != _semiaxis_b_variation.size() ||
       nv != _semiaxis_c_variation.size()))
    mooseError("Vectors for numbub, semiaxis_a_variation, semiaxis_b_variation, and "
               "semiaxis_c_variation must be the same size.");

  if (_semiaxis_variation_type == 2 &&
      (_semiaxis_a_variation.size() > 0 || _semiaxis_b_variation.size() > 0 ||
       _semiaxis_c_variation.size() > 0))
    mooseWarning(
        "Values were provided for semiaxis_a/b/c_variation but semiaxis_variation_type is set "
        "to 'none' in 'MultiSmoothSuperellipsoidIC'.");

  for (_gk = 0; _gk < nv; ++_gk)
  {
    // Set up domain bounds with mesh tools
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
      _bottom_left(i) = _mesh.getMinInDimension(i);
      _top_right(i) = _mesh.getMaxInDimension(i);
    }
    _range = _top_right - _bottom_left;

    SmoothSuperellipsoidBaseIC::initialSetup();
  }
}
예제 #10
0
Real
PolycrystalReducedIC::value(const Point & p)
{
  // Assumption: We are going to assume that all variables are periodic together
  // _mesh.initPeriodicDistanceForVariable(_nl, _var.number());

  Real min_distance = _top_right(0)*1e5;
  Real val = 0.0;
  unsigned int min_index = _grain_num + 100;
  //Loops through all of the grain centers and finds the center that is closest to the point p
  for (unsigned int grain = 0; grain < _grain_num; grain++)
  {
    Real distance = _mesh.minPeriodicDistance(_var.number(), _centerpoints[grain], p);

    if (min_distance > distance)
    {
      min_distance = distance;
      min_index = grain;
    }
  }

  if (min_index > _grain_num)
    mooseError("ERROR in PolycrystalReducedIC: didn't find minimum values");

  //If the current order parameter index (_op_index) is equal to the min_index, set the value to 1.0
  if (_assigned_op[min_index] == _op_index) //Make sure that the _op_index goes from 0 to _op_num-1
    val = 1.0;

  if (val > 1.0)
    val = 1.0;

  if (val < 0.0)
    val = 0.0;

  return val;
}
예제 #11
0
void
PolycrystalReducedIC::initialSetup()
{
 //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  MooseRandom::seed(_rand_seed);

  //Randomly generate the centers of the individual grains represented by the Voronoi tesselation
  _centerpoints.resize(_grain_num);
  std::vector<Real> distances(_grain_num);

  for (unsigned int grain = 0; grain < _grain_num; grain++)
  {
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
      _centerpoints[grain](i) = _bottom_left(i) + _range(i) * MooseRandom::rand();
    if (_columnar_3D)
      _centerpoints[grain](2) = _bottom_left(2) + _range(2) * 0.5;
  }

  if (!_advanced_op_assignment)
    //Assign grains to specific order parameters in a way that maximizes the distance
    _assigned_op = PolycrystalICTools::assignPointsToVariables(_centerpoints, _op_num, _mesh, _var);
  else
  {
    std::map<dof_id_type, unsigned int> entity_to_grain;

    // TODO: Add a nodal option
    if (false)
    {
      /**
       * We first need to build a node to grain map (i.e. every node in the mesh needs to say
       * which grain it belongs to). For Voronoi, this is straightforward and we have a utility
       * already setup to handle this case.
       */
      const MeshBase::node_iterator end = _mesh.getMesh().active_nodes_end();
      for (MeshBase::node_iterator nl = _mesh.getMesh().active_nodes_begin(); nl != end; ++nl)
      {
        unsigned int grain_index = PolycrystalICTools::assignPointToGrain(**nl, _centerpoints, _mesh, _var, _range.norm());

        entity_to_grain.insert(std::pair<dof_id_type, unsigned int>((*nl)->id(), grain_index));
      }
    }
    else
    {
      const MeshBase::element_iterator end = _mesh.getMesh().active_elements_end();
      for (MeshBase::element_iterator el = _mesh.getMesh().active_elements_begin(); el != end; ++el)
      {
        Point centroid = (*el)->centroid();

        unsigned int grain_index = PolycrystalICTools::assignPointToGrain(centroid, _centerpoints, _mesh, _var, _range.norm());

        entity_to_grain.insert(std::pair<dof_id_type, unsigned int>((*el)->id(), grain_index));
      }
    }

    /**
     * Now we need to construct a neighbor graph using our node to grain map information.
     * We have a utility for this too. This one makes no assumptions about how the
     * grain structure was built. It uses the entity_to_grain map.
     */
    AdjacencyGraph grain_neighbor_graph = PolycrystalICTools::buildGrainAdjacencyGraph(entity_to_grain, _mesh, _grain_num, true);

    /**
     * Now we need to assign ops in some optimal fashion.
     */
    _assigned_op = PolycrystalICTools::assignOpsToGrains(grain_neighbor_graph, _grain_num, _op_num);
  }
}
예제 #12
0
void
PolycrystalReducedIC::initialSetup()
{
 //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  if (_cody_test)
    if (_op_num != 5 || _grain_num != 10)
      mooseError("ERROR in PolycrystalReducedIC: Numbers aren't correct for Cody's test.");

  MooseRandom::seed(_rand_seed);

  //Randomly generate the centers of the individual grains represented by the Voronoi tesselation
  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);
  std::vector<Real> distances(_grain_num);


  std::vector<Point> holder;

  if (_cody_test)
  {
    holder.resize(_grain_num);
    holder[0] = Point(0.2, 0.85, 0.0);
    holder[1] = Point(0.5, 0.85, 0.0);
    holder[2] = Point(0.8, 0.85, 0.0);

    holder[3] = Point(0.2, 0.5, 0.0);
    holder[4] = Point(0.5, 0.5, 0.0);
    holder[5] = Point(0.8, 0.5, 0.0);

    holder[6] = Point(0.1, 0.1, 0.0);
    holder[7] = Point(0.5, 0.05, 0.0);
    holder[8] = Point(0.9, 0.1, 0.0);

    holder[9] = Point(0.5, 0.1, 0.0);
  }

  //Assign actual center point positions
  for (unsigned int grain = 0; grain < _grain_num; grain++)
  {
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
      if (_cody_test)
        _centerpoints[grain](i) = _bottom_left(i) + _range(i)*holder[grain](i);
      else
        _centerpoints[grain](i) = _bottom_left(i) + _range(i)*MooseRandom::rand();
    }
    if (_columnar_3D)
        _centerpoints[grain](2) = _bottom_left(2) + _range(2)*0.5;
  }

  //Assign grains to each order parameter
  if (_cody_test)
  {
    _assigned_op[0] = 0.0;
    _assigned_op[1] = 0.0;
    _assigned_op[2] = 0.0;
    _assigned_op[3] = 1.0;
    _assigned_op[4] = 1.0;
    _assigned_op[5] = 1.0;
    _assigned_op[6] = 2.0;
    _assigned_op[7] = 3.0;
    _assigned_op[8] = 2.0;
    _assigned_op[9] = 4.0;
  }
  else
  {
    for (unsigned int grain = 0; grain < _grain_num; grain++) //Assign grains to specific order parameters in a way that maximized the distance
    {
      std::vector<int> min_op_ind;
      std::vector<Real> min_op_dist;
      min_op_ind.resize(_op_num);
      min_op_dist.resize(_op_num);
      //Determine the distance to the closest center assigned to each order parameter
      if (grain >= _op_num)
      {
        std::fill(min_op_dist.begin() , min_op_dist.end(), _range.size());
        for (unsigned int i = 0; i < grain; i++)
        {
          Real dist = _mesh.minPeriodicDistance(_var.number(), _centerpoints[grain], _centerpoints[i]);
          if (min_op_dist[_assigned_op[i]] > dist)
          {
            min_op_dist[_assigned_op[i]] = dist;
            min_op_ind[_assigned_op[i]] = i;
          }
        }
      }

      //Assign the current center point to the order parameter that is furthest away.
      Real mx;
      if (grain < _op_num)
        _assigned_op[grain] = grain;
      else
      {
        mx = 0.0;
        unsigned int mx_ind = 1e6;
        for (unsigned int i = 0; i < _op_num; i++) //Find index of max
          if (mx < min_op_dist[i])
          {
            mx = min_op_dist[i];
            mx_ind = i;
          }

        _assigned_op[grain] = mx_ind;
      }
      //Moose::out << "For grain " << grain << ", center point = " << _centerpoints[grain](0) << " " << _centerpoints[grain](1) << "\n";
      //Moose::out << "Max index is " << _assigned_op[grain] << ", with a max distance of " << mx << "\n";
    }
  }
}
예제 #13
0
void
PolycrystalReducedIC::initialSetup()
{
 //Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  if (_cody_test)
    if (_op_num != 5 || _grain_num != 10)
      mooseError("ERROR in PolycrystalReducedIC: Numbers aren't correct for Cody's test.");

  MooseRandom::seed(_rand_seed);

  //Randomly generate the centers of the individual grains represented by the Voronoi tesselation
  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);
  std::vector<Real> distances(_grain_num);

  std::vector<Point> holder;

  if (_cody_test)
  {
    holder.resize(_grain_num);
    holder[0] = Point(0.2, 0.99, 0.0);
    holder[1] = Point(0.5, 0.99, 0.0);
    holder[2] = Point(0.8, 0.99, 0.0);

    holder[3] = Point(0.2, 0.5, 0.0);
    holder[4] = Point(0.5, 0.5, 0.0);
    holder[5] = Point(0.8, 0.5, 0.0);

    holder[6] = Point(0.1, 0.1, 0.0);
    holder[7] = Point(0.5, 0.05, 0.0);
    holder[8] = Point(0.9, 0.1, 0.0);

    holder[9] = Point(0.5, 0.1, 0.0);
  }

  //Assign actual center point positions
  for (unsigned int grain = 0; grain < _grain_num; grain++)
  {
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
      if (_cody_test)
        _centerpoints[grain](i) = _bottom_left(i) + _range(i)*holder[grain](i);
      else
        _centerpoints[grain](i) = _bottom_left(i) + _range(i)*MooseRandom::rand();
    }
    if (_columnar_3D)
        _centerpoints[grain](2) = _bottom_left(2) + _range(2)*0.5;
  }

  //Assign grains to each order parameter
  if (_cody_test)
  {
    _assigned_op[0] = 0.0;
    _assigned_op[1] = 0.0;
    _assigned_op[2] = 0.0;
    _assigned_op[3] = 1.0;
    _assigned_op[4] = 1.0;
    _assigned_op[5] = 1.0;
    _assigned_op[6] = 2.0;
    _assigned_op[7] = 0.0;
    _assigned_op[8] = 2.0;
    _assigned_op[9] = 4.0;
  }
  else
    //Assign grains to specific order parameters in a way that maximizes the distance
    _assigned_op = PolycrystalICTools::assignPointsToVariables(_centerpoints,_op_num, _mesh, _var);
}
예제 #14
0
void
HexPolycrystalIC::initialSetup()
{
  MooseRandom::seed(_rand_seed);

  unsigned int root = std::floor(std::pow(_grain_num, 1.0/_mesh.dimension()));

  if (_grain_num != std::pow((float)root, (float)_mesh.dimension()))
  {
    root++;  // Try "ceiling due to round off error
    if (_grain_num != std::pow((float)root, (float)_mesh.dimension()))
      mooseError("HexPolycrystalIC requires a square or cubic number depending on the mesh dimension");
  }

  unsigned int third_dimension_iterations = _mesh.dimension() == 3 ? root : 1;
  Real ndist = 1.0/root;

  // Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);
  std::vector<Real> distances(_grain_num);

  std::vector<Point> holder(_grain_num);

  unsigned int count = 0;
  // Assign the relative center points positions, defining the grains according to a hexagonal pattern
  for (unsigned int k = 0; k < third_dimension_iterations; ++k)
    for (unsigned int j = 0; j < root; ++j)
      for (unsigned int i = 0; i < root; ++i)
      {
        // set x-coordinate
        holder[count](0) = i*ndist + (0.5*ndist*(j%2)) + _x_offset*ndist;

        // set y-coordinate
        holder[count](1) = j*ndist + (0.5*ndist*(k%2));

        // set z-coordinate
        holder[count](2) = k*ndist;

        //increment counter
        count++;
      }

  // Assign center point values
  for (unsigned int grain=0; grain < _grain_num; grain++)
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
      if (_range(i) == 0)
        continue;

      Real perturbation_dist = (_range(i)/root * (MooseRandom::rand()*2 - 1.0)) * _perturbation_percent;  // Perturb -100 to 100%
      _centerpoints[grain](i) = _bottom_left(i) + _range(i)*holder[grain](i) + perturbation_dist;

      if (_centerpoints[grain](i) > _top_right(i))
        _centerpoints[grain](i) = _top_right(i);
      if (_centerpoints[grain](i) < _bottom_left(i))
        _centerpoints[grain](i) = _bottom_left(i);
    }

  //Assign grains to specific order parameters in a way that maximizes the distance
  _assigned_op = PolycrystalICTools::assignPointsToVariables(_centerpoints,_op_num, _mesh, _var);
}
예제 #15
0
void Proc3DSCropper::sort_rotate() {
    float min_x = FLT_MAX, min_y = FLT_MAX, max_x = 0, max_y = 0;
    for(const cv::Point2f& p: this->poses) {
        if(p.x < min_x) min_x = p.x;
        if(p.x > max_x) max_x = p.x;
        if(p.y < min_y) min_y = p.y;
        if(p.y > max_y) max_y = p.y;
    }
    cv::Point2f _bot_left(min_x, max_y), _bot_right(max_x, max_y), _top_left(min_x, min_y), _top_right(max_x, min_y);
    cv::Point2f bot_left, bot_right, top_left, top_right;
    double norm_bot_left = DBL_MAX, norm_bot_right = DBL_MAX, norm_top_left = DBL_MAX, norm_top_right = DBL_MAX;
    for(const cv::Point2f& p: this->poses) {
        if(cv::norm(_bot_left - p) < norm_bot_left) {
            norm_bot_left = cv::norm(_bot_left - p);
            bot_left = p;
        }
        if(cv::norm(_bot_right - p) < norm_bot_right) {
            norm_bot_right = cv::norm(_bot_right - p);
            bot_right = p;
        }
        if(cv::norm(_top_left - p) < norm_top_left) {
            norm_top_left = cv::norm(_top_left - p);
            top_left = p;
        }
        if(cv::norm(_top_right - p) < norm_top_right) {
            norm_top_right = cv::norm(_top_right - p);
            top_right = p;
        }
    }
    this->corners.clear();
    this->corners.push_back(bot_right);
    this->corners.push_back(top_right);
    this->corners.push_back(top_left);
    this->corners.push_back(bot_left);
    std::cout << bot_right << ", " << top_right << ", " << ", " << top_left << ", " << bot_left << std::endl;
};
예제 #16
0
void
HexPolycrystalIC::initialSetup()
{
  MooseRandom::seed(_rand_seed);

  unsigned int root = std::floor(std::pow(_grain_num, 1.0/_mesh.dimension()));

  if (_grain_num != std::pow((float)root, (float)_mesh.dimension()))
  {
    root++;  // Try "ceiling due to round off error
    if (_grain_num != std::pow((float)root, (float)_mesh.dimension()))
      mooseError("HexPolycrystalIC requires a square or cubic number depending on the mesh dimension");
  }

  unsigned int third_dimension_iterations = _mesh.dimension() == 3 ? root : 1;
  Real ndist = 1.0/root;

  // Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
     mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger than the number of grains (grain_num)");

  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);
  std::vector<Real> distances(_grain_num);

  std::vector<Point> holder(_grain_num);

  unsigned int count = 0;
  // Assign the relative center points positions, defining the grains according to a hexagonal pattern
  for (unsigned int k = 0; k < third_dimension_iterations; ++k)
    for (unsigned int j = 0; j < root; ++j)
      for (unsigned int i = 0; i < root; ++i)
      {
        // set x-coordinate
        holder[count](0) = i*ndist + (0.5*ndist*(j%2)) + _x_offset*ndist;

        // set y-coordinate
        holder[count](1) = j*ndist + (0.5*ndist*(k%2));

        // set z-coordinate
        holder[count](2) = k*ndist;

        //increment counter
        count++;
      }

  // Assign center point values
  for (unsigned int grain=0; grain < _grain_num; grain++)
    for (unsigned int i = 0; i < LIBMESH_DIM; i++)
    {
      if (_range(i) == 0)
        continue;

      Real perturbation_dist = (_range(i)/root * (MooseRandom::rand()*2 - 1.0)) * _perturbation_percent;  // Perturb -100 to 100%
      _centerpoints[grain](i) = _bottom_left(i) + _range(i)*holder[grain](i) + perturbation_dist;

      if (_centerpoints[grain](i) > _top_right(i))
        _centerpoints[grain](i) = _top_right(i);
      if (_centerpoints[grain](i) < _bottom_left(i))
        _centerpoints[grain](i) = _bottom_left(i);
    }

  for (unsigned int grain = 0; grain < _grain_num; grain++) //Assign grains to specific order parameters in a way that maximized the distance
  {
    std::vector<int> min_op_ind;
    std::vector<Real> min_op_dist;
    min_op_ind.resize(_op_num);
    min_op_dist.resize(_op_num);
    //Determine the distance to the closest center assigned to each order parameter
    if (grain >= _op_num)
    {
      std::fill(min_op_dist.begin() , min_op_dist.end(), _range.size());
      for (unsigned int i = 0; i < grain; i++)
      {
        Real dist =  _mesh.minPeriodicDistance(_var.number(), _centerpoints[grain], _centerpoints[i]);
        if (min_op_dist[_assigned_op[i]] > dist)
        {
          min_op_dist[_assigned_op[i]] = dist;
          min_op_ind[_assigned_op[i]] = i;
        }
      }
    }

    // Assign the current center point to the order parameter that is furthest away.
    Real mx;
    if (grain < _op_num)
      _assigned_op[grain] = grain;
    else
    {
      mx = 0.0;
      unsigned int mx_ind = 1e6;
      for (unsigned int i = 0; i < _op_num; i++) //Find index of max
        if (mx < min_op_dist[i])
        {
          mx = min_op_dist[i];
          mx_ind = i;
        }
      _assigned_op[grain] = mx_ind;
    }

    //Moose::out << "For grain " << grain << ", center point = " << _centerpoints[grain](0) << " " << _centerpoints[grain](1) << "\n";
    //Moose::out << "Max index is " << _assigned_op[grain] << ", with a max distance of " << mx << "\n";
  }
}
예제 #17
0
void
PolycrystalVoronoiVoidIC::computeCircleCenters()
{
  _centers.resize(_numbub);

  // This Code will place void center points on grain boundaries
  for (unsigned int vp = 0; vp < _numbub; ++vp)
  {
    bool try_again;
    unsigned int num_tries = 0;

    do
    {
      try_again = false;
      num_tries++;

      if (num_tries > _max_num_tries)
        mooseError("Too many tries of assigning void centers in "
                   "PolycrystalVoronoiVoidIC");

      Point rand_point;

      for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
        rand_point(i) = _bottom_left(i) + _range(i) * _random.rand(_tid);

      // Allow the vectors to be sorted based on their distance from the
      // rand_point
      std::vector<PolycrystalVoronoiVoidIC::DistancePoint> diff(_grain_num);

      for (unsigned int gr = 0; gr < _grain_num; ++gr)
      {
        diff[gr].d = _mesh.minPeriodicDistance(_var.number(), rand_point, _centerpoints[gr]);
        diff[gr].gr = gr;
      }

      std::sort(diff.begin(), diff.end(), _customLess);

      Point closest_point = _centerpoints[diff[0].gr];
      Point next_closest_point = _centerpoints[diff[1].gr];

      // Find Slope of Line in the plane orthogonal to the diff_centerpoint
      // vector
      Point diff_centerpoints =
          _mesh.minPeriodicVector(_var.number(), closest_point, next_closest_point);
      Point diff_rand_center = _mesh.minPeriodicVector(_var.number(), closest_point, rand_point);
      Point normal_vector = diff_centerpoints.cross(diff_rand_center);
      Point slope = normal_vector.cross(diff_centerpoints);

      // Midpoint position vector between two center points
      Point midpoint = closest_point + (0.5 * diff_centerpoints);

      // Solve for the scalar multiplier solution on the line
      Real lambda = 0;
      Point mid_rand_vector = _mesh.minPeriodicVector(_var.number(), midpoint, rand_point);

      Real slope_dot = slope * slope;
      mooseAssert(slope_dot > 0, "The dot product of slope with itself is zero");
      for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
        lambda += (mid_rand_vector(i) * slope(i)) / slope_dot;

      // Assigning points to vector
      _centers[vp] = slope * lambda + midpoint;

      // Checking to see if points are in the domain ONLY WORKS FOR PERIODIC
      for (unsigned int i = 0; i < LIBMESH_DIM; i++)
        if ((_centers[vp](i) > _top_right(i)) || (_centers[vp](i) < _bottom_left(i)))
          try_again = true;

      for (unsigned int i = 0; i < vp; ++i)
      {
        Real dist = _mesh.minPeriodicDistance(_var.number(), _centers[vp], _centers[i]);

        if (dist < _bubspac)
          try_again = true;
      }

      // Two algorithms are available for screening bubbles falling in grain
      // interior. They produce
      // nearly identical results.
      // Here only one is listed. The other one is available upon request.

      // Use circle center for checking whether voids are at GBs
      if (try_again == false)
      {
        Real min_rij_1, min_rij_2, rij, rij_diff_tol;

        min_rij_1 = _range.norm();
        min_rij_2 = _range.norm();

        rij_diff_tol = 0.1 * _radius;

        for (unsigned int gr = 0; gr < _grain_num; ++gr)
        {
          rij = _mesh.minPeriodicDistance(_var.number(), _centers[vp], _centerpoints[gr]);

          if (rij < min_rij_1)
          {
            min_rij_2 = min_rij_1;
            min_rij_1 = rij;
          }
          else if (rij < min_rij_2)
            min_rij_2 = rij;
        }

        if (std::abs(min_rij_1 - min_rij_2) > rij_diff_tol)
          try_again = true;
      }

    } while (try_again == true);
  }
}
예제 #18
0
void
HexPolycrystalIC::initialSetup()
{
  const unsigned int root = MathUtils::round(std::pow(_grain_num, 1.0 / _dim));

  // integer power the rounded root and check if we recover the grain number
  unsigned int grain_pow = root;
  for (unsigned int i = 1; i < _dim; ++i)
    grain_pow *= root;

  if (_grain_num != grain_pow)
    mooseError(
        "HexPolycrystalIC requires a square or cubic number depending on the mesh dimension");

  // Set up domain bounds with mesh tools
  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
  {
    _bottom_left(i) = _mesh.getMinInDimension(i);
    _top_right(i) = _mesh.getMaxInDimension(i);
  }
  _range = _top_right - _bottom_left;

  if (_op_num > _grain_num)
    mooseError("ERROR in PolycrystalReducedIC: Number of order parameters (op_num) can't be larger "
               "than the number of grains (grain_num)");

  _centerpoints.resize(_grain_num);
  _assigned_op.resize(_grain_num);

  std::vector<Real> distances(_grain_num);
  std::vector<Point> holder(_grain_num);

  const Real ndist = 1.0 / root;

  // Assign the relative center points positions, defining the grains according to a hexagonal
  // pattern
  unsigned int count = 0;
  for (unsigned int k = 0; k < (_dim == 3 ? root : 1); ++k)
    for (unsigned int j = 0; j < (_dim >= 2 ? root : 1); ++j)
      for (unsigned int i = 0; i < root; ++i)
      {
        // set x-coordinate
        holder[count](0) = i * ndist + (0.5 * ndist * (j % 2)) + _x_offset * ndist;

        // set y-coordinate
        holder[count](1) = j * ndist + (0.5 * ndist * (k % 2));

        // set z-coordinate
        holder[count](2) = k * ndist;

        // increment counter
        count++;
      }

  // Assign center point values
  for (unsigned int grain = 0; grain < _grain_num; ++grain)
    for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
    {
      if (_range(i) == 0)
        continue;

      Real perturbation_dist = (_range(i) / root * (_random.rand(_tid) * 2 - 1.0)) *
                               _perturbation_percent; // Perturb -100 to 100%
      _centerpoints[grain](i) = _bottom_left(i) + _range(i) * holder[grain](i) + perturbation_dist;

      if (_centerpoints[grain](i) > _top_right(i))
        _centerpoints[grain](i) = _top_right(i);
      if (_centerpoints[grain](i) < _bottom_left(i))
        _centerpoints[grain](i) = _bottom_left(i);
    }

  // Assign grains to specific order parameters in a way that maximizes the distance
  _assigned_op = PolycrystalICTools::assignPointsToVariables(_centerpoints, _op_num, _mesh, _var);
}