mirror of https://github.com/KLayout/klayout.git
Doc and small fixes
This commit is contained in:
parent
9bf03390de
commit
93e10d1d72
|
|
@ -138,7 +138,7 @@ RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
|||
}
|
||||
|
||||
RElement *
|
||||
RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
||||
RNetwork::create_element (double conductance, RNode *a, RNode *b)
|
||||
{
|
||||
std::pair<RNode *, RNode *> key (a, b);
|
||||
if (size_t (b) < size_t (a)) {
|
||||
|
|
@ -148,17 +148,17 @@ RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
|||
auto i = m_elements_by_nodes.find (key);
|
||||
if (i != m_elements_by_nodes.end ()) {
|
||||
|
||||
if (conductivity == pex::RElement::short_value () || i->second->conductivity == pex::RElement::short_value ()) {
|
||||
i->second->conductivity = pex::RElement::short_value ();
|
||||
if (conductance == pex::RElement::short_value () || i->second->conductance == pex::RElement::short_value ()) {
|
||||
i->second->conductance = pex::RElement::short_value ();
|
||||
} else {
|
||||
i->second->conductivity += conductivity;
|
||||
i->second->conductance += conductance;
|
||||
}
|
||||
|
||||
return i->second;
|
||||
|
||||
} else {
|
||||
|
||||
RElement *element = new RElement (this, conductivity, a, b);
|
||||
RElement *element = new RElement (this, conductance, a, b);
|
||||
m_elements.push_back (element);
|
||||
m_elements_by_nodes.insert (std::make_pair (key, element));
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ RNetwork::join_nodes (RNode *a, RNode *b)
|
|||
for (auto e = b->elements ().begin (); e != b->elements ().end (); ++e) {
|
||||
RNode *on = const_cast<RNode *> ((*e)->other (b));
|
||||
if (on != a) {
|
||||
create_element ((*e)->conductivity, on, a);
|
||||
create_element ((*e)->conductance, on, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ RNetwork::simplify ()
|
|||
|
||||
tl::equivalence_clusters<const RNode *> clusters;
|
||||
for (auto e = m_elements.begin (); e != m_elements.end (); ++e) {
|
||||
if (e->conductivity == pex::RElement::short_value () && (e->a ()->type == pex::RNode::Internal || e->b ()->type == pex::RNode::Internal)) {
|
||||
if (e->conductance == pex::RElement::short_value () && (e->a ()->type == pex::RNode::Internal || e->b ()->type == pex::RNode::Internal)) {
|
||||
clusters.same (e->a (), e->b ());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,25 +40,57 @@ class RElement;
|
|||
class RNode;
|
||||
class RNetwork;
|
||||
|
||||
/**
|
||||
* @brief Represents a node in the R graph
|
||||
*
|
||||
* A node connects to multiple elements (resistors).
|
||||
* Every element has two nodes. The nodes and elements form
|
||||
* a graph.
|
||||
*
|
||||
* RNode object cannot be created directly. Use "create_node"
|
||||
* from RNetwork.
|
||||
*/
|
||||
struct PEX_PUBLIC RNode
|
||||
: public tl::list_node<RNode>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The type of the node
|
||||
*/
|
||||
enum node_type {
|
||||
Internal,
|
||||
VertexPort,
|
||||
PolygonPort
|
||||
Internal, // an internal node, not related to a port
|
||||
VertexPort, // a node related to a vertex port
|
||||
PolygonPort // a node related to a polygon port
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The node type
|
||||
*/
|
||||
node_type type;
|
||||
|
||||
/**
|
||||
* @brief The location + extension of the node
|
||||
*/
|
||||
db::DBox location;
|
||||
|
||||
/**
|
||||
* @brief An index locating the node in the vertex or polygon port lists
|
||||
*
|
||||
* For internal nodes, the index is a unique numbers.
|
||||
*/
|
||||
unsigned int port_index;
|
||||
|
||||
/**
|
||||
* @brief Gets the R elements connected to this node
|
||||
*/
|
||||
const std::list<const RElement *> &elements () const
|
||||
{
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string representation of the node
|
||||
*/
|
||||
std::string to_string () const;
|
||||
|
||||
protected:
|
||||
|
|
@ -80,14 +112,35 @@ private:
|
|||
mutable std::list<const RElement *> m_elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents an R element in the graph (an edge)
|
||||
*
|
||||
* An element has two nodes that form the ends of the edge and
|
||||
* a conductance value (given in Siemens).
|
||||
*
|
||||
* The value can be RElement::short_value() indicating
|
||||
* "infinite" conductance (a short).
|
||||
*
|
||||
* RElement objects cannot be created directly. Use "create_element"
|
||||
* from RNetwork.
|
||||
*/
|
||||
struct PEX_PUBLIC RElement
|
||||
: public tl::list_node<RElement>
|
||||
{
|
||||
double conductivity;
|
||||
/**
|
||||
* @brief The conductance value
|
||||
*/
|
||||
double conductance;
|
||||
|
||||
/**
|
||||
* @brief The nodes the resistor connects
|
||||
*/
|
||||
const RNode *a () const { return mp_a; }
|
||||
const RNode *b () const { return mp_b; }
|
||||
|
||||
/**
|
||||
* @brief Gets the other node for n
|
||||
*/
|
||||
const RNode *other (const RNode *n) const
|
||||
{
|
||||
if (mp_a == n) {
|
||||
|
|
@ -98,16 +151,27 @@ struct PEX_PUBLIC RElement
|
|||
tl_assert (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents the conductance value for a short
|
||||
*/
|
||||
static double short_value ()
|
||||
{
|
||||
return std::numeric_limits<double>::infinity ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the resistance value
|
||||
*
|
||||
* The resistance value is the inverse of the conducance.
|
||||
*/
|
||||
double resistance () const
|
||||
{
|
||||
return conductivity == short_value () ? 0.0 : 1.0 / conductivity;
|
||||
return conductance == short_value () ? 0.0 : 1.0 / conductance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string representation of the element
|
||||
*/
|
||||
std::string to_string () const;
|
||||
|
||||
protected:
|
||||
|
|
@ -115,7 +179,7 @@ protected:
|
|||
friend class tl::list_impl<RElement, false>;
|
||||
|
||||
RElement (RNetwork *network, double _conductivity, const RNode *a, const RNode *b)
|
||||
: conductivity (_conductivity), mp_network (network), mp_a (a), mp_b (b)
|
||||
: conductance (_conductivity), mp_network (network), mp_a (a), mp_b (b)
|
||||
{ }
|
||||
|
||||
~RElement ()
|
||||
|
|
@ -138,6 +202,9 @@ private:
|
|||
RElement &operator= (const RElement &other);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a R network (a graph of RNode and RElement)
|
||||
*/
|
||||
class PEX_PUBLIC RNetwork
|
||||
: public tl::Object
|
||||
{
|
||||
|
|
@ -147,33 +214,95 @@ public:
|
|||
typedef tl::list<RElement, false> element_list;
|
||||
typedef element_list::const_iterator element_iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
RNetwork ();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~RNetwork ();
|
||||
|
||||
/**
|
||||
* @brief Creates a node with the given type and port index
|
||||
*
|
||||
* If the node type is Internal, a new node is created always.
|
||||
* If the node type is VertexPort or PolygonPort, an existing
|
||||
* node is returned if one way created with the same type
|
||||
* or port index already. This avoids creating duplicates
|
||||
* for the same port.
|
||||
*/
|
||||
RNode *create_node (RNode::node_type type, unsigned int port_index);
|
||||
RElement *create_element (double conductivity, RNode *a, RNode *b);
|
||||
|
||||
/**
|
||||
* @brief Creates a new element between the given nodes
|
||||
*
|
||||
* If an element already exists between the specified nodes, the
|
||||
* given value is added to the existing element and the existing
|
||||
* object is returned.
|
||||
*/
|
||||
RElement *create_element (double conductance, RNode *a, RNode *b);
|
||||
|
||||
/**
|
||||
* @brief Removes the given element
|
||||
*
|
||||
* Removing the element will also remove any orphan nodes
|
||||
* at the ends if they are of type Internal.
|
||||
*/
|
||||
void remove_element (RElement *element);
|
||||
|
||||
/**
|
||||
* @brief Removes the node and the attached elements.
|
||||
*
|
||||
* Only nodes of type Internal can be removed.
|
||||
*/
|
||||
void remove_node (RNode *node);
|
||||
|
||||
/**
|
||||
* @brief Clears the network
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Simplifies the network
|
||||
*
|
||||
* This will:
|
||||
* - Join serial resistors if connected by an internal node
|
||||
* - Remove shorts and join the nodes, if one of them is
|
||||
* an internal node. The non-internal node will persist.
|
||||
* - Remove "dangling" resistors if the dangling node is
|
||||
* an internal one
|
||||
*/
|
||||
void simplify ();
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
/**
|
||||
* @brief Iterate the nodes (begin)
|
||||
*/
|
||||
node_iterator begin_nodes () const
|
||||
{
|
||||
return m_nodes.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate the nodes (end)
|
||||
*/
|
||||
node_iterator end_nodes () const
|
||||
{
|
||||
return m_nodes.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of nodes
|
||||
*/
|
||||
size_t num_nodes () const
|
||||
{
|
||||
return m_nodes.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of internal nodes
|
||||
*/
|
||||
size_t num_internal_nodes () const
|
||||
{
|
||||
size_t count = 0;
|
||||
|
|
@ -185,21 +314,35 @@ public:
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate the elements (begin)
|
||||
*/
|
||||
element_iterator begin_elements () const
|
||||
{
|
||||
return m_elements.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate the elements (end)
|
||||
*/
|
||||
element_iterator end_elements () const
|
||||
{
|
||||
return m_elements.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of elements
|
||||
*/
|
||||
size_t num_elements () const
|
||||
{
|
||||
return m_elements.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string representation of the graph
|
||||
*/
|
||||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
node_list m_nodes;
|
||||
element_list m_elements;
|
||||
|
|
@ -225,9 +368,24 @@ private:
|
|||
class PEX_PUBLIC RExtractor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
RExtractor ();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~RExtractor ();
|
||||
|
||||
/**
|
||||
* @brief Extracts the resistance network from the given polygon and ports
|
||||
*
|
||||
* The ports define specific locations where to connect to the resistance network.
|
||||
* The network will contain corresponding nodes with the VertexPort for vertex ports
|
||||
* and PolygonPort for polygon port. The node index is the index in the respective
|
||||
* lists.
|
||||
*/
|
||||
virtual void extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ SquareCountingRExtractor::do_extract (const db::Polygon &db_poly, const std::vec
|
|||
// @@@ TODO: multiply with sheet rho!
|
||||
// @@@ TODO: width dependency
|
||||
if (r == 0) {
|
||||
// @@@ TODO: join nodes later!
|
||||
rnetwork.create_element (pex::RElement::short_value (), pl->second, pl_next->second);
|
||||
} else {
|
||||
rnetwork.create_element (r, pl->second, pl_next->second);
|
||||
|
|
@ -293,6 +292,7 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
|
|||
|
||||
}
|
||||
|
||||
rnetwork.simplify ();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,28 +31,58 @@
|
|||
namespace pex
|
||||
{
|
||||
|
||||
// @@@ doc
|
||||
/**
|
||||
* @brief The Square Counting R Extractor
|
||||
*
|
||||
* The idea of that extractor is to first decompose the polygon into
|
||||
* convex parts. Each convex part is taken as "thin" and the current
|
||||
* flow being parallel and homogeneous to the long axis.
|
||||
*
|
||||
* Internal ports are created between the partial polygons where
|
||||
* they touch.
|
||||
*
|
||||
* The ports are considered point-like (polygon ports are replaced
|
||||
* by points in their bounding box centers) and inject current
|
||||
* at their specific position only. The resistance is accumulated
|
||||
* between ports by integrating the squares (length along
|
||||
* the long axis / width).
|
||||
*/
|
||||
class PEX_PUBLIC SquareCountingRExtractor
|
||||
: public RExtractor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
SquareCountingRExtractor (double dbu);
|
||||
|
||||
/**
|
||||
* @brief Gets the decomposition parameters
|
||||
*/
|
||||
db::plc::ConvexDecompositionParameters &decomposition_parameters ()
|
||||
{
|
||||
return m_decomp_param;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the database unit
|
||||
*/
|
||||
void set_dbu (double dbu)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the database unit
|
||||
*/
|
||||
double dbu () const
|
||||
{
|
||||
return m_dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of the extraction function
|
||||
*/
|
||||
virtual void extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ TriangulationRExtractor::eliminate_node (pex::RNode *node, RNetwork &rnetwork)
|
|||
{
|
||||
double s_sum = 0.0;
|
||||
for (auto e = node->elements ().begin (); e != node->elements ().end (); ++e) {
|
||||
s_sum += (*e)->conductivity;
|
||||
s_sum += (*e)->conductance;
|
||||
}
|
||||
|
||||
if (fabs (s_sum) > 1e-10) {
|
||||
|
|
@ -311,7 +311,7 @@ TriangulationRExtractor::eliminate_node (pex::RNode *node, RNetwork &rnetwork)
|
|||
for ( ; ee != node->elements ().end (); ++ee) {
|
||||
pex::RNode *n1 = const_cast <pex::RNode *> ((*e)->other (node));
|
||||
pex::RNode *n2 = const_cast <pex::RNode *> ((*ee)->other (node));
|
||||
double c = (*e)->conductivity * (*ee)->conductivity / s_sum;
|
||||
double c = (*e)->conductance * (*ee)->conductance / s_sum;
|
||||
rnetwork.create_element (c, n1, n2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,28 +31,59 @@
|
|||
namespace pex
|
||||
{
|
||||
|
||||
// @@@ doc
|
||||
/**
|
||||
* @brief An R extractor based on a triangulation of the resistor area
|
||||
*
|
||||
* This resistor extractor starts with a triangulation of the
|
||||
* polygon area and substitutes each triangle by a 3-resistor network.
|
||||
*
|
||||
* After this, it will eliminate nodes where possible.
|
||||
*
|
||||
* This extractor delivers a resistor matrix (there is a resistor
|
||||
* between every specified port).
|
||||
*
|
||||
* Polygon ports are considered to be perfectly conductive and cover
|
||||
* their given area, shorting all nodes at their boundary.
|
||||
*
|
||||
* This extractor delivers higher quality results than the square
|
||||
* counting extractor, but is slower in general.
|
||||
*/
|
||||
class PEX_PUBLIC TriangulationRExtractor
|
||||
: public RExtractor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
TriangulationRExtractor (double dbu);
|
||||
|
||||
/**
|
||||
* @brief Gets the triangulation parameters
|
||||
*/
|
||||
db::plc::TriangulationParameters &triangulation_parameters ()
|
||||
{
|
||||
return m_tri_param;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the database unit
|
||||
*/
|
||||
void set_dbu (double dbu)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the database unit
|
||||
*/
|
||||
double dbu () const
|
||||
{
|
||||
return m_dbu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implementation of the extraction function
|
||||
*/
|
||||
virtual void extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork);
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in New Issue