mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
8a122c8a7d
commit
dfe67178dc
|
|
@ -26,6 +26,50 @@
|
||||||
namespace pex
|
namespace pex
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
std::string
|
||||||
|
RNode::to_string () const
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
res += "$" + tl::to_string (port_index);
|
||||||
|
break;
|
||||||
|
case VertexPort:
|
||||||
|
res += "V" + tl::to_string (port_index);
|
||||||
|
break;
|
||||||
|
case PolygonPort:
|
||||||
|
res += "P" + tl::to_string (port_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
std::string
|
||||||
|
RElement::to_string () const
|
||||||
|
{
|
||||||
|
std::string res = "R ";
|
||||||
|
if (a ()) {
|
||||||
|
res += a ()->to_string ();
|
||||||
|
} else {
|
||||||
|
res += "(nil)";
|
||||||
|
}
|
||||||
|
res += " ";
|
||||||
|
if (b ()) {
|
||||||
|
res += b ()->to_string ();
|
||||||
|
} else {
|
||||||
|
res += "(nil)";
|
||||||
|
}
|
||||||
|
res += " ";
|
||||||
|
res += tl::sprintf ("%.6g", resistance ());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
RNetwork::RNetwork ()
|
RNetwork::RNetwork ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
|
|
@ -36,10 +80,23 @@ RNetwork::~RNetwork ()
|
||||||
clear ();
|
clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
RNetwork::to_string () const
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
for (auto e = m_elements.begin (); e != m_elements.end (); ++e) {
|
||||||
|
if (! res.empty ()) {
|
||||||
|
res += "\n";
|
||||||
|
}
|
||||||
|
res += e->to_string ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RNetwork::clear ()
|
RNetwork::clear ()
|
||||||
{
|
{
|
||||||
m_elements.clear (); // must come before m_nodes
|
m_elements.clear (); // must happen before m_nodes
|
||||||
m_nodes.clear ();
|
m_nodes.clear ();
|
||||||
m_elements_by_nodes.clear ();
|
m_elements_by_nodes.clear ();
|
||||||
m_nodes_by_type.clear ();
|
m_nodes_by_type.clear ();
|
||||||
|
|
@ -51,7 +108,7 @@ std::map<std::pair<RNode::node_type, unsigned int>, RNode *> m_nodes;
|
||||||
RNode *
|
RNode *
|
||||||
RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
||||||
{
|
{
|
||||||
if (type != RNode::INTERNAL) {
|
if (type != RNode::Internal) {
|
||||||
|
|
||||||
auto i = m_nodes_by_type.find (std::make_pair (type, port_index));
|
auto i = m_nodes_by_type.find (std::make_pair (type, port_index));
|
||||||
if (i != m_nodes_by_type.end ()) {
|
if (i != m_nodes_by_type.end ()) {
|
||||||
|
|
@ -60,7 +117,7 @@ RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
RNode *new_node = new RNode (this, type, db::DBox (), port_index);
|
||||||
m_nodes.push_back (new_node);
|
m_nodes.push_back (new_node);
|
||||||
m_nodes_by_type.insert (std::make_pair (std::make_pair (type, port_index), new_node));
|
m_nodes_by_type.insert (std::make_pair (std::make_pair (type, port_index), new_node));
|
||||||
|
|
||||||
|
|
@ -69,7 +126,7 @@ RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
RNode *new_node = new RNode (this, type, db::DBox (), port_index);
|
||||||
m_nodes.push_back (new_node);
|
m_nodes.push_back (new_node);
|
||||||
return new_node;
|
return new_node;
|
||||||
|
|
||||||
|
|
@ -87,13 +144,15 @@ RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
RElement *element = new RElement (conductivity, a, b);
|
RElement *element = new RElement (this, conductivity, a, b);
|
||||||
a->elements.push_back (element);
|
m_elements.push_back (element);
|
||||||
element->m_ia = --a->elements.end ();
|
|
||||||
b->elements.push_back (element);
|
|
||||||
element->m_ia = --b->elements.end ();
|
|
||||||
|
|
||||||
m_elements_by_nodes.insert (std::make_pair (std::make_pair (a, b), element));
|
m_elements_by_nodes.insert (std::make_pair (std::make_pair (a, b), element));
|
||||||
|
|
||||||
|
a->m_elements.push_back (element);
|
||||||
|
element->m_ia = --a->m_elements.end ();
|
||||||
|
b->m_elements.push_back (element);
|
||||||
|
element->m_ib = --b->m_elements.end ();
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -102,9 +161,9 @@ RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
||||||
void
|
void
|
||||||
RNetwork::remove_node (RNode *node)
|
RNetwork::remove_node (RNode *node)
|
||||||
{
|
{
|
||||||
tl_assert (node->type == RNode::INTERNAL);
|
tl_assert (node->type == RNode::Internal);
|
||||||
while (! node->elements.empty ()) {
|
while (! node->m_elements.empty ()) {
|
||||||
remove_element (const_cast<RElement *> (node->elements.front ()));
|
delete const_cast<RElement *> (node->m_elements.front ());
|
||||||
}
|
}
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
@ -112,19 +171,20 @@ RNetwork::remove_node (RNode *node)
|
||||||
void
|
void
|
||||||
RNetwork::remove_element (RElement *element)
|
RNetwork::remove_element (RElement *element)
|
||||||
{
|
{
|
||||||
RNode *a = const_cast<RNode *> (element->a);
|
RNode *a = const_cast<RNode *> (element->a ());
|
||||||
RNode *b = const_cast<RNode *> (element->b);
|
RNode *b = const_cast<RNode *> (element->b ());
|
||||||
|
|
||||||
delete element;
|
delete element;
|
||||||
|
|
||||||
if (a && a->type == RNode::INTERNAL && a->elements.empty ()) {
|
if (a && a->type == RNode::Internal && a->m_elements.empty ()) {
|
||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
if (b && b->type == RNode::INTERNAL && b->elements.empty ()) {
|
if (b && b->type == RNode::Internal && b->m_elements.empty ()) {
|
||||||
delete b;
|
delete b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
RExtractor::RExtractor ()
|
RExtractor::RExtractor ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,28 +39,36 @@ namespace pex
|
||||||
|
|
||||||
class RElement;
|
class RElement;
|
||||||
class RNode;
|
class RNode;
|
||||||
|
class RNetwork;
|
||||||
|
|
||||||
struct PEX_PUBLIC RNode
|
struct PEX_PUBLIC RNode
|
||||||
: public tl::list_node<RNode>
|
: public tl::list_node<RNode>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum node_type {
|
enum node_type {
|
||||||
INTERNAL,
|
Internal,
|
||||||
VERTEX_PORT,
|
VertexPort,
|
||||||
POLYGON_PORT
|
PolygonPort
|
||||||
};
|
};
|
||||||
|
|
||||||
node_type type;
|
node_type type;
|
||||||
db::DBox location;
|
db::DBox location;
|
||||||
unsigned int port_index;
|
unsigned int port_index;
|
||||||
mutable std::list<const RElement *> elements;
|
|
||||||
|
const std::list<const RElement *> &elements () const
|
||||||
|
{
|
||||||
|
return m_elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RNetwork;
|
friend class RNetwork;
|
||||||
|
friend class RElement;
|
||||||
friend class tl::list_impl<RNode, false>;
|
friend class tl::list_impl<RNode, false>;
|
||||||
|
|
||||||
RNode (node_type _type, const db::DBox &_location, unsigned int _port_index)
|
RNode (RNetwork *network, node_type _type, const db::DBox &_location, unsigned int _port_index)
|
||||||
: type (_type), location (_location), port_index (_port_index)
|
: type (_type), location (_location), port_index (_port_index), mp_network (network)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~RNode () { }
|
~RNode () { }
|
||||||
|
|
@ -68,39 +76,48 @@ protected:
|
||||||
private:
|
private:
|
||||||
RNode (const RNode &other);
|
RNode (const RNode &other);
|
||||||
RNode &operator= (const RNode &other);
|
RNode &operator= (const RNode &other);
|
||||||
|
|
||||||
|
RNetwork *mp_network;
|
||||||
|
mutable std::list<const RElement *> m_elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PEX_PUBLIC RElement
|
struct PEX_PUBLIC RElement
|
||||||
: public tl::list_node<RElement>
|
: public tl::list_node<RElement>
|
||||||
{
|
{
|
||||||
double conductivity;
|
double conductivity;
|
||||||
const RNode *a, *b;
|
|
||||||
|
const RNode *a () const { return mp_a; }
|
||||||
|
const RNode *b () const { return mp_b; }
|
||||||
|
|
||||||
double resistance () const
|
double resistance () const
|
||||||
{
|
{
|
||||||
return 1.0 / conductivity;
|
return 1.0 / conductivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RNetwork;
|
friend class RNetwork;
|
||||||
friend class tl::list_impl<RElement, false>;
|
friend class tl::list_impl<RElement, false>;
|
||||||
|
|
||||||
RElement (double _conductivity, const RNode *_a, const RNode *_b)
|
RElement (RNetwork *network, double _conductivity, const RNode *a, const RNode *b)
|
||||||
: conductivity (_conductivity), a (_a), b (_b)
|
: conductivity (_conductivity), mp_network (network), mp_a (a), mp_b (b)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~RElement ()
|
~RElement ()
|
||||||
{
|
{
|
||||||
if (a) {
|
if (mp_a) {
|
||||||
a->elements.erase (m_ia);
|
mp_a->m_elements.erase (m_ia);
|
||||||
}
|
}
|
||||||
if (b) {
|
if (mp_b) {
|
||||||
b->elements.erase (m_ib);
|
mp_b->m_elements.erase (m_ib);
|
||||||
}
|
}
|
||||||
a = b = 0;
|
mp_a = mp_b = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<const RElement *>::iterator m_ia, m_ib;
|
std::list<const RElement *>::iterator m_ia, m_ib;
|
||||||
|
RNetwork *mp_network;
|
||||||
|
const RNode *mp_a, *mp_b;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RElement (const RElement &other);
|
RElement (const RElement &other);
|
||||||
|
|
@ -108,6 +125,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class PEX_PUBLIC RNetwork
|
class PEX_PUBLIC RNetwork
|
||||||
|
: public tl::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RNetwork ();
|
RNetwork ();
|
||||||
|
|
@ -119,6 +137,8 @@ public:
|
||||||
void remove_node (RNode *node);
|
void remove_node (RNode *node);
|
||||||
void clear ();
|
void clear ();
|
||||||
|
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tl::list<RNode, false> m_nodes;
|
tl::list<RNode, false> m_nodes;
|
||||||
tl::list<RElement, false> m_elements;
|
tl::list<RElement, false> m_elements;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,53 @@
|
||||||
#include "pexRExtractor.h"
|
#include "pexRExtractor.h"
|
||||||
#include "tlUnitTest.h"
|
#include "tlUnitTest.h"
|
||||||
|
|
||||||
TEST(1)
|
TEST(network_basic)
|
||||||
{
|
{
|
||||||
// @@@
|
pex::RNetwork rn;
|
||||||
|
EXPECT_EQ (rn.to_string (), "");
|
||||||
|
|
||||||
|
pex::RNode *n1 = rn.create_node (pex::RNode::Internal, 1);
|
||||||
|
pex::RNode *n2 = rn.create_node (pex::RNode::Internal, 2);
|
||||||
|
/* pex::RElement *e12 = */ rn.create_element (0.5, n1, n2);
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (),
|
||||||
|
"R $1 $2 2"
|
||||||
|
);
|
||||||
|
|
||||||
|
pex::RNode *n3 = rn.create_node (pex::RNode::Internal, 3);
|
||||||
|
/* pex::RElement *e13 = */ rn.create_element (0.25, n1, n3);
|
||||||
|
pex::RElement *e23 = rn.create_element (1.0, n2, n3);
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (),
|
||||||
|
"R $1 $2 2\n"
|
||||||
|
"R $1 $3 4\n"
|
||||||
|
"R $2 $3 1"
|
||||||
|
);
|
||||||
|
|
||||||
|
pex::RElement *e23b = rn.create_element (4.0, n2, n3);
|
||||||
|
EXPECT_EQ (e23 == e23b, true);
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (),
|
||||||
|
"R $1 $2 2\n"
|
||||||
|
"R $1 $3 4\n"
|
||||||
|
"R $2 $3 0.2"
|
||||||
|
);
|
||||||
|
|
||||||
|
rn.remove_element (e23);
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (),
|
||||||
|
"R $1 $2 2\n"
|
||||||
|
"R $1 $3 4"
|
||||||
|
);
|
||||||
|
|
||||||
|
rn.remove_node (n3);
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (),
|
||||||
|
"R $1 $2 2"
|
||||||
|
);
|
||||||
|
|
||||||
|
rn.clear ();
|
||||||
|
|
||||||
|
EXPECT_EQ (rn.to_string (), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue