use std::rc::{Rc, Weak};
use std::cell::RefCell;
use gmatlib::{col_vec, Matrix};
use crate::errors::ElementCreationError;
use crate::{flux_formulas::*, get_node_potential, is_locked, lock_node, set_node_potential};
use crate::{GenericElement, GenericNode};
pub const SSDC_CIRCUIT: &str = "ssdc_circuit";
pub const RESISTOR: &str = "resistor";
pub const VOLTAGE_SOURCE: &str = "voltage_source";
pub const CURRENT_SOURCE: &str = "current_source";
pub fn resistor(
input: Weak<RefCell<GenericNode>>,
output: Weak<RefCell<GenericNode>>,
resistance: Vec<f64>,
) -> anyhow::Result<Rc<GenericElement>>
{
GenericElement::try_new(
vec![1.0 / resistance[0]], input, output, normal_flux, false, true, true, )
}
pub fn voltage_source(
input: Weak<RefCell<GenericNode>>,
output: Weak<RefCell<GenericNode>>,
voltage: Vec<f64>,
) -> anyhow::Result<Rc<GenericElement>>
{
if is_locked(&output)? && is_locked(&input)?
{
return Err(ElementCreationError.into())
}
let drives_output = !is_locked(&output)?;
if drives_output
{
lock_node(&output)?;
set_node_potential(&output, (get_node_potential(&input)? + col_vec![voltage[0]]).into())?;
}
else {
lock_node(&input)?;
set_node_potential(&input, (get_node_potential(&output)? + col_vec![voltage[0]]).into())?;
}
let connect_input_node = drives_output;
let connect_output_node = !connect_input_node;
GenericElement::try_new(
voltage,
input, output,
observe_flux,
drives_output,
connect_input_node,
connect_output_node,
)
}
pub fn current_source(
input: Weak<RefCell<GenericNode>>,
output: Weak<RefCell<GenericNode>>,
current: Vec<f64>,
) -> anyhow::Result<Rc<GenericElement>>
{
GenericElement::try_new(
current,
input, output,
constant_flux,
false,
true, true,
)
}