1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/plugins/models/simple_circuit.c

191 lines
No EOL
5.8 KiB
C

/** This is c-code for CBuilder component for Subsystem 2
* Solver used as in RTDS: Resistive companion (Dommel's algo)
* Subsystem 1 is modelled in RSCAD
*
* % Circuit topology
* %
* % *** Subsystem 1 (SS1) *** % *** Subsystem 2 (SS2) ***
* % %
* % |---------| |---------| %
* % |---------| R1 |-------| L1 |----%-------|---------|
* % | |---------| |---------| % | |
* % | % | |
* % ----- % ----- -----
* % | + | % | | | |
* % | E | % |C2 | | R2|
* % | - | % | | | |
* % ----- % ----- -----
* % | % | |
* % |------------------------------------------%------------------
* %
* %
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASnode
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
/* Variables declared here may be used as parameters inputs or outputs
* The have to match with whats in Subsystem.h */
#if defined(VILLAS) || SECTION == INPUTS
double IntfIn;
#endif /* defined(VILLAS) || SECTION == INPUTS */
#if defined(VILLAS) || SECTION == OUTPUTS
double IntfOut;
#endif /* defined(VILLAS) || SECTION == OUTPUTS */
#if defined(VILLAS) || SECTION == PARAMS
double R2; /**< Resistor [Ohm] in SS2 */
double C2; /**< Capacitance [F] in SS2 */
#endif /* defined(VILLAS) || SECTION == PARAMS */
/* Variables declared here may be used in both the RAM: and CODE: sections below. */
#if defined(VILLAS) || SECTION == STATIC
double dt;
double GR2, GC2; /**< Inductances of components */
double GnInv; /**< Inversion of conductance matrix (here only scalar) */
double vC2Hist, iC2Hist, AC2; /**< History meas. and current of dynamic elements */
double Jn; /**< Source vector in equation Gn*e=Jn */
double eSS2; /**< Node voltage solution */
#endif /* defined(VILLAS) || SECTION == STATIC */
/* This section should contain any 'c' functions
* to be called from the RAM section (either
* RAM_PASS1 or RAM_PASS2). Example:
*
* static double myFunction(double v1, double v2)
* {
* return(v1*v2);
* }
*/
#if defined(VILLAS) || SECTION == RAM_FUNCTIONS
/* Nothing here */
#endif /* defined(VILLAS) || SECTION == RAM_FUNCTIONS */
/* Place C code here which computes constants
* required for the CODE: section below. The C
* code here is executed once, prior to the start
* of the simulation case.
*/
#if defined(VILLAS) || SECTION == RAM
void simple_circuit_ram() {
GR2 = 1/R2;
GC2 = 2*C2/dt; /**< Trapezoidal rule */
GnInv = 1/(GR2+GC2); /**< eq. conductance (inverted) */
vC2Hist = 0.0; /**< Voltage over C2 in previous time step */
iC2Hist = 0.0; /**< Current through C2 in previous time step */
}
#endif /* defined(VILLAS) || SECTION == RAM */
// -----------------------------------------------
// Place C code here which runs on the RTDS. The
// code below is entered once each simulation
// step.
// -----------------------------------------------
#if defined(VILLAS) || SECTION == CODE
void simple_circuit_code() {
/* Update source vector */
AC2 = iC2Hist+vC2Hist*GC2;
Jn = IntfIn+AC2;
/* Solution of the equation Gn*e=Jn; */
eSS2 = GnInv*Jn;
/* Post step -> calculate the voltage and current for C2 for next step and set interface output */
vC2Hist= eSS2;
iC2Hist = vC2Hist*GC2-AC2;
IntfOut = eSS2;
}
#endif /* defined(VILLAS) || SECTION == CODE */
/* Interface to VILLASnode */
#if defined(VILLAS)
#include <villas/nodes/cbuilder.h>
#include <villas/plugin.h>
double getTimeStep()
{
return dt;
}
/** Place C code here which intializes parameters */
int simple_circuit_init(struct cbuilder *cb)
{
if (cb->paramlen < 2)
return -1; /* not enough parameters given */
R2 = cb->params[0];
C2 = cb->params[1];
/* 'dt' is a special parameter */
dt = cb->timestep;
return 0; /* success */
}
/** Place C code here reads model outputs */
int simple_circuit_read(float outputs[], int len)
{
if (len < 1)
return -1; /* not enough space */
outputs[0] = IntfOut;
return 1; /* 1 value per sample */
}
/** Place C code here which updates model inputs */
int simple_circuit_write(float inputs[], int len)
{
if (len < 1)
return -1; /* not enough values */
IntfIn = inputs[0];
return 0;
}
static struct plugin p = {
.name = "simple_circuit",
.description = "A simple CBuilder model",
.type = PLUGIN_TYPE_MODEL_CBUILDER,
.cb = {
.code = simple_circuit_code,
.init = simple_circuit_init,
.read = simple_circuit_read,
.write = simple_circuit_write,
.ram = simple_circuit_ram
}
};
REGISTER_PLUGIN(&p)
#endif /* defined(VILLAS) */