Exemplo n.º 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);
}
Exemplo n.º 2
0
void
MultiSmoothCircleIC::computeCircleCenters()
{
  _centers.resize(_numbub);

  for (unsigned int i = 0; i < _numbub; i++)
  {
    //Vary circle center positions
    unsigned int num_tries = 0;

    Real rr = 0.0;
    Point newcenter = 0.0;

    while (rr < _bubspac && num_tries < _numtries)
    {
      num_tries++;
      //Moose::out<<"num_tries: "<<num_tries<<std::endl;

      Real ran1 = _random.rand(_tid);
      Real ran2 = _random.rand(_tid);
      Real ran3 = _random.rand(_tid);

      newcenter(0) = _bottom_left(0) + ran1*_range(0);
      newcenter(1) = _bottom_left(1) + ran2*_range(1);
      newcenter(2) = _bottom_left(2) + ran3*_range(2);

      for (unsigned int j = 0; j < i; j++)
      {
        if (j == 0) rr = _range.norm();

        Real tmp_rr = _mesh.minPeriodicDistance(_var.number(), _centers[j], newcenter);

        if (tmp_rr < rr) rr = tmp_rr;
      }

      if (i == 0) rr = _range.norm();
    }

    if (num_tries == _numtries)
      mooseError("Too many tries in MultiSmoothCircleIC");

    _centers[i] = newcenter;
  }
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
Real
TwoParticleGrainsIC::value(const Point & p)
{
  //_redius.resize(2);
  Real radius_left = 5.0; //_radius[0];
  Real radius_right = 5.0; //_radius[1];
  
  Point grain_center_left;
  grain_center_left(0) = _bottom_left(0) + _rangedomain(0)/2.0 - radius_left;
  grain_center_left(1) = _bottom_left(1) + _rangedomain(1)/2.0;
  grain_center_left(2) = _bottom_left(2) + _rangedomain(2)/2.0;

  Point grain_center_right;
  grain_center_right(0) = _bottom_left(0) + _rangedomain(0)/2.0 + radius_right;
  grain_center_right(1) = _bottom_left(1) + _rangedomain(1)/2.0;
  grain_center_right(2) = _bottom_left(2) + _rangedomain(2)/2.0;
  
  Real dist_left = (p - grain_center_left).size();
  Real dist_right = (p - grain_center_right).size();

  if ((dist_left <= radius_left && _op_index == 0) || (dist_right <= radius_right && _op_index == 1))
    return 1.0;
  else
    return 0.0;
}
Exemplo n.º 5
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();
}
Exemplo n.º 6
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();
}
Exemplo n.º 7
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();
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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();
}
Exemplo n.º 11
0
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();
  }
}
Exemplo n.º 12
0
Real
Tricrystal2CircleGrainsIC::value(const Point & p)
{
    Point grain_center_left;
    grain_center_left(0) = _bottom_left(0) + _range(0)/4.0;
    grain_center_left(1) = _bottom_left(1) + _range(1)/2.0;
    grain_center_left(2) = _bottom_left(2) + _range(2)/2.0;

    Point grain_center_right;
    grain_center_right(0) = _bottom_left(0) + _range(0)*3.0/4.0;
    grain_center_right(1) = _bottom_left(1) + _range(1)/2.0;
    grain_center_right(2) = _bottom_left(2) + _range(2)/2.0;

    Real radius = _range(0)/5.0;
    Real dist_left = (p - grain_center_left).size();
    Real dist_right = (p - grain_center_right).size();

    if ((dist_left <= radius && _op_index == 1) || (dist_right <= radius && _op_index == 2) || (dist_left > radius && dist_right > radius && _op_index == 0))
        return 1.0;
    else
        return 0.0;
}
Exemplo n.º 13
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);
}
Exemplo n.º 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);
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
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);
  }
}
Exemplo n.º 17
0
void
MultiSmoothParticleIC::computeCircleCenters()
{
  _centers.resize(_numbub);

  for (unsigned int i = 0; i < _numbub; i++)
  {
    //Vary circle center positions
    unsigned int num_tries = 0;

    Real rr = 0.0;
    Point newcenter = 0.0;

    while (rr < _bubspac && num_tries < _numtries)
    {
      num_tries++;
      //Moose::out<<"num_tries: "<<num_tries<<std::endl;

      Real ran1 = MooseRandom::rand();
      Real ran2 = MooseRandom::rand();
      Real ran3 = MooseRandom::rand();

      newcenter(0) = _bottom_left(0) + ran1*_range(0);
      newcenter(1) = _bottom_left(1) + ran2*_range(1);
      newcenter(2) = _bottom_left(2) + ran3*_range(2);

      for (unsigned int j = 0; j < i; j++)
      {
        if (j == 0) rr = _range.size();

        Real tmp_rr = _mesh.minPeriodicDistance(_var.number(), _centers[j], newcenter);

        if (tmp_rr < rr) rr = tmp_rr;
      }

      if (i == 0) rr = _range.size();
      
      //Verify not out of bounds
        if (_avoid_bounds && newcenter(0) < _radii[i] + _int_width)
          newcenter(0) = _radii[i] + _int_width;
        if (_avoid_bounds && newcenter(0) > _range(0) - (_radii[i] + _int_width))
          newcenter(0) = _range(0) - (_radii[i] + _int_width);
        if (_avoid_bounds && newcenter(1) < _radii[i] + _int_width)
          newcenter(1) = _radii[i] + _int_width;
        if (_avoid_bounds && newcenter(1) > _range(1) - (_radii[i] + _int_width))
          newcenter(1) = _range(1) - (_radii[i] + _int_width);
        if (_range(2) != 0.0)
        {
          if (_avoid_bounds && newcenter(2) < _radii[i] + _int_width)
            newcenter(2) = _radii[i] + _int_width;
          if (_avoid_bounds && newcenter(2) > _range(2) - (_radii[i] + _int_width))
            newcenter(2) = _range(2) - (_radii[i] + _int_width);
        }
    }

    if (num_tries == _numtries)
      mooseError("Too many tries in MultiSmoothParticleIC");
    
     _centers[i] = newcenter;
  }
}
void
BimodalInverseSuperellipsoidsIC::computeSuperellipsoidCenters()
{
  _centers.resize(_x_positions.size() + _npart);

  //First place the specified (large) particles from the input file
  for (unsigned int i = 0; i < _x_positions.size(); ++i)
  {
    _centers[i](0) = _x_positions[i];
    _centers[i](1) = _y_positions[i];
    _centers[i](2) = _z_positions[i];
  }

  //Next place the randomly positioned (small) particles
  for (unsigned int i = _x_positions.size(); i < _x_positions.size() + _npart; i++)
  {
    unsigned int num_tries = 0;

    Real dsmall_min = 0.0; //minimum distance from the random particle to another random particle
    Real dlarge_max = 0.0; //minimum distance from the random particle to edge of the specified (large) particle

    Point newcenter = 0.0;

    while ((dsmall_min < _small_spac || dlarge_max < _large_spac) && num_tries < _numtries)
    {
      num_tries++;

      Real ran1 = _random.rand(_tid);
      Real ran2 = _random.rand(_tid);
      Real ran3 = _random.rand(_tid);

      newcenter(0) = _bottom_left(0) + ran1*_range(0);
      newcenter(1) = _bottom_left(1) + ran2*_range(1);
      newcenter(2) = _bottom_left(2) + ran3*_range(2);

      //First check to make sure we are INSIDE a larger particle
      for (unsigned int j = 0; j < _x_positions.size(); j++)
      {
        if (j == 0)
          dlarge_max = - _range.norm();

        //Compute the distance r1 from the center of each specified superellipsoid to its outside edge
        //along the vector between the specified superellipsoid and the current randomly
        //positioned one
        //This uses the equation for a superellipse in polar coordinates and substitutes
        //distances for sin, cos functions
        Real dist = _mesh.minPeriodicDistance(_var.number(), _centers[j], newcenter);
        Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[j], newcenter);

        //First calculate rmn1 = r1^(-n), replacing sin, cos functions with distances
        Real rmn1 = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j])
                  + std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j])
                  + std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]) );
        //Then calculate r1 from rmn1
        Real r1 = std::pow(rmn1, (-1.0/_ns[j]));

        //Now calculate the distance r2 from the center of the randomly placed superellipsoid
        //to its outside edge in the same manner
        Real rmn2 = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i])
                  + std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i])
                  + std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]) );
        Real r2 = std::pow(rmn2, (-1.0/_ns[i]));

        //Calculate the distance between the edges for an interior particle
        Real tmp_dlarge_max = r1 - dist - r2;

        if (tmp_dlarge_max > dlarge_max)
          dlarge_max = tmp_dlarge_max;
      }

      //Then check for collisions between the randomly placed particles
      for (unsigned int j = _x_positions.size(); j < i; j++)
      {
        if (j == _x_positions.size())
          dsmall_min = _range.norm();

        Real dist = _mesh.minPeriodicDistance(_var.number(), _centers[j], newcenter);
        Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[j], newcenter);

        Real rmn1 = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j])
                  + std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j])
                  + std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]) );
        Real r1 = std::pow(rmn1, (-1.0/_ns[j]));

        Real rmn2 = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i])
                  + std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i])
                  + std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]) );
        Real r2 = std::pow(rmn2, (-1.0/_ns[i]));

        //Calculate the distance between the edges
        Real tmp_dsmall_min = dist - r1 - r2;

        if (tmp_dsmall_min < dsmall_min)
          dsmall_min = tmp_dsmall_min;
      }
      //Cause while statement to exit for the first randomly placed particle
      if (i == _x_positions.size())
        dsmall_min = _range.norm();
    }

    if (num_tries == _numtries)
      mooseError("Too many tries in BimodalInverseSuperellipsoidsIC");

    _centers[i] = newcenter;
  }
}
Exemplo n.º 19
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";
  }
}
Exemplo n.º 20
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);
  }
}
Exemplo n.º 21
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";
    }
  }
}