📄 voltage.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "component.h"
#include "graph.h"
#include "eq.h"
static int voltage_eq_item (int pin1, int pin2 )
{
EQ_item_t *p = EQ_item_alloc();
VA_value_t constant;
if (!p) {
error (ENO_MEM);
return ENO_MEM;
}
assert (COMPCLASS (pin1)->U_eq);
constant = COMPCLASS (pin1)->U_eq (COMP (pin1), pin1, pin2, p );
if (p->next == (EQ_item_t *)-1 )
EQ_add_const (constant);
else
EQ_add (constant, p);
return SUCCESS;
}
int voltage_eq_2_link (int pin1, int pin2, int pin3, int pin4 )
{
EQ_start ();
voltage_eq_item (pin1,pin2);
voltage_eq_item (pin3,pin4);
EQ_end ();
}
/*
* apply KVL for a loop
* path : a sequence of links comprising the path
* length : number of links
*/
void voltage_eq_for_circuit (link_t **path, int length )
{
int i;
float_t vcc;
assert (path);
if (!length) return;
EQ_start ();
/*
* Unfortunately, we don't know the information for the link
* but we can determine it from two consecutive links
*/
if (length == 1) { /* must be a open path, find VCC */
voltage_eq_item ( path[0]->pin_from,path[0]->pin_to);
if (CHECK_NODEFLAG (path[0]->node_id, CVS))
vcc = +nodes[ path[0]->node_id ]->value;
else {
assert (CHECK_NODEFLAG (path[0]->node_id, GND));
vcc = nodes [NODE (path[0]->pin_from)]->value;
}
EQ_add_const (vcc);
}
else {
int last_node;
int first_node;
if (NODE (path[1]->pin_from) == path[0]->node_id
||NODE (path[1]->pin_to) == path[0]->node_id) {
last_node = path[0]->node_id;
first_node = NODE (path[0]->pin_from);
voltage_eq_item ( path[0]->pin_from,path[0]->pin_to);
} else {
last_node = NODE (path[0]->pin_from);
first_node = path[0]->node_id;
voltage_eq_item ( path[0]->pin_to,path[0]->pin_from);
}
for (i = 1; i < length; i ++ ) {
assert (path[i]);
if (NODE (path[i]->pin_from) == last_node ){
last_node = path[i]->node_id;
voltage_eq_item ( path[i]->pin_from,path[i]->pin_to);
} else {
assert (NODE (path[i]->pin_to) == last_node);
last_node = NODE (path[i]->pin_from);
voltage_eq_item ( path[i]->pin_to,path[i]->pin_from);
}
}
if (last_node != first_node) {
if (CHECK_NODEFLAG (last_node, CVS)){
assert (CHECK_NODEFLAG (first_node, GND));
vcc = -nodes [last_node]->value;
} else {
assert (CHECK_NODEFLAG (last_node, GND));
assert (CHECK_NODEFLAG (first_node, CVS));
vcc = +nodes[ first_node ]->value;
}
EQ_add_const (vcc);
}
}
EQ_end ();
}
void voltage_link (link_t *q, int node_ref )
{
EQ_item_t x;
float_t constant;
if (CHECK_NODEFLAG (q->node_id, SOURCE)) {
#if _DEBUG
constant = COMPCLASS (q->pin_from)->U_eq (
COMP (q->pin_from),q->pin_from,q->pin_to, &x );
if (x.next != (EQ_item_t *)-1)
constant += x.coef * vars[ x.var_index ];
assert (fabs(nodes[ q->node_id ]->value + constant -
nodes[ NODE (q->pin_from) ]->value)< FLOAT_EQU_LIMIT);
#endif
return ;
}
constant = COMPCLASS (q->pin_from)->U_eq (
COMP (q->pin_from),q->pin_from,q->pin_to, &x );
if (x.next != (EQ_item_t *)-1)
constant += x.coef * vars[ x.var_index ];
nodes[ q->node_id ]->value = - constant + nodes[ NODE (q->pin_from) ]->value;
WATCH (q->node_id);
WATCHF (nodes[ q->node_id ]->value);
WATCHF (nodes[ node_ref ]->value);
WATCHF (constant);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -