/////////////////////////////////////////////////////////////////////////////
// simlib2D.cc
//
// SIMLIB version: 2.18
// Date: 2004-01-25
//
// Copyright (c) 1997-2004 Petr Peringer
//
// This library is licensed under GNU Library GPL. See the file COPYING.
//
//
// 2D extension
//
// - Integrator2D
// - blocks for + - * / operations
//
////////////////////////////////////////////////////////////////////////////
// interface
//
#include "simlib.h"
#include "simlib2D.h"
#include "internal.h"
#include <cmath>
////////////////////////////////////////////////////////////////////////////
// implementation
//
SIMLIB_IMPLEMENTATION
////////////////////////////////////////////////////////////////////////////
// non-block operations
//
double abs(const Value2D &a)
{
return sqrt( a._x * a._x + a._y * a._y );
}
Value2D operator +(const Value2D& a, const Value2D &b)
{
return Value2D( a._x + b._x, a._y + b._y );
}
Value2D operator -(const Value2D& a, const Value2D &b)
{
return Value2D( a._x - b._x, a._y - b._y );
}
Value2D operator -(const Value2D& a)
{
return Value2D( -a._x, -a._y);
}
/*
Value2D operator *(const Value2D& a, const Value2D &b)
{
return Value2D( a._y * b._z - a._z * b._y,
a._z * b._x - a._x * b._z,
a._x * b._y - a._y * b._x
);
}
*/
Value2D operator *(const Value2D& a, const double b)
{
return Value2D( a._x * b, a._y * b );
}
Value2D operator *(const double a, const Value2D& b)
{
return b * a;
}
double scalar_product(const Value2D& a, const Value2D &b)
{
return a._x * b._x + a._y * b._y ;
}
Value2D operator /(const Value2D& a, const double b)
{
return Value2D( a._x / b, a._y / b );
}
////////////////////////////////////////////////////////////////////////////
// aContiBlock2D --- constructor & destructor
//
aContiBlock2D::aContiBlock2D():
isEvaluated(false)
{
dprintf(("2Dblock-ctr"));
}
aContiBlock2D::~aContiBlock2D() {
dprintf(("2Dblock-dtr"));
}
////////////////////////////////////////////////////////////////////////////
// aContiBlock2D::Print --- print of 2D block output value
//
void aContiBlock2D::Print() {
Value2D a = Value();
a.Print();
}
////////////////////////////////////////////////////////////////////////////
// aContiBlock::_Eval --- evaluation with algebraic loop detection ###
//
void aContiBlock2D::_Eval()
{
if(isEvaluated) // was evaluated
SIMLIB_error(AlgLoopDetected); // recursive call
isEvaluated = true; // eval-flag
Eval(); // evaluation of block
isEvaluated = false;
}
////////////////////////////////////////////////////////////////////////////
// Parameter2D --- parameter of model
//
Parameter2D &Parameter2D::operator= (const Value2D &x) {
if(SIMLIB_Phase==SIMULATION)
SIMLIB_error(ParameterChangeErr);
value = x;
return *this;
}
////////////////////////////////////////////////////////////////////////////
// aContiBlock1 --- base for blocks with one input
//
aContiBlock2D1::aContiBlock2D1(Input2D i) : input(i)
{
if(input==this)
SIMLIB_error(AlgLoopDetected);
// LoopCheck();
}
////////////////////////////////////////////////////////////////////////////
// Integrator2D::special_input::Value() --- expects 2 subsequent evaluations
//
// return scalar value for scalar integrator
// two evaluations are guaranteed by Integrator2D
//
double Integrator2D::special_input::Value() { // interface class
if(count == 0)
a = in.Value(); // get vector input (x,y)
switch(++count) {
case 1: return a.x(); // first call (x)
case 2: count=0; // second call (y)
return a.y();
} // switch
SIMLIB_internal_error(); // *** never reached ***
return 0; // compiler warning elimination
}
////////////////////////////////////////////////////////////////////////////
// Integrator2D --- constructors
//
Integrator2D::Integrator2D(Input2D i, Value2D initial_value):
_x(in, initial_value.x()), // linking of inputs to integrators
_y(in, initial_value.y()),
in(i) {}
Integrator2D::Integrator2D(Input2D i):
_x(in), _y(in),
in(i) {}
// --- special copy constructor
Integrator2D::Integrator2D(Integrator2D &i, Value2D initial_value):
_x(in, initial_value.x()), // linking of inputs to integrators
_y(in, initial_value.y()),
in(i) {}
// zero input for default Integrator2D constructor
// we need it for creating arrays of integrators
static Constant2D Zero2D(0,0);
Integrator2D::Integrator2D():
_x(in), _y(in),
in(Zero2D) {}
////////////////////////////////////////////////////////////////////////////
// operator = --- assign new value
//
Integrator2D &Integrator2D::operator = (const Value2D &a)
{
_x=a.x();
_y=a.y();
return *this;
}
Integrator2D &Integrator2D::operator = (Input2D i)
{
Value2D a = i.Value();
_x=a.x();
_y=a.y();
return *this;
}
////////////////////////////////////////////////////////////////////////////
// Integrator2D output method
//
Value2D Integrator2D::Value()
{
return Value2D(_x.Value(), _y.Value());
}
////////////////////////////////////////////////////////////////////////////
// aContiBlock2 --- base for 2 input blocks
//
aContiBlock2D2::aContiBlock2D2(Input2D i1, Input2D i2)
: input1(i1), input2(i2)
{
if(input1==this || input2==this)
SIMLIB_error(AlgLoopDetected);
// LoopCheck();
}
aContiBlock2D3::aContiBlock2D3(Input2D i1, Input2D i2, Input2D i3)
: aContiBlock2D2(i1,i2), input3(i3)
{
if(input3==this )
SIMLIB_error(AlgLoopDetected);
}
////////////////////////////////////////////////////////////////////////////
// Add --- sum of two inputs
//
class _Add2D : public aContiBlock2D2 {
virtual void _Eval() {}
public:
_Add2D(Input2D a, Input2D b): aContiBlock2D2(a,b) {
dprintf(("ctr: _Add2D[%p](in1,in2)", this));
}
virtual Value2D Value() {
Value2D a = Input1Value();
Value2D b = Input2Value();
return a + b;
}
};
////////////////////////////////////////////////////////////////////////////
// Sub --- subtract two inputs
//
class _Sub2D : public aContiBlock2D2 {
virtual void _Eval() {}
public:
_Sub2D(Input2D a, Input2D b): aContiBlock2D2(a,b) {
dprintf(("ctr: _Sub2D[%p](in1,in2)", this));
}
virtual Value2D Value() {
Value2D a = Input1Value();
Value2D b = Input2Value();
return a - b;
}
};
////////////////////////////////////////////////////////////////////////////
// Mul --- multiplier vector * scalar
//
class _Mul2D1D : public aContiBlock2D1 {
Input _b;
virtual void _Eval() {}
public:
_Mul2D1D(Input2D a, Input b): aContiBlock2D1(a), _b(b) {
dprintf(("ctr: _Mul2D1D[%p](in1,in2)", this));
}
virtual Value2D Value() {
Value2D a = InputValue();
double b = _b.Value();
return a * b;
}
};
////////////////////////////////////////////////////////////////////////////
// Div --- divider vector / scalar
//
class _Div2D : public aContiBlock2D1 {
Input _b;
virtual void _Eval() {}
public:
_Div2D(Input2D a, Input b): aContiBlock2D1(a), _b(b) {
dprintf(("ctr: _Div2D[%p](in1_2D,in2)", this));
}
virtual Value2D Value() {
Value2D a = InputValue();
double b = _b.Value();
return a / b;
}
};
////////////////////////////////////////////////////////////////////////////
// binary operators ...
//
// wrapper operator functions for block expressions
//
Input2D operator + (Input2D a, Input2D b) { return new _Add2D(a,b); }
Input2D operator - (Input2D a, Input2D b) { return new _Sub2D(a,b); }
Input2D operator * (Input2D a, Input b) { return new _Mul2D1D(a,b); }
Input2D operator * (Input a, Input2D b) { return new _Mul2D1D(b,a); }
Input2D operator / (Input2D a, Input b) { return new _Div2D(a,b); }
////////////////////////////////////////////////////////////////////////////
// UMinus --- unary minus
//
class _UMinus2D: public aContiBlock2D1 {
virtual void _Eval() {}
public:
_UMinus2D(Input2D a): aContiBlock2D1(a) {
dprintf(("ctr: _UMinus2D[%p](in)", this));
}
virtual Value2D Value() {
Value2D a = InputValue();
return -a;
}
};
////////////////////////////////////////////////////////////////////////////
// unary operators ...
//
Input2D operator - (Input2D a) { return new _UMinus2D(a); }
////////////////////////////////////////////////////////////////////////////
// functions for block expressions
//
////////////////////////////////////////////////////////////////////////////
// _Abs2D --- absolute value of vector x
//
class _Abs2D: public aContiBlock {
virtual void _Eval() {}
Input2D in;
public:
_Abs2D(Input2D a): in(a) {}
virtual double Value() {
Value2D a = in.Value();
return abs(a);
}
};
////////////////////////////////////////////////////////////////////////////
// _Norm2D --- unit vector = vector x/Abs(x)
//
class _Norm2D: public aContiBlock2D1 {
virtual void _Eval() {}
public:
_Norm2D(Input2D a): aContiBlock2D1(a) {}
virtual Value2D Value() {
Value2D a = InputValue();
return a/abs(a);
}
};
////////////////////////////////////////////////////////////////////////////
// _ScalarProduct2D --- scalar multiply
//
class _ScalarProduct2D: public aContiBlock {
virtual void _Eval() {}
Input2D input1;
Input2D input2;
public:
_ScalarProduct2D(Input2D a, Input2D b): input1(a), input2(b) {}
virtual double Value() {
Value2D a = input1.Value();
Value2D b = input2.Value();
return scalar_product(a,b);
}
};
////////////////////////////////////////////////////////////////////////////
// wrapper functions for block expressions
//
Input Abs(Input2D x) { return new _Abs2D(x); } // absolute value of vector x
Input2D UnitVector(Input2D x) { return new _Norm2D(x); }
Input ScalarProduct(Input2D x, Input2D y) { return new _ScalarProduct2D(x,y); }
////////////////////////////////////////////////////////////////////////////
// _XYpart --- vector part
//
class _XYpart: public aContiBlock {
virtual void _Eval() {}
Input2D input;
public:
enum WhichPart { x,y }; // part identification
_XYpart(Input2D a, WhichPart w): input(a), which(w) {}
virtual double Value() {
Value2D a = input.Value();
switch(which) {
case x: return a.x();
case y: return a.y();
}
SIMLIB_internal_error(); // *** never reached ***
return 0; // compiler warning elimination
}
private:
WhichPart which;
};
////////////////////////////////////////////////////////////////////////////
// get x,y part of vector block
//
// wrapper functions for block expressions
//
Input Xpart(Input2D a) { return new _XYpart(a, _XYpart::x); }
Input Ypart(Input2D a) { return new _XYpart(a, _XYpart::y); }
////////////////////////////////////////////////////////////////////////////
// end
////////////////////////////////////////////////////////////////////////////
syntax highlighted by Code2HTML, v. 0.9.1