Page MenuHomec4science

geometry.hh
No OneTemporary

File Metadata

Created
Sun, Oct 20, 19:15

geometry.hh

/**
* @file geometry.hh
* @author Till Junge <junge@lsmspc42.epfl.ch>
* @date Wed Apr 4 15:15:10 2012
*
* @brief Geometry motherclass (interface) for CADD mesher
*
* @section LICENSE
*
* <insert lisence here>
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __GEOMETRY_HH__
#define __GEOMETRY_HH__
#include "common.hh"
#include "point_container.hh"
#include <sstream>
//#include "cadd_mesh.hh"
template <Uint DIM>
class Mesh;
struct InsideObject {
Real distance;
bool is_inside;
};
/*! \brief Geometry interface for CADD mesher
* You will never use this class.*/
template <Uint DIM>
class Geometry {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
/*! Constructor
*\param _name a string identifier for the geometry */
Geometry(std::string _name = ""):name(_name){};
virtual ~Geometry(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// function to print the content of the class
virtual void printself(std::ostream & stream, int indent = 0) const
{
stream << "This is just a interface class and this function should never "
<< "ever be called" <<std::endl;
}
virtual void shift(const PointRef<DIM> & offset) = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
/// returns the string identifier
const std::string & get_name() const
{
return this->name;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
public:
/*! creates a copy of the object (calling new) and returns a Geometry
* pointer*/
virtual Geometry * resolveType() const = 0;
/*! test whether a point is inside the domain
* \param point coordinates of the point to test*/
virtual bool is_inside(const Real * point, Real tol) const = 0;
bool py_is_inside(const PointRef<DIM> & point, Real tol) const {
return this->is_inside(point, tol);
}
virtual inline bool is_inside(const PointRef<DIM> & point, Real tol) const {
return this->is_inside(&(point.getComponent(0)), tol);}
/*! Returns the minimum value of all constraint violations (negative return
* value means point is inside and return value from the nearest boundary)
* \param point coordintates of the point to test*/
virtual InsideObject from_border(const Real * point, Real tol) const = 0;
inline InsideObject from_border(const PointRef<DIM> & point, Real tol) const {
return this->from_border(&(point.getComponent(0)), tol);}
/*! projects the geometry on a line of direction \a dir and returns the
* minimum of the line segment spanned
* \param dir direction vector (will be scaled to unity by the method
* \param unit unit in which the distance should be expressed, by default unity*/
virtual Real min_in_direction(const Real * dir, const Real & unit = 1) const = 0;
/*! projects the geometry on a line of direction \a dir and returns the
* maximum of the line segment spanned
* \param dir direction vector (will be scaled to unity by the method
* \param unit unit in which the distance should be expressed, by default unity*/
virtual Real max_in_direction(const Real * dir, const Real & unit = 1) const = 0;
/*! projects the geometry on a line of direction \a dir and returns the length
* of the projection
* \param dir direction vector (will be scaled to unity by the method
* \param unit unit in which the distance should be expressed, by default unity*/
virtual Real size_in_direction(const Real * dir, const Real & unit = 1) const ;
/*! put nodes onto the surface of the geometry
* \param auxiliary mesh for refinement interpolation
* \param refinement vector of refinements used with the auxiliary mesh
* \param step_size array of periodic cell sizes as returned by
* lattice::getSpatialConstants()
* \param repr_const representative constant of the periodic cell
* \param periodicity self-explanatory
* \param points container of nodal points for meshing
*/
virtual void generate_surface_points(const Mesh<DIM> & auxiliary,
const std::vector<Real> & refinement,
const Real step_size[DIM],
const Real & repr_const,
const bool periodicity[DIM],
PointContainer<DIM> & points) const;
/*! When the dimensions of the overall geometry are not a power of two times
* the lattice size, the domain can be not filled correctly. This method
* corrects the fucked up side by periodically repeating the ok side.
* \param direction positive values mean that the min side is used to augment
* the max size, negative values the inverse.
* \param dim dimension to fix: 0:x, 1:y, 2:z
*/
virtual void complement_periodically(const Mesh<DIM> & auxiliary,
const std::vector<Real> & refinement,
const PointContainer<DIM> & points,
PointContainer<DIM> & complement,
int direction,
Uint dim) const;
protected:
std::string name;
};
/// standard output stream operator
template<Uint DIM>
inline std::ostream & operator <<(std::ostream & stream, const Geometry<DIM> & _this)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template <Uint DIM, typename subGeom>
Geometry<DIM> * newGeom(const subGeom & geometry) {
return static_cast<Geometry<DIM>*>(new subGeom(geometry));
}
/* -------------------------------------------------------------------------- */
template<Uint DIM>
inline bool check_if_ok(const PointRef<DIM> & point,
const Mesh<DIM> & auxiliary,
const std::vector<Real> & refinement,
const Real & step_size,
PointContainer<DIM> & points) {
Real ref_sq = square(step_size * auxiliary.interpolate(point,
refinement));
Real step_sq = step_size*step_size;
// if refinement is smaller than 1 => full resolution
if (ref_sq < step_sq) {
return false;
}
// check whether the new point in too close to an existing point
for (Uint point_id = 0; point_id < points.getSize() ; ++point_id) {
if (ref_sq > distance2<DIM>(point, points.getPoint(point_id))) {
return false;
}
}
return true;
}
/* -------------------------------------------------------------------------- */
template<Uint DIM>
inline bool add_if_ok(const PointRef<DIM> & point,
const Mesh<DIM> & auxiliary,
const std::vector<Real> & refinement,
const Real & step_size,
PointContainer<DIM> & points) {
if (check_if_ok(point, auxiliary, refinement, step_size, points)) {
points.addPoint(point);
return true;
} else {
return false;
}
}
/* -------------------------------------------------------------------------- */
template<Uint DIM>
bool add_periodic_complement(const Mesh<DIM> & auxiliary,
const std::vector<Real> & refinement,
const PointRef<DIM> & point,
const PointContainer<DIM> & points,
PointContainer<DIM> & complement) {
Real local_refinement = auxiliary.interpolate(point, refinement);
if (local_refinement <= 1.) {
complement.addPoint(point);
return true;
} else {
return false;
}
}
#endif /* __GEOMETRY_HH__ */

Event Timeline