Added jacobian stuff, and tasmet_variable, updated triplets
This commit is contained in:
parent
a8af3fc3e6
commit
a13fa4c5ad
10
src/sys/CMakeLists.txt
Normal file
10
src/sys/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
add_library(sys
|
||||||
|
# enginesystem.cpp
|
||||||
|
globalconf.cpp
|
||||||
|
tasmet_variable.cpp
|
||||||
|
jaccol.cpp
|
||||||
|
jacobian.cpp
|
||||||
|
jacrow.cpp
|
||||||
|
# tasystem.cpp
|
||||||
|
triplets.cpp
|
||||||
|
)
|
@ -3,59 +3,64 @@
|
|||||||
#include "tasmet_exception.h"
|
#include "tasmet_exception.h"
|
||||||
#include "tasmet_io.h"
|
#include "tasmet_io.h"
|
||||||
|
|
||||||
GlobalConf::GlobalConf(us Nf,d freq)
|
GlobalConf::GlobalConf(us Nf,d freq):
|
||||||
|
_Nf(Nf)
|
||||||
{
|
{
|
||||||
|
|
||||||
set(Nf,freq);
|
|
||||||
TRACE(10,"GlobalConf constructor done");
|
TRACE(10,"GlobalConf constructor done");
|
||||||
|
|
||||||
|
if(Nf>=constants::maxNf)
|
||||||
|
throw TaSMETError("Too large number of frequencies given");
|
||||||
|
|
||||||
|
|
||||||
|
us Ns=this->Ns();
|
||||||
|
|
||||||
|
// Reinitialize all operators
|
||||||
|
_iDFT=zeros<dmat>(Ns,Ns);
|
||||||
|
_fDFT=zeros<dmat>(Ns,Ns);
|
||||||
|
|
||||||
|
_fDFT.row(0).fill(1.0/double(Ns));
|
||||||
|
|
||||||
|
for(us i=1;i<=_Nf;i++){
|
||||||
|
for(us j=0; j<Ns;j++){
|
||||||
|
//Row i+1 (cosine components)
|
||||||
|
_fDFT(2*i-1,j)=2.0*cos(2.0*number_pi*double(i)*double(j)/double(Ns))/double(Ns);
|
||||||
|
//Row i (sine components)
|
||||||
|
_fDFT(2*i,j)=-2.0*sin(2.0*number_pi*double(i)*double(j)/double(Ns))/double(Ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iDFT.col(0).fill(1.0); // Steady part
|
||||||
|
for(us k=0;k<Ns;k++){
|
||||||
|
for (us n=1;n<=_Nf;n++){
|
||||||
|
_iDFT(k,2*n-1)=cos(2.0*number_pi*double(n)*double(k)/Ns);
|
||||||
|
_iDFT(k,2*n)=-sin(2.0*number_pi*double(n)*double(k)/Ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setfreq(freq);
|
||||||
|
|
||||||
}
|
}
|
||||||
void GlobalConf::show() const {
|
void GlobalConf::show() const {
|
||||||
cout << "------- Global configuration ------ \n";
|
cout << "------- Global configuration ------ \n";
|
||||||
cout << "------- Number of harmonics to solve for: "<< _Nf <<"\n";
|
cout << "------- Number of harmonics to solve for: "<< _Nf <<"\n";
|
||||||
cout << "------- Fundamental frequency : " << _omg/2/number_pi << " Hz\n";
|
cout << "------- Fundamental frequency : " << _omg/2/number_pi << " Hz\n";
|
||||||
}
|
}
|
||||||
void GlobalConf::set(us Nf,d freq){
|
void GlobalConf::setomg(d omg){
|
||||||
TRACE(15,"GlobalConf::set(_Nf,freq)");
|
TRACE(15,"GlobalConf::set(_Nf,freq)");
|
||||||
d omg = 2*number_pi*freq;
|
|
||||||
//ctor
|
|
||||||
|
_DDTfd=zeros<dmat>(Ns(),Ns());
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if(omg<constants::minomg && omg>constants::maxomg)
|
if(omg<constants::minomg && omg>constants::maxomg)
|
||||||
throw TaSMETError("Illegal frequency given");
|
throw TaSMETError("Illegal frequency given");
|
||||||
if(Nf>=constants::maxNf)
|
|
||||||
throw TaSMETError("Too large number of frequencies given");
|
|
||||||
|
|
||||||
this->_Nf=Nf;
|
|
||||||
this->_omg=omg;
|
this->_omg=omg;
|
||||||
|
|
||||||
us Ns=this->Ns();
|
|
||||||
// Reinitialize all operators
|
|
||||||
iDFT_=zeros<dmat>(Ns,Ns);
|
|
||||||
fDFT_=zeros<dmat>(Ns,Ns);
|
|
||||||
|
|
||||||
DDTfd_=zeros<dmat>(Ns,Ns);
|
|
||||||
fDFT_.row(0).fill(1.0/double(Ns));
|
|
||||||
|
|
||||||
for(us i=1;i<=_Nf;i++){
|
for(us i=1;i<=_Nf;i++){
|
||||||
for(us j=0; j<Ns;j++){
|
_DDTfd(2*i-1,2*i )=-double(i)*_omg;
|
||||||
//Row i+1 (cosine components)
|
_DDTfd(2*i ,2*i-1)=double(i)*_omg;
|
||||||
fDFT_(2*i-1,j)=2.0*cos(2.0*number_pi*double(i)*double(j)/double(Ns))/double(Ns);
|
|
||||||
//Row i (sine components)
|
|
||||||
fDFT_(2*i,j)=-2.0*sin(2.0*number_pi*double(i)*double(j)/double(Ns))/double(Ns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iDFT_.col(0).fill(1.0); // Steady part
|
|
||||||
for(us k=0;k<Ns;k++){
|
|
||||||
for (us n=1;n<=_Nf;n++){
|
|
||||||
iDFT_(k,2*n-1)=cos(2.0*number_pi*double(n)*double(k)/Ns);
|
|
||||||
iDFT_(k,2*n)=-sin(2.0*number_pi*double(n)*double(k)/Ns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(us i=1;i<=_Nf;i++){
|
|
||||||
DDTfd_(2*i-1,2*i )=-double(i)*_omg;
|
|
||||||
DDTfd_(2*i ,2*i-1)=double(i)*_omg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,19 @@
|
|||||||
#ifndef _GLOBALCONF_H_
|
#ifndef _GLOBALCONF_H_
|
||||||
#define _GLOBALCONF_H_
|
#define _GLOBALCONF_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "tasmet_types.h"
|
#include "tasmet_types.h"
|
||||||
#include "tasmet_tracer.h"
|
#include "tasmet_tracer.h"
|
||||||
|
|
||||||
|
class GlobalConf;
|
||||||
|
|
||||||
|
typedef std::shared_ptr<GlobalConf> gc_ptr;
|
||||||
|
|
||||||
class GlobalConf{
|
class GlobalConf{
|
||||||
d _omg; // The "base" frequency in rad/s
|
d _omg; // The "base" frequency in rad/s
|
||||||
us _Nf; // Number of frequencies to solve for
|
us _Nf; // Number of frequencies to solve for
|
||||||
|
|
||||||
dmat fDFT_,iDFT_,DDTfd_;
|
dmat _fDFT,_iDFT,_DDTfd;
|
||||||
// d Wfo_=0; // First order 'upwind' factor. If
|
// d Wfo_=0; // First order 'upwind' factor. If
|
||||||
// Wfo=-1, interpolation is done from
|
// Wfo=-1, interpolation is done from
|
||||||
// the left side. If Wfo=0,
|
// the left side. If Wfo=0,
|
||||||
@ -27,6 +32,10 @@ class GlobalConf{
|
|||||||
public:
|
public:
|
||||||
GlobalConf(us Nf,d freq);
|
GlobalConf(us Nf,d freq);
|
||||||
|
|
||||||
|
const dmat& iDFT = _iDFT; //inverse discrete Fourier transform matrix
|
||||||
|
const dmat& fDFT = _fDFT; //forward discrete Fourier transform matrix
|
||||||
|
const dmat& DDTfd = _DDTfd; //Derivative in frequency domain
|
||||||
|
|
||||||
us Nf() const {return _Nf;}
|
us Nf() const {return _Nf;}
|
||||||
us Ns() const {return 2*_Nf+1;}
|
us Ns() const {return 2*_Nf+1;}
|
||||||
|
|
||||||
@ -35,16 +44,8 @@ public:
|
|||||||
d getfreq() const {return _omg/2/number_pi;}
|
d getfreq() const {return _omg/2/number_pi;}
|
||||||
// d meshPeclet(const Gas& gas,d dx,d u) const {return u*dx*gas.rho0()*gas().cp(T0())/gas().kappa(T0());}
|
// d meshPeclet(const Gas& gas,d dx,d u) const {return u*dx*gas.rho0()*gas().cp(T0())/gas().kappa(T0());}
|
||||||
|
|
||||||
void set(us Nf,d freq); // Set data for new frequency and
|
void setfreq(d freq){setomg(2*number_pi*freq);}
|
||||||
// number of samples
|
void setomg(d omg);
|
||||||
|
|
||||||
void setNf(us Nf){set(Nf,getfreq());}
|
|
||||||
void setfreq(d freq){set(Nf(),freq);}
|
|
||||||
void setomg(d omg) {set(Nf(),omg/(2*number_pi));}
|
|
||||||
|
|
||||||
const dmat& iDFT() const {return iDFT_;} //inverse discrete Fourier transform matrix
|
|
||||||
const dmat& fDFT() const {return fDFT_;} //forward discrete Fourier transform matrix
|
|
||||||
const dmat& DDTfd() const {return DDTfd_;}//Derivative in frequency domain
|
|
||||||
|
|
||||||
void show() const;
|
void show() const;
|
||||||
|
|
||||||
|
70
src/sys/jaccol.cpp
Normal file
70
src/sys/jaccol.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// jaccol.cpp
|
||||||
|
//
|
||||||
|
// last-edit-by: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "jaccol.h"
|
||||||
|
#include "tasmet_variable.h"
|
||||||
|
|
||||||
|
|
||||||
|
JacCol::JacCol(const Variable& thevar):
|
||||||
|
coldof_(thevar.getDofNr()),
|
||||||
|
data_(thevar.getGc().Ns(),thevar.getGc().Ns(),fillwith::zeros)
|
||||||
|
{ }
|
||||||
|
JacCol::JacCol(us coldof,const GlobalConf& gc):
|
||||||
|
coldof_(coldof),
|
||||||
|
data_(gc.Ns(),gc.Ns(),fillwith::zeros)
|
||||||
|
{ }
|
||||||
|
JacCol::JacCol(us coldof,const dmat& data):
|
||||||
|
coldof_(coldof),
|
||||||
|
data_(data)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
JacCol::JacCol(const Variable& thevar,const dmat& data):
|
||||||
|
coldof_(thevar.getDofNr()),
|
||||||
|
data_(data)
|
||||||
|
{ }
|
||||||
|
// JacCol::JacCol(JacCol&& j):
|
||||||
|
// tobeadded(std::move(j.tobeadded)),
|
||||||
|
// coldof_(j.coldof_),
|
||||||
|
// data_(std::move(j.data_))
|
||||||
|
// {
|
||||||
|
// TRACE(45,"JacCol::JacCol(JacCol&&)");
|
||||||
|
// }
|
||||||
|
JacCol::JacCol(const JacCol& j):
|
||||||
|
tobeadded(j.tobeadded),
|
||||||
|
coldof_(j.coldof_),
|
||||||
|
data_(j.data_)
|
||||||
|
{
|
||||||
|
TRACE(5,"JacCol::JacCol(const JacCol& j)");
|
||||||
|
}
|
||||||
|
JacCol& JacCol::operator=(const JacCol& j){
|
||||||
|
TRACE(10,"JacCol::operator=(const JacCol& j)");
|
||||||
|
data_=j.data_;
|
||||||
|
coldof_=j.coldof_;
|
||||||
|
tobeadded=j.tobeadded;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
// JacCol& JacCol::operator=(JacCol&& j){
|
||||||
|
// TRACE(45,"JacCol::operator=(const JacCol& j)");
|
||||||
|
// data_=std::move(j.data_);
|
||||||
|
// coldof_=j.coldof_;
|
||||||
|
// tobeadded=j.tobeadded;
|
||||||
|
// return *this;
|
||||||
|
// }
|
||||||
|
|
||||||
|
JacCol& JacCol::operator+=(const dmat& data){
|
||||||
|
data_+=data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
JacCol& JacCol::operator*=(const d& val){
|
||||||
|
data_*=val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
47
src/sys/jaccol.h
Normal file
47
src/sys/jaccol.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// jaccol.h
|
||||||
|
//
|
||||||
|
// Author: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// A column block of the Jacobian matrix
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
#ifndef JACCOL_H
|
||||||
|
#define JACCOL_H
|
||||||
|
#include "tasmet_types.h"
|
||||||
|
|
||||||
|
class Variable;
|
||||||
|
class GlobalConf;
|
||||||
|
|
||||||
|
|
||||||
|
class JacCol{ // Column block of Jacobian
|
||||||
|
bool tobeadded=true;
|
||||||
|
us coldof_; // First dof of column
|
||||||
|
dmat data_; // data
|
||||||
|
public:
|
||||||
|
JacCol(const Variable&);
|
||||||
|
JacCol(us coldof,const GlobalConf&);
|
||||||
|
JacCol(us coldof,const dmat&);
|
||||||
|
JacCol(const Variable&,const dmat&);
|
||||||
|
// JacCol(JacCol&&); // Move data
|
||||||
|
JacCol(const JacCol&);
|
||||||
|
void prePostMultiply(const dmat& pre,const dmat& post){ data_=pre*data_*post;}
|
||||||
|
JacCol& operator=(const JacCol&);
|
||||||
|
// JacCol& operator=(JacCol&&);
|
||||||
|
|
||||||
|
// Negate all terms
|
||||||
|
JacCol operator-();
|
||||||
|
bool isToAdd() const {return tobeadded;}
|
||||||
|
void setToAdd(bool set){tobeadded=set;} // If this is set to
|
||||||
|
// false, this column will not be added to the row.
|
||||||
|
JacCol& operator+=(const dmat& add);
|
||||||
|
JacCol& operator*=(const double&);
|
||||||
|
dmat& data(){return data_;}
|
||||||
|
const dmat& const_data() const {return data_;}
|
||||||
|
const us& getColDof() const{return coldof_;}
|
||||||
|
void show() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JACCOL_H
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
41
src/sys/jacobian.cpp
Normal file
41
src/sys/jacobian.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "jacobian.h"
|
||||||
|
#include "triplets.h"
|
||||||
|
#include "tasmet_tracer.h"
|
||||||
|
|
||||||
|
void Jacobian::operator+=(const Jacobian& other){
|
||||||
|
TRACE(2,"Jacobian::append()");
|
||||||
|
jacrows.insert(jacrows.end(),other.jacrows.begin(),other.jacrows.end());
|
||||||
|
}
|
||||||
|
void Jacobian::operator+=(const JacRow& other){
|
||||||
|
TRACE(2,"Jacobian::append()");
|
||||||
|
jacrows.push_back(other);
|
||||||
|
}
|
||||||
|
Jacobian::operator TripletList() const{
|
||||||
|
TRACE(18,"Jacobian::operator Tripletlist()");
|
||||||
|
int insertrow,insertcol;
|
||||||
|
TripletList res(ndofs_);
|
||||||
|
const dmat& typicaldatacel=jacrows.at(0).jaccols.at(0).const_data();
|
||||||
|
us size=typicaldatacel.n_rows;
|
||||||
|
|
||||||
|
us i,j;
|
||||||
|
|
||||||
|
for(const JacRow& row: jacrows) {
|
||||||
|
insertrow=row.getRowDof();
|
||||||
|
for(const JacCol& col: row.jaccols){
|
||||||
|
insertcol=col.getColDof();
|
||||||
|
if(insertcol>=0){
|
||||||
|
const dmat& data=col.const_data();
|
||||||
|
for(i=0;i<size;i++){
|
||||||
|
for(j=0;j<size;j++){
|
||||||
|
if(data(i,j)!=0)
|
||||||
|
res.addTriplet(Triplet(i+insertrow,j+insertcol,data(i,j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // insertcol>0
|
||||||
|
} // for loop over cols
|
||||||
|
} // for loop over rows
|
||||||
|
// TRACE(10,"SFSG");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
30
src/sys/jacobian.h
Normal file
30
src/sys/jacobian.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// jacobian.h
|
||||||
|
//
|
||||||
|
// Author: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
#ifndef JACOBIAN_H
|
||||||
|
#define JACOBIAN_H
|
||||||
|
|
||||||
|
#include "jacrow.h"
|
||||||
|
|
||||||
|
class TripletList;
|
||||||
|
|
||||||
|
class Jacobian{
|
||||||
|
us ndofs_;
|
||||||
|
public:
|
||||||
|
Jacobian(us ndofs):ndofs_(ndofs){}
|
||||||
|
vector<JacRow> jacrows;
|
||||||
|
void operator+=(const Jacobian&);
|
||||||
|
void operator+=(const JacRow&);
|
||||||
|
operator TripletList() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JACOBIAN_H
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
58
src/sys/jacrow.cpp
Normal file
58
src/sys/jacrow.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "jacobian.h"
|
||||||
|
#include "tasmet_variable.h"
|
||||||
|
#include "globalconf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JacRow::JacRow(const JacCol& j):
|
||||||
|
JacRow(-1,1)
|
||||||
|
{
|
||||||
|
(*this)+=j;
|
||||||
|
}
|
||||||
|
JacRow::JacRow(us rowdof,const JacCol& j):
|
||||||
|
JacRow(rowdof,1)
|
||||||
|
{
|
||||||
|
(*this)+=j;
|
||||||
|
}
|
||||||
|
// JacRow& JacRow::operator+=(JacCol&& j){
|
||||||
|
// TRACE(45,"JacRow::operator+=(JacCol&& j)");
|
||||||
|
// jaccols.emplace_back(std::move(j));
|
||||||
|
// }
|
||||||
|
JacRow& JacRow::operator+=(const JacCol& j){
|
||||||
|
TRACE(10,"JacRow::operator+=(const JacCol& j)");
|
||||||
|
if(j.isToAdd())
|
||||||
|
jaccols.emplace_back(j);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JacRow& JacRow::addCol(const JacCol& jaccol){
|
||||||
|
// if(jaccol.isToAdd())
|
||||||
|
// jaccols.push_back(jaccol);
|
||||||
|
// return *this;
|
||||||
|
// }
|
||||||
|
JacRow& JacRow::operator*=(const d& val){
|
||||||
|
TRACE(2,"Jacobian::operator*=()");
|
||||||
|
for(JacCol& col: jaccols)
|
||||||
|
col.data()*=val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
JacRow& JacRow::operator+=(const JacRow& other){
|
||||||
|
TRACE(2,"Jacobian::operator*=()");
|
||||||
|
this->jaccols.reserve(this->jaccols.capacity()+other.jaccols.size()-this->jaccols.size());
|
||||||
|
for(const JacCol& col :other.jaccols)
|
||||||
|
(*this)+=col;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
JacRow JacRow::operator-() const{
|
||||||
|
TRACE(15,"JacRow::operator-()");
|
||||||
|
JacRow result(*this);
|
||||||
|
for (JacCol& jaccol : result.jaccols)
|
||||||
|
jaccol*=-1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void JacRow::prePostMultiply(const dmat& pre,const dmat& post) {
|
||||||
|
for(JacCol& jaccol: jaccols)
|
||||||
|
jaccol.prePostMultiply(pre,post);
|
||||||
|
}
|
||||||
|
|
44
src/sys/jacrow.h
Normal file
44
src/sys/jacrow.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// jacrow.h
|
||||||
|
//
|
||||||
|
// Author: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
#ifndef JACROW_H
|
||||||
|
#define JACROW_H
|
||||||
|
|
||||||
|
#include "jaccol.h"
|
||||||
|
|
||||||
|
class Variable;
|
||||||
|
|
||||||
|
|
||||||
|
class JacRow{ // Row in Jacobian matrix
|
||||||
|
int rowdof_=-1; // Number of first row, default is
|
||||||
|
// invalid state
|
||||||
|
public:
|
||||||
|
// Negate all terms
|
||||||
|
JacRow operator-() const;
|
||||||
|
|
||||||
|
vector<JacCol> jaccols; // Column blocks
|
||||||
|
JacRow(const JacCol&);
|
||||||
|
JacRow(us rowdof,const JacCol&); // Initialization with only one column
|
||||||
|
JacRow(int rowdofnr,us cols=2): rowdof_(rowdofnr){ jaccols.reserve(cols);}
|
||||||
|
// void addCol(const JacCol& jaccol);
|
||||||
|
// JacRow& operator+=(JacCol&&);
|
||||||
|
JacRow& operator+=(const JacCol&);
|
||||||
|
JacRow& operator+=(const JacRow& jacrow);
|
||||||
|
JacRow& operator*=(const d& val); // Multiply all terms with constant value
|
||||||
|
void prePostMultiply(const dmat& pre,const dmat& post);
|
||||||
|
const int& getRowDof() const {return rowdof_;}
|
||||||
|
void setRowDof(us dofnr){rowdof_=dofnr;}
|
||||||
|
void show() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // JACROW_H
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
225
src/sys/tasmet_variable.cpp
Normal file
225
src/sys/tasmet_variable.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
// var.cpp
|
||||||
|
//
|
||||||
|
// last-edit-by: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#include "tasmet_variable.h"
|
||||||
|
#include "tasmet_exception.h"
|
||||||
|
#define Ns (_gc->Ns())
|
||||||
|
#define Nf (_gc->Nf())
|
||||||
|
#define fDFT (_gc->fDFT)
|
||||||
|
#define iDFT (_gc->iDFT)
|
||||||
|
#define DDTfd (_gc->DDTfd)
|
||||||
|
|
||||||
|
//******************************************************************************** Operators
|
||||||
|
|
||||||
|
Variable operator*(const double& scalar,const Variable& other){ // Pre-multiplication with scalar
|
||||||
|
TRACE(0,"Variable::operator*(scalar,Variable)");
|
||||||
|
return Variable(other._gc,scalar*other._adata);
|
||||||
|
}
|
||||||
|
Variable Variable::operator/(const Variable& Variable2) const {
|
||||||
|
TRACE(0,"Variable::operator/()");
|
||||||
|
return Variable(this->_gc,this->_tdata/Variable2._tdata,false);
|
||||||
|
}
|
||||||
|
Variable Variable::operator/(d val) const {
|
||||||
|
TRACE(0,"Variable::operator/(double)");
|
||||||
|
return Variable(this->_gc,this->tdata()/val,false);
|
||||||
|
}
|
||||||
|
Variable Variable::operator-(const Variable& other) const{
|
||||||
|
TRACE(0,"Variable::operator-(Variable)");
|
||||||
|
return Variable(this->_gc,_adata-other._adata);
|
||||||
|
}
|
||||||
|
Variable Variable::operator*(d scalar) const {
|
||||||
|
TRACE(0,"Variable::operator*(scalar)"); // Post-multiplication with scalar
|
||||||
|
return Variable(this->_gc,scalar*_adata);
|
||||||
|
}
|
||||||
|
Variable Variable::operator+(const Variable& other) const{
|
||||||
|
TRACE(0,"Variable::operator+()");
|
||||||
|
return Variable(this->_gc,_adata+other._adata);
|
||||||
|
}
|
||||||
|
Variable Variable::operator*(const Variable& Variable2) const { // Multiply two
|
||||||
|
TRACE(0,"Variable::operator*(const Variable& Variable2) const");
|
||||||
|
return Variable(this->_gc,_tdata%Variable2._tdata,false);
|
||||||
|
}
|
||||||
|
//***************************************** The Variable class
|
||||||
|
Variable::Variable(const gc_ptr& gc,double initval): _gc(gc)
|
||||||
|
{
|
||||||
|
TRACE(0,"Variable::Variable(us ndofs, double initval)");
|
||||||
|
|
||||||
|
_tdata=initval*ones(Ns);
|
||||||
|
_adata=zeros(Ns);
|
||||||
|
_adata(0)=initval;
|
||||||
|
}
|
||||||
|
Variable::Variable(const gc_ptr& gc,const vd& data,bool adata): _gc(gc)
|
||||||
|
{ // Create a tasystem and fill it with time data.
|
||||||
|
TRACE(0,"Variable::Variable(gc,_tdata)");
|
||||||
|
if(adata){
|
||||||
|
this->_adata=data;
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this->_tdata=data;
|
||||||
|
_adata=fDFT*_tdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Variable::Variable(const gc_ptr& gc,const vc& data)
|
||||||
|
:Variable(gc)
|
||||||
|
{ // Create a tasystem and fill it with time data.
|
||||||
|
if(data.size()!=Nf+1)
|
||||||
|
throw TaSMETError("Wrong size of amplitude vector given. Does the"
|
||||||
|
"vector size correspond to Ns?");
|
||||||
|
setadata(data);
|
||||||
|
}
|
||||||
|
void Variable::setGc(const gc_ptr& gc){
|
||||||
|
TRACE(10,"Variable::setGc()");
|
||||||
|
this->_gc = gc;
|
||||||
|
updateNf();
|
||||||
|
}
|
||||||
|
void Variable::resetHarmonics(){
|
||||||
|
TRACE(10,"Variable::resetHarmonics()");
|
||||||
|
if(Nf>1){
|
||||||
|
for(us i=3;i<Ns;i++)
|
||||||
|
_adata(i)=0;
|
||||||
|
}
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
Variable::Variable(const Variable& other){
|
||||||
|
TRACE(0,"Variable::Variable(const Variable& other)");
|
||||||
|
this->_gc=other._gc;
|
||||||
|
this->_tdata=other._tdata;
|
||||||
|
this->_adata=other._adata;
|
||||||
|
}
|
||||||
|
Variable& Variable::operator=(const Variable& other){
|
||||||
|
// THIS WOULD COUPLE TO THE WRONG GLOBALCONF when setRes is used
|
||||||
|
// between ducts!!!!!
|
||||||
|
if(this!=&other){
|
||||||
|
if(!this->_gc) {
|
||||||
|
this->_gc=other._gc;
|
||||||
|
}
|
||||||
|
this->_tdata=other._tdata;
|
||||||
|
this->_adata=other._adata;
|
||||||
|
updateNf();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void Variable::updateNf(){
|
||||||
|
TRACE(0,"Variable::updateNf()");
|
||||||
|
us oldsize=_adata.size();
|
||||||
|
assert(oldsize==_tdata.size());
|
||||||
|
assert(_gc);
|
||||||
|
us newsize=Ns;
|
||||||
|
if(oldsize!=newsize){
|
||||||
|
_adata.resize(newsize);
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get methods (which require implementation)
|
||||||
|
d Variable::operator()(us i) const {//Extract result at specific frequency
|
||||||
|
TRACE(-2,"Variable::operator()("<<i<<"), Ns: "<< Ns);
|
||||||
|
if(i>=Ns)
|
||||||
|
throw TaSMETError("Invalid frequency number!");
|
||||||
|
TRACE(-1,"_adata: "<<_adata);
|
||||||
|
return _adata(i);
|
||||||
|
}
|
||||||
|
vc Variable::getcRes() const
|
||||||
|
{
|
||||||
|
TRACE(-2,"Variable::getcRes()");
|
||||||
|
// TRACE(0,"_adata:" << _adata);
|
||||||
|
vc cadata(Nf+1);
|
||||||
|
cadata(0)=_adata(0);
|
||||||
|
for(us i=1;i<Nf+1;i++)
|
||||||
|
cadata(i)=_adata(2*i-1)+I*_adata(2*i); //The minus is very important
|
||||||
|
// TRACE(0,"Resulting cadata:" << cadata);
|
||||||
|
return cadata;
|
||||||
|
}
|
||||||
|
// Set methods
|
||||||
|
void Variable::setadata(us freqnr,d val) { //Set result for specific frequency zero,real one, -imag one, etc
|
||||||
|
TRACE(-2,"Variable::setadata("<<freqnr<<","<<val<<")");
|
||||||
|
if(freqnr>=Ns)
|
||||||
|
throw TaSMETError("Tried to change a value beyond length of the vector");
|
||||||
|
_adata[freqnr]=val;
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
void Variable::setadata(const vc& res)
|
||||||
|
{
|
||||||
|
TRACE(0,"Variable::setadata(const vc& res)");
|
||||||
|
assert(res.size()==Nf+1);
|
||||||
|
_adata(0)=res(0).real();
|
||||||
|
for(us i=1;i<Nf+1;i++){
|
||||||
|
_adata(2*i-1)=res(i).real();
|
||||||
|
_adata(2*i)=res(i).imag();
|
||||||
|
}
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
d min(us a,us b){return a<=b?a:b;}
|
||||||
|
void Variable::setadata(const vd& val) {
|
||||||
|
TRACE(0,"Variable::setadata(const vd& val)");
|
||||||
|
_adata.zeros();
|
||||||
|
us minsize=min(val.size(),_adata.size());
|
||||||
|
for(us i=0;i<minsize;i++)
|
||||||
|
_adata(i)=val(i);
|
||||||
|
_tdata=iDFT*_adata;
|
||||||
|
}
|
||||||
|
void Variable::settdata(double val) {
|
||||||
|
TRACE(0,"Variable::settdata(double val)");
|
||||||
|
for (auto& td: _tdata) {
|
||||||
|
td=val;
|
||||||
|
}
|
||||||
|
_adata=fDFT*_tdata;
|
||||||
|
}
|
||||||
|
void Variable::settdata(const vd& val) {
|
||||||
|
TRACE(0,"Variable::settdata(vd& val)");
|
||||||
|
assert(val.size()==_tdata.size());
|
||||||
|
_tdata=val;
|
||||||
|
_adata=fDFT*_tdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
vd Variable::timeResponse(us nperiod,us ninst) const {
|
||||||
|
TRACE(15,"vd Variable::timeResponse()");
|
||||||
|
vd t=timeResponseTime(nperiod,ninst);
|
||||||
|
vc cres=getcRes();
|
||||||
|
vd res(t.size(),fillwith::zeros);
|
||||||
|
c omg=_gc->getomg();
|
||||||
|
for(us i=0;i<Nf+1;i++)
|
||||||
|
res+=real(cres(i)*exp(((d) i)*omg*I*t));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
vd Variable::timeResponseTime(us nperiod,us ninst) const{
|
||||||
|
d T=1/_gc->getfreq();
|
||||||
|
return linspace(0,nperiod*T,ninst);
|
||||||
|
}
|
||||||
|
dmat Variable::freqMultiplyMat() const{
|
||||||
|
TRACE(0,"Variable::freqMultiplyMat()");
|
||||||
|
dmat result(Ns,Ns,fillwith::zeros);
|
||||||
|
result(0,0)=_adata(0);
|
||||||
|
if(Nf>0){
|
||||||
|
for(us j=1;j<Nf+1;j++){
|
||||||
|
result(2*j-1,2*j-1)= _adata(2*j-1);
|
||||||
|
result(2*j-1,2*j )=-_adata(2*j ); // Yes only one
|
||||||
|
// minus sign
|
||||||
|
result(2*j ,2*j-1)= _adata(2*j);
|
||||||
|
result(2*j ,2*j )= _adata(2*j-1);
|
||||||
|
} // end for loop
|
||||||
|
} // if(Nf>0)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get a tasystem which is the time derivative of the current one
|
||||||
|
Variable Variable::ddt() const {
|
||||||
|
|
||||||
|
vd newadata=DDTfd*_adata;
|
||||||
|
|
||||||
|
return Variable(_gc,newadata);
|
||||||
|
}
|
||||||
|
// The product
|
||||||
|
|
||||||
|
//***************************************** End of the Variable class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
115
src/sys/tasmet_variable.h
Normal file
115
src/sys/tasmet_variable.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// tasmet_variable.h
|
||||||
|
//
|
||||||
|
// Author: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
#ifndef TASMET_VARIABLE_H
|
||||||
|
#define TASMET_VARIABLE_H
|
||||||
|
|
||||||
|
#include "globalconf.h"
|
||||||
|
#include <tasmet_types.h>
|
||||||
|
#include <tasmet_assert.h>
|
||||||
|
|
||||||
|
class Variable; // Forward declaration
|
||||||
|
Variable operator*(const double&,const Variable&);
|
||||||
|
// Variable operator+(const d&,const Variable&);
|
||||||
|
|
||||||
|
class Variable {
|
||||||
|
|
||||||
|
friend Variable operator*(const double&,const Variable&);
|
||||||
|
|
||||||
|
int _dofnr=-1;
|
||||||
|
vd _tdata,_adata;
|
||||||
|
|
||||||
|
gc_ptr _gc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setDofNr(us Dofnr){_dofnr=Dofnr;}
|
||||||
|
int getDofNr() const{return _dofnr;}
|
||||||
|
|
||||||
|
Variable(const gc_ptr&,double); // Initialize with one time-average value
|
||||||
|
Variable(const Variable& o);
|
||||||
|
Variable(const gc_ptr&); // Initialize with zeros
|
||||||
|
|
||||||
|
// Initialize with amplitudedata. With _tdata if adata is set to false
|
||||||
|
Variable(const gc_ptr&,const vd& data,bool adata=true);
|
||||||
|
|
||||||
|
// Assign with frequency domain data
|
||||||
|
Variable(const gc_ptr&,const vc& data);
|
||||||
|
|
||||||
|
Variable& operator=(const Variable&);
|
||||||
|
|
||||||
|
~Variable(){}
|
||||||
|
|
||||||
|
void setGc(const gc_ptr&);
|
||||||
|
const GlobalConf& getGc() const {return *_gc;}
|
||||||
|
void updateNf();
|
||||||
|
|
||||||
|
// Get methods
|
||||||
|
d operator()(us i) const; // Extract amplitude data result at
|
||||||
|
// specific frequency
|
||||||
|
|
||||||
|
operator vd() const {return _adata;}
|
||||||
|
|
||||||
|
// Extract data
|
||||||
|
const vd& tdata() const {return _tdata; } //Get time data
|
||||||
|
const vd& adata() const {return _adata; } //Get time data //vector
|
||||||
|
|
||||||
|
// Obtain a time response vector
|
||||||
|
vd timeResponse(us nperiod=2,us ninst=100) const;
|
||||||
|
// Obtain the corresponding time vector
|
||||||
|
vd timeResponseTime(us nperiod=2,us ninst=100) const;
|
||||||
|
|
||||||
|
dmat diagt() const {return diagmat(_tdata);}
|
||||||
|
dmat diag() const {return diagmat(_adata);}
|
||||||
|
|
||||||
|
//Set/reset methods
|
||||||
|
void resetHarmonics();
|
||||||
|
void updateNDofs(us new_ndofs);
|
||||||
|
|
||||||
|
void setadata(const vd& values); //Set amplitude data vector to these values
|
||||||
|
void settdata(double value); //Set time data to specific value for all time
|
||||||
|
void settdata(const vd& values);
|
||||||
|
void setadata(us freq,double val); //Set result vector at specific frequency
|
||||||
|
void setadata(const vc& values); //Set result vector to these values,
|
||||||
|
|
||||||
|
us size() const {return _adata.size();}
|
||||||
|
// Specific methods to the result using time domain data
|
||||||
|
// Operations ********************
|
||||||
|
|
||||||
|
Variable ddt() const; // Time-derivative of this variable
|
||||||
|
|
||||||
|
Variable operator/(const Variable& Variable2) const; // Time-domain division operator
|
||||||
|
Variable operator/(d value) const; // Time-domain or frequency domain division operator
|
||||||
|
|
||||||
|
// Multiply two Variables in time domain
|
||||||
|
Variable operator*(const Variable& tasystem) const;
|
||||||
|
|
||||||
|
// Multiply a tasystem with a scalar. This operation is possible
|
||||||
|
// for both frequency and time domain data
|
||||||
|
Variable operator*(d scalar) const;
|
||||||
|
|
||||||
|
// add two Variableiables
|
||||||
|
Variable operator+(const Variable& other) const;
|
||||||
|
//Subtract two Variableiables
|
||||||
|
Variable operator-(const Variable& Variable2) const;
|
||||||
|
// with Note multiplication is defined outside of the class
|
||||||
|
|
||||||
|
// If we need to multiply two numbers in frequency domain, this
|
||||||
|
// corresponds to a matrix-vector multiplication (cosines and
|
||||||
|
// sines) are mixed up due to the complex numbers. This product
|
||||||
|
// can be obtained by getting the matrix-Variable of the first
|
||||||
|
// Variable. The following function will give the effective matrix
|
||||||
|
dmat freqMultiplyMat() const;
|
||||||
|
|
||||||
|
// Get the result vector in complex form
|
||||||
|
vc getcRes() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TASMET_VARIABLE_H_ */
|
||||||
|
|
@ -3,6 +3,9 @@
|
|||||||
#include "tasmet_io.h"
|
#include "tasmet_io.h"
|
||||||
#include "tasmet_exception.h"
|
#include "tasmet_exception.h"
|
||||||
|
|
||||||
|
TripletList::TripletList(us ndofs): _ndofs(ndofs) {
|
||||||
|
TRACE(15,"TripletList::TripletList()");
|
||||||
|
}
|
||||||
TripletList::operator sdmat() const {
|
TripletList::operator sdmat() const {
|
||||||
|
|
||||||
TRACE(15,"TripletList::operator sdmat()");
|
TRACE(15,"TripletList::operator sdmat()");
|
||||||
@ -60,11 +63,12 @@ void TripletList::show() const {
|
|||||||
cout << "Row: " << t.row << " , column: " << t.col << " , value: " << t.value << "\n";
|
cout << "Row: " << t.row << " , column: " << t.col << " , value: " << t.value << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TripletList::multiplyTriplets(const d& factor){
|
TripletList& TripletList::operator*=(d factor){
|
||||||
TRACE(15,"multiplyTriplets()");
|
TRACE(15,"multiplyTriplets()");
|
||||||
for(auto tr: triplets){
|
for(auto tr: triplets){
|
||||||
tr.value*= factor;
|
tr.value*= factor;
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TripletList::reserveExtraDofs(us n){
|
void TripletList::reserveExtraDofs(us n){
|
||||||
@ -77,8 +81,12 @@ void TripletList::shiftTriplets(int nrows,int ncols){
|
|||||||
// shift the position of the values in a matrix. nrows and ncols
|
// shift the position of the values in a matrix. nrows and ncols
|
||||||
// can be negative numbers.
|
// can be negative numbers.
|
||||||
TRACE(15,"shiftTriplets()");
|
TRACE(15,"shiftTriplets()");
|
||||||
TRACE(100,"EXTRA CHECKS HERE!");
|
|
||||||
for(auto tr: triplets){
|
for(auto tr: triplets){
|
||||||
|
#if TASMET_DEBUG == 1
|
||||||
|
if(tr.col+ncols >= _ndofs || (tr.row+nrows >= _ndofs)) {
|
||||||
|
FATAL("Out of bounds shift");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tr.col+=ncols;
|
tr.col+=ncols;
|
||||||
tr.row+=nrows;
|
tr.row+=nrows;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
// Make one row zero
|
// Make one row zero
|
||||||
void zeroOutRow(us rownr);
|
void zeroOutRow(us rownr);
|
||||||
|
|
||||||
void multiplyTriplets(const d& multiplicationfactor);
|
TripletList& operator*=(d multiplicationfactor);
|
||||||
|
|
||||||
// Add to capacity
|
// Add to capacity
|
||||||
void reserveExtraDofs(us n);
|
void reserveExtraDofs(us n);
|
||||||
|
Loading…
Reference in New Issue
Block a user