CSGSurface

This is an abstract class for any surface definition for constructive solid geometry (CSG) representations. The CSGBase framework already contains definitions for some basic surfaces (planes, spheres, and cylinders), but developers of modules or MOOSE-based application can define additional custom surfaces by deriving from this abstract CSGBase class. General information about implementing Constructive Solid Geometry (CSG)-related methods can be found in CSGBase.

Defining a New Surface Type

Any arbitrary or custom surface can be defined by inheriting from CSGSurface. At a minimum, the surface name and surface type, must be set, and two virtual methods that need to be defined. Additional information required by the constructor will depend on the specific surface to be defined.

Setting Coefficients

Each surface should be defined by some equation, which therefore requires the definition of coefficients or other parameters. These coefficient values should be set and be returned through the getCoefficients method which will return a map of the coefficient strings to their values. These coefficient values are returned in the JavaScript Object Notation (JSON) file that is produced. For example, a plane is defined by the equation and so this method would return a map of the values for a, b, c, and d.

Half-space Determination

In CSG representation, knowing which half-space of the surface is positive or negative is necessary for correct construction of a cell region. To help determine the sign of these half-spaces, each surface type should have a evaluateSurfaceEquationAtPoint method implemented that returns a floating point value, where a positive value indicates that the point lies in the positive half-space, a negative value indicates that the point lies in the negative half-space, and a value of 0 indicates that the point lies on the surface.

Setting the Surface Type

The type of surface must be set for _surface_type in the surface constructor. It is recommended that this be done based on the class name using MooseUtils::prettyCppType<SurfaceClassName>() so that the surface type automatically matches the class that created it.

Example

Below shows how CSGSphere is implemented as an example.


#pragma once

#include "CSGSurface.h"

#include "libmesh/point.h"

namespace CSG
{

/**
 * CSGSphere creates an internal representation of a Constructive Solid Geometry (CSG)
 * sphere, represented in the form (x - x0)^2 + (y - y0)^2 + (z - z0)^2 = r^2
 */
class CSGSphere : public CSGSurface
{
public:
  /**
   * @brief Construct a new CSGSphere surface
   *
   * @param name unique name for the sphere surface
   * @param center center point of sphere
   * @param r radius of sphere
   */
  CSGSphere(const std::string & name, const Point & center, const Real r);

  /**
   * @brief Construct a new CSGSphere surface
   *
   * @param name unique name for the sphere surface
   * @param r radius of sphere
   */
  CSGSphere(const std::string & name, const Real r);

  /**
   * Destructor
   */
  virtual ~CSGSphere() = default;

  /**
   * @brief Get the coefficients (x0, y0, z0, r) for the equation of a sphere
   * (x - x0)^2 + (y - y0)^2 + (z - z0)^2 = r^2
   *
   * @return map of coefficients (x0, y0, z0, and r) and their values
   */
  virtual std::unordered_map<std::string, Real> getCoeffs() const override;

  /**
   * @brief given a point, determine its evaluation based on the equation of the sphere
   *
   * @param p point
   * @return evaluation of point based on surface equation
   */
  virtual Real evaluateSurfaceEquationAtPoint(const Point & p) const override;

protected:
  // check that radius is positive
  void checkRadius() const;

  /// Value of x0 in equation of sphere
  Real _x0;

  /// Value of y0 in equation of sphere
  Real _y0;

  /// Value of z0 in equation of sphere
  Real _z0;

  /// Value of r in equation of sphere
  Real _r;
};
} // namespace CSG
(moose/framework/include/csg/CSGSphere.h)

#include "CSGSphere.h"

namespace CSG
{

CSGSphere::CSGSphere(const std::string & name, const Point & center, const Real r)
  : CSGSurface(name, MooseUtils::prettyCppType<CSGSphere>()),
    _x0(center(0)),
    _y0(center(1)),
    _z0(center(2)),
    _r(r)
{
  checkRadius();
}

CSGSphere::CSGSphere(const std::string & name, const Real r)
  : CSGSurface(name, MooseUtils::prettyCppType<CSGSphere>()), _x0(0.0), _y0(0.0), _z0(0.0), _r(r)
{
  checkRadius();
}

std::unordered_map<std::string, Real>
CSGSphere::getCoeffs() const
{
  std::unordered_map<std::string, Real> coeffs = {{"x0", _x0}, {"y0", _y0}, {"z0", _z0}, {"r", _r}};
  return coeffs;
}

Real
CSGSphere::evaluateSurfaceEquationAtPoint(const Point & p) const
{
  // Compute distance from the sphere center to determine if inside (< r^2)
  // or outside (> r^2) the sphere
  const Real dist_sq =
      Utility::pow<2>((p(0) - _x0)) + Utility::pow<2>((p(1) - _y0)) + Utility::pow<2>((p(2) - _z0));

  return dist_sq - Utility::pow<2>(_r);
}

void
CSGSphere::checkRadius() const
{
  if (_r <= 0.0)
    mooseError("Radius of sphere must be positive.");
}

} // namespace CSG
(moose/framework/src/csg/CSGSphere.C)