Model residual is calculatable. Now Jacobian
This commit is contained in:
parent
696ba04422
commit
c818655c0c
@ -91,22 +91,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake_tools)
|
|||||||
# Python #####################
|
# Python #####################
|
||||||
# ##########################
|
# ##########################
|
||||||
|
|
||||||
include_directories(/usr/include/PythonQt)
|
|
||||||
|
|
||||||
|
|
||||||
if(TaSMET_PY_VERSION)
|
|
||||||
# Find major version from version string
|
|
||||||
set(PYTHON_LIBRARY "/usr/lib/libpython${TaSMET_PY_VERSION}.so")
|
|
||||||
set(PYTHON_INCLUDE_DIR "/usr/include/python${TaSMET_PY_VERSION}")
|
|
||||||
set(PYTHON_INCLUDE_DIRS "/usr/include/python${TaSMET_PY_VERSION}")
|
|
||||||
|
|
||||||
endif(TaSMET_PY_VERSION)
|
|
||||||
message("Python include dirs: ${PYTHON_INCLUDE_DIRS}")
|
|
||||||
|
|
||||||
find_package(PythonLibs REQUIRED)
|
|
||||||
string(REGEX MATCH "^." TaSMET_PY_MAJOR_VERSION ${PYTHONLIBS_VERSION_STRING})
|
|
||||||
MESSAGE("Python major version: ${TaSMET_PY_MAJOR_VERSION}")
|
|
||||||
|
|
||||||
# Find the site_packages directory of python
|
# Find the site_packages directory of python
|
||||||
execute_process(COMMAND python${TaSMET_PY_MAJOR_VERSION} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND python${TaSMET_PY_MAJOR_VERSION} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
@ -120,7 +104,6 @@ add_definitions(-DARMA_USE_SUPERLU -DARMA_USE_CXX11)
|
|||||||
# link_directories(common)
|
# link_directories(common)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${PYTHON_INCLUDE_DIRS}
|
|
||||||
src
|
src
|
||||||
src/solver
|
src/solver
|
||||||
src/material
|
src/material
|
||||||
@ -135,5 +118,5 @@ add_subdirectory(testing)
|
|||||||
|
|
||||||
add_executable(tasmet src/main.cpp src/gui/tasmet_resources.qrc)
|
add_executable(tasmet src/main.cpp src/gui/tasmet_resources.qrc)
|
||||||
add_executable(tasmet_solvemodel src/tasmet_solvemodel.cpp)
|
add_executable(tasmet_solvemodel src/tasmet_solvemodel.cpp)
|
||||||
target_link_libraries(tasmet tasmet_gui tasmet_src messages PythonQt Qt5::Widgets chaiscript_stdlib-5.7.0 openblas)
|
target_link_libraries(tasmet tasmet_gui tasmet_src messages Qt5::Widgets chaiscript_stdlib-5.7.0 openblas)
|
||||||
target_link_libraries(tasmet_solvemodel tasmet_src messages PythonQt openblas chaiscript_stdlib-5.7.0)
|
target_link_libraries(tasmet_solvemodel tasmet_src messages openblas chaiscript_stdlib-5.7.0)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "tasystem.h"
|
#include "tasystem.h"
|
||||||
#include "tasmet_assert.h"
|
#include "tasmet_assert.h"
|
||||||
#include "tasmet_evalscript.h"
|
#include "tasmet_evalscript.h"
|
||||||
|
#include "perfectgas.h"
|
||||||
|
|
||||||
Duct::Duct(const us id,const pb::Duct& ductpb):
|
Duct::Duct(const us id,const pb::Duct& ductpb):
|
||||||
Segment(id,ductpb.name()),
|
Segment(id,ductpb.name()),
|
||||||
@ -62,11 +62,127 @@ Duct::~Duct() {
|
|||||||
void Duct::residual(const TaSystem& sys,arma::subview_col<d> && residual) const {
|
void Duct::residual(const TaSystem& sys,arma::subview_col<d> && residual) const {
|
||||||
|
|
||||||
TRACE(15,"Duct::residual()");
|
TRACE(15,"Duct::residual()");
|
||||||
|
|
||||||
const arma::subview_col<d> sol = sys.getSolution(_id);
|
const arma::subview_col<d> sol = sys.getSolution(_id);
|
||||||
|
|
||||||
VARTRACE(15,sol(0));
|
vd rho,u,T,p,Ts; // Solution at this gp
|
||||||
|
vd rhop,up,Tp,pp,Tsp; // Solution at next gp
|
||||||
|
|
||||||
|
// Continuity eq residual, momentum, energy, state, solid energy
|
||||||
|
vd cont,mom,en,st,sen;
|
||||||
|
|
||||||
|
// When we have to solve a solid heat balance
|
||||||
|
bool has_solideq = _ductpb.stempmodel() == pb::HeatBalance;
|
||||||
|
|
||||||
|
us number_eqs = 4;
|
||||||
|
number_eqs += (has_solideq) ? 1 : 0;
|
||||||
|
|
||||||
|
VARTRACE(15,number_eqs);
|
||||||
|
|
||||||
|
us Ns = sys.Ns();
|
||||||
|
us eq_offset = 0; // Equation offset for current gp
|
||||||
|
us res_offset = 0; // Residual offset for current gp
|
||||||
|
us res_offsetp = 0; // Residual offset for next gp
|
||||||
|
|
||||||
|
us gp_jump = number_eqs * Ns; // The jump per gp
|
||||||
|
|
||||||
|
rhop = getvart(sys,constants::rho,0);
|
||||||
|
up = getvart(sys,constants::u,0);
|
||||||
|
Tp = getvart(sys,constants::T,0);
|
||||||
|
pp = getvart(sys,constants::p,0);
|
||||||
|
|
||||||
|
const Gas& gas = sys.gas();
|
||||||
|
|
||||||
|
for(us gp=0;gp<ngp()-1;gp++) {
|
||||||
|
|
||||||
|
eq_offset = gp*Ns*number_eqs;
|
||||||
|
res_offset = eq_offset;
|
||||||
|
res_offsetp = res_offset + gp_jump;
|
||||||
|
|
||||||
|
d dx = x(gp+1)-x(gp);
|
||||||
|
|
||||||
|
// Update the current gp solution
|
||||||
|
rho = rhop; u=up; T=Tp; p = pp; Ts=Tsp;
|
||||||
|
|
||||||
|
// Update the next gp solution
|
||||||
|
rhop = getvart(sys,constants::rho,gp+1);
|
||||||
|
up = getvart(sys,constants::u,gp+1);
|
||||||
|
Tp = getvart(sys,constants::T,gp+1);
|
||||||
|
pp = getvart(sys,constants::p,gp+1);
|
||||||
|
|
||||||
|
cont = ((rhop%up)-(rho%u))/dx;
|
||||||
|
|
||||||
|
mom = (rhop%up%up - rho%u%u + pp - p)/dx;
|
||||||
|
|
||||||
|
switch (_ductpb.htmodel()) {
|
||||||
|
case pb::Isentropic: {
|
||||||
|
|
||||||
|
d T0 = gas.T0();
|
||||||
|
d p0 = gas.p0();
|
||||||
|
d rho0 = gas.rho0();
|
||||||
|
d gamma0 = gas.gamma(T0,p0);
|
||||||
|
|
||||||
|
en = p/p0 - pow(rho/rho0,gamma0);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tasmet_assert(false,"Not implemented htmodel");
|
||||||
|
}
|
||||||
|
|
||||||
|
st = gas.rho(T,p) - rho;
|
||||||
|
|
||||||
|
residual.subvec(eq_offset+0*Ns,eq_offset+1*Ns-1) = cont;
|
||||||
|
residual.subvec(eq_offset+1*Ns,eq_offset+2*Ns-1) = mom;
|
||||||
|
residual.subvec(eq_offset+2*Ns,eq_offset+3*Ns-1) = en;
|
||||||
|
residual.subvec(eq_offset+3*Ns,eq_offset+4*Ns-1) = st;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
eq_offset += number_eqs*Ns;
|
||||||
|
|
||||||
|
// Equation of state for the last node
|
||||||
|
st = gas.rho(Tp,pp) - rhop;
|
||||||
|
residual.subvec(eq_offset,eq_offset+Ns-1) = st;
|
||||||
|
|
||||||
|
// Two more equations for the last grid point in case
|
||||||
|
// the heat transfer model is not a transport equation.
|
||||||
|
if(_ductpb.htmodel() == pb::Isentropic) {
|
||||||
|
|
||||||
|
eq_offset += Ns;
|
||||||
|
|
||||||
|
d T0 = gas.T0();
|
||||||
|
d p0 = gas.p0();
|
||||||
|
d rho0 = gas.rho0();
|
||||||
|
d gamma0 = gas.gamma(T0,p0);
|
||||||
|
|
||||||
|
en = p/p0 - pow(rho/rho0,gamma0);
|
||||||
|
|
||||||
|
residual.subvec(eq_offset,eq_offset+Ns-1) = en;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
vd Duct::getvart(const TaSystem& sys,int varnr,int gp) const {
|
||||||
|
TRACE(15,"Duct::getvart()");
|
||||||
|
const arma::subview_col<d> sol = sys.getSolution(_id);
|
||||||
|
|
||||||
|
us Ns = sys.Ns();
|
||||||
|
|
||||||
|
// Wraparound
|
||||||
|
if(gp<0) gp+=ngp();
|
||||||
|
|
||||||
|
us vars_per_gp = 4;
|
||||||
|
vars_per_gp+= (_ductpb.stempmodel() == pb::HeatBalance ? 1 : 0);
|
||||||
|
|
||||||
|
return sol.subvec((gp*vars_per_gp+varnr)*Ns,
|
||||||
|
(gp*vars_per_gp+varnr+1)*Ns-1);
|
||||||
|
}
|
||||||
|
vd Duct::getvarx(const TaSystem& sys,int varnr,int t) const {
|
||||||
|
vd res(ngp());
|
||||||
|
for(us i=0;i<ngp();i++){
|
||||||
|
res(i) = getvart(sys,varnr,i)(t);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
vd Duct::initialSolution(const TaSystem& sys) const {
|
vd Duct::initialSolution(const TaSystem& sys) const {
|
||||||
|
|
||||||
@ -87,7 +203,7 @@ vd Duct::initialSolution(const TaSystem& sys) const {
|
|||||||
// Initial density
|
// Initial density
|
||||||
|
|
||||||
initsol.subvec((i*vars_per_gp+0)*Ns,(i*vars_per_gp+1)*Ns-1) =
|
initsol.subvec((i*vars_per_gp+0)*Ns,(i*vars_per_gp+1)*Ns-1) =
|
||||||
gas.rho0();
|
gas.rho0()+.01;
|
||||||
|
|
||||||
// Initial velocity
|
// Initial velocity
|
||||||
initsol.subvec((i*vars_per_gp+1)*Ns,(i*vars_per_gp+2)*Ns-1) =
|
initsol.subvec((i*vars_per_gp+1)*Ns,(i*vars_per_gp+2)*Ns-1) =
|
||||||
@ -115,20 +231,35 @@ vd Duct::initialSolution(const TaSystem& sys) const {
|
|||||||
us Duct::getNEqs(const TaSystem& sys) const {
|
us Duct::getNEqs(const TaSystem& sys) const {
|
||||||
TRACE(15,"Duct::getNEqs()");
|
TRACE(15,"Duct::getNEqs()");
|
||||||
us Ns = sys.Ns();
|
us Ns = sys.Ns();
|
||||||
|
|
||||||
|
// The number of equations per gridpoint. We have: continuity,
|
||||||
|
// momentum, energy, and state
|
||||||
us number_eqs = 4;
|
us number_eqs = 4;
|
||||||
|
|
||||||
// When we have to solve a solid heat balance
|
// When we have to solve a solid heat balance
|
||||||
number_eqs+= (_ductpb.stempmodel() == pb::HeatBalance ? 1 : 0);
|
number_eqs+= (_ductpb.stempmodel() == pb::HeatBalance ? : 0);
|
||||||
|
|
||||||
return Ns*number_eqs*(ngp()-1);
|
us neqs = Ns*number_eqs*(ngp()-1);
|
||||||
|
|
||||||
|
// For the last gridpoint, we also have an equation of state
|
||||||
|
neqs += Ns;
|
||||||
|
|
||||||
|
// We also have an extra equation for isentropic. For the energy
|
||||||
|
// transport equation, this would result in a boundary condition
|
||||||
|
if(_ductpb.htmodel() == pb::Isentropic) {
|
||||||
|
neqs += Ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARTRACE(15,neqs);
|
||||||
|
return neqs;
|
||||||
}
|
}
|
||||||
us Duct::getNDofs(const TaSystem& sys) const {
|
us Duct::getNDofs(const TaSystem& sys) const {
|
||||||
TRACE(15,"Duct::getNDofs()");
|
TRACE(15,"Duct::getNDofs()");
|
||||||
us Ns = sys.Ns();
|
us Ns = sys.Ns();
|
||||||
|
|
||||||
// rho,u,T,p,Ts
|
// rho,u,T,p
|
||||||
us nvars_per_gp = 4;
|
us nvars_per_gp = 4;
|
||||||
|
// Ts maybe
|
||||||
nvars_per_gp += (_ductpb.stempmodel() == pb::HeatBalance ? 1 : 0);
|
nvars_per_gp += (_ductpb.stempmodel() == pb::HeatBalance ? 1 : 0);
|
||||||
|
|
||||||
return Ns*nvars_per_gp*ngp();
|
return Ns*nvars_per_gp*ngp();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "segment.h"
|
#include "segment.h"
|
||||||
#include "duct.pb.h"
|
#include "duct.pb.h"
|
||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
|
#include "tasmet_constants.h" // For the variable nrs
|
||||||
|
|
||||||
class Equation;
|
class Equation;
|
||||||
class Drag;
|
class Drag;
|
||||||
@ -43,6 +44,28 @@ public:
|
|||||||
|
|
||||||
const pb::Duct& getDuctPb() const { return _ductpb;}
|
const pb::Duct& getDuctPb() const { return _ductpb;}
|
||||||
|
|
||||||
|
// Obtain values as a function of position, for a given time
|
||||||
|
// instance.
|
||||||
|
vd rhox(const TaSystem& sys,int t) const { return getvarx(sys,constants::rho,t);}
|
||||||
|
vd ux(const TaSystem& sys,int t) const { return getvarx(sys,constants::u,t); }
|
||||||
|
vd Tx(const TaSystem& sys,int t) const { return getvarx(sys,constants::T,t); }
|
||||||
|
vd px(const TaSystem& sys,int t) const { return getvarx(sys,constants::p,t); }
|
||||||
|
vd Tsx(const TaSystem& sys,int t) const { return getvarx(sys,constants::Ts,t); }
|
||||||
|
|
||||||
|
vd rhot(const TaSystem& sys,int gp) const { return getvart(sys,constants::rho,gp); }
|
||||||
|
vd ut(const TaSystem& sys,int gp) const { return getvart(sys,constants::u,gp); }
|
||||||
|
vd Tt(const TaSystem& sys,int gp) const { return getvart(sys,constants::T,gp); }
|
||||||
|
vd pt(const TaSystem& sys,int gp) const { return getvart(sys,constants::p,gp); }
|
||||||
|
vd Tst(const TaSystem& sys,int gp) const { return getvart(sys,constants::Ts,gp); }
|
||||||
|
|
||||||
|
/// Obtain variable as a function of time for a given grid point
|
||||||
|
vd getvart(const TaSystem& sys,int varnr,int gp) const;
|
||||||
|
|
||||||
|
/// Obtain variable as a function of position, for a given time
|
||||||
|
/// instance
|
||||||
|
vd getvarx(const TaSystem& sys,int varnr,int t) const;
|
||||||
|
|
||||||
|
d getvartx(const TaSystem& sys,int t,int gp) const;
|
||||||
// Solving
|
// Solving
|
||||||
virtual void residual(const TaSystem&,arma::subview_col<d>&& residual) const;
|
virtual void residual(const TaSystem&,arma::subview_col<d>&& residual) const;
|
||||||
|
|
||||||
|
@ -44,16 +44,44 @@ void AdiabaticWall::residual(const TaSystem& sys,
|
|||||||
) const {
|
) const {
|
||||||
|
|
||||||
TRACE(15,"AdiabaticWall::residual()");
|
TRACE(15,"AdiabaticWall::residual()");
|
||||||
|
const pb::Duct& dpb = getDuct(sys).getDuctPb();
|
||||||
|
us Ns = sys.Ns();
|
||||||
|
|
||||||
|
const Duct& duct = getDuct(sys);
|
||||||
|
if(_side == pb::left) {
|
||||||
|
residual.subvec(0,Ns-1) = duct.ut(sys,0);
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) {
|
||||||
|
// TODO: Put the boundary condition of zero heat flux here
|
||||||
|
// residual.subvec(Ns,2*Ns-1) =
|
||||||
|
tasmet_assert(false,"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
residual.subvec(0,Ns-1) = duct.ut(sys,-1);
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) {
|
||||||
|
// TODO: Put the boundary condition of zero heat flux here
|
||||||
|
// residual.subvec(Ns,2*Ns-1) = duct.Tt(sys,-1) - _T;
|
||||||
|
tasmet_assert(false,"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
us AdiabaticWall::getNEqs(const TaSystem& sys) const {
|
us AdiabaticWall::getNEqs(const TaSystem& sys) const {
|
||||||
TRACE(15,"AdiabaticWall::getNEqs()");
|
TRACE(15,"AdiabaticWall::getNEqs()");
|
||||||
// u = 0
|
// u = 0
|
||||||
// dT/dx = 0
|
// dT/dx = 0 --> if htmodel is not Isentropic
|
||||||
// dTs/dx = 0 => 3 eqs
|
// dTs/dx = 0 => if stempmodel is not Prescribed
|
||||||
bool has_solideq = getDuct(sys).getDuctPb().stempmodel() != pb::Prescribed;
|
|
||||||
return sys.Ns()*(has_solideq ? 3: 2);
|
const pb::Duct& dpb = getDuct(sys).getDuctPb();
|
||||||
|
|
||||||
|
bool has_solideq = dpb.stempmodel() != pb::Prescribed;
|
||||||
|
|
||||||
|
us neqs = sys.Ns()*(has_solideq ? 2: 1);
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) neqs+= sys.Ns();
|
||||||
|
|
||||||
|
VARTRACE(15,neqs);
|
||||||
|
return neqs;
|
||||||
}
|
}
|
||||||
void AdiabaticWall::show(const TaSystem&,us verbosity_level) const {
|
void AdiabaticWall::show(const TaSystem&,us verbosity_level) const {
|
||||||
TRACE(15,"AdiabaticWall::show()");
|
TRACE(15,"AdiabaticWall::show()");
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "tasmet_tracer.h"
|
#include "tasmet_tracer.h"
|
||||||
#include "tasystem.h"
|
#include "tasystem.h"
|
||||||
#include "duct.h"
|
#include "duct.h"
|
||||||
|
#include "tasmet_evalscript.h"
|
||||||
|
#include "perfectgas.h"
|
||||||
|
#include "adiabatictemp.h"
|
||||||
|
|
||||||
PressureBc::PressureBc(const us id,
|
PressureBc::PressureBc(const us id,
|
||||||
const TaSystem& sys,
|
const TaSystem& sys,
|
||||||
@ -18,16 +21,48 @@ PressureBc::PressureBc(const us id,
|
|||||||
DuctBc(id,dbc)
|
DuctBc(id,dbc)
|
||||||
{
|
{
|
||||||
TRACE(15,"PressureBc(id,sys,dbc)");
|
TRACE(15,"PressureBc(id,sys,dbc)");
|
||||||
|
vd time = sys.timeInstances();
|
||||||
|
VARTRACE(15,time);
|
||||||
|
|
||||||
|
EvaluateFun pfun(dbc.pressure(),
|
||||||
|
"Error in evaluating prescribed pressure",
|
||||||
|
"t");
|
||||||
|
|
||||||
|
pfun.addGlobalDef("f",sys.getfreq());
|
||||||
|
pfun.addGlobalDef("omg",sys.getomg());
|
||||||
|
pfun.addGlobalDef("p0",sys.gas().p0());
|
||||||
|
pfun.addGlobalDef("T0",sys.gas().T0());
|
||||||
|
|
||||||
|
_p = pfun(time);
|
||||||
|
|
||||||
|
if(dbc.isentropic()) {
|
||||||
|
auto& gas = dynamic_cast<const PerfectGas&>(sys.gas());
|
||||||
|
_T = adiabaticTemp(gas,_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
EvaluateFun Tfun(dbc.temperature(),
|
||||||
|
"Error in evaluating prescribed temperature",
|
||||||
|
"t");
|
||||||
|
|
||||||
|
Tfun.addGlobalDef("f",sys.getfreq());
|
||||||
|
Tfun.addGlobalDef("omg",sys.getomg());
|
||||||
|
Tfun.addGlobalDef("p0",sys.gas().p0());
|
||||||
|
Tfun.addGlobalDef("T0",sys.gas().T0());
|
||||||
|
_T = Tfun(time);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
PressureBc::PressureBc(const PressureBc& o):
|
PressureBc::PressureBc(const PressureBc& o):
|
||||||
DuctBc(o) {
|
DuctBc(o),_p(o._p),_T(o._T) {
|
||||||
|
|
||||||
TRACE(15,"PressureBc(o)");
|
TRACE(15,"PressureBc(o)");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
PressureBc::~PressureBc() {
|
PressureBc::~PressureBc() {
|
||||||
|
|
||||||
}
|
}
|
||||||
PressureBc* PressureBc::copy() const {
|
PressureBc* PressureBc::copy() const {
|
||||||
return new PressureBc(*this);
|
return new PressureBc(*this);
|
||||||
@ -36,23 +71,49 @@ vd PressureBc::initialSolution(const TaSystem& sys) const {
|
|||||||
return vd();
|
return vd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PressureBc::residual(const TaSystem&,
|
void PressureBc::residual(const TaSystem& sys,
|
||||||
arma::subview_col<d>&& residual
|
arma::subview_col<d>&& residual
|
||||||
) const {
|
) const {
|
||||||
|
|
||||||
TRACE(15,"PressureBc::residual()");
|
TRACE(15,"PressureBc::residual()");
|
||||||
|
|
||||||
|
const pb::Duct& dpb = getDuct(sys).getDuctPb();
|
||||||
|
us Ns = sys.Ns();
|
||||||
|
|
||||||
|
const Duct& duct = getDuct(sys);
|
||||||
|
if(_side == pb::left) {
|
||||||
|
residual.subvec(0,Ns-1) = duct.pt(sys,0) - _p;
|
||||||
|
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) {
|
||||||
|
residual.subvec(Ns,2*Ns-1) = duct.Tt(sys,0) - _T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
residual.subvec(0,Ns-1) = duct.pt(sys,-1) - _p;
|
||||||
|
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) {
|
||||||
|
residual.subvec(Ns,2*Ns-1) = duct.Tt(sys,-1) - _T;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
us PressureBc::getNEqs(const TaSystem& sys) const {
|
us PressureBc::getNEqs(const TaSystem& sys) const {
|
||||||
TRACE(15,"PressureBc::getNEqs()");
|
TRACE(15,"PressureBc::getNEqs()");
|
||||||
// p = x
|
|
||||||
// T = x
|
// We provide equations for
|
||||||
// This one only if the duct solves for solid
|
// p = prescribed
|
||||||
// Ts = x => 3 equations
|
// T = prescribed, if htmodel of duct is not Isentropic
|
||||||
bool has_solideq = getDuct(sys).getDuctPb().stempmodel() != pb::Prescribed;
|
// Ts = prescribed, if stempmodel of duct is not Prescribed
|
||||||
return sys.Ns()*(has_solideq ? 3: 2);
|
|
||||||
|
const pb::Duct& dpb = getDuct(sys).getDuctPb();
|
||||||
|
|
||||||
|
bool has_solideq = dpb.stempmodel() != pb::Prescribed;
|
||||||
|
|
||||||
|
us neqs = sys.Ns()*(has_solideq ? 2: 1);
|
||||||
|
if(dpb.htmodel() != pb::Isentropic) neqs+= sys.Ns();
|
||||||
|
|
||||||
|
VARTRACE(15,neqs);
|
||||||
|
return neqs;
|
||||||
}
|
}
|
||||||
void PressureBc::show(const TaSystem&,us verbosity_level) const {
|
void PressureBc::show(const TaSystem&,us verbosity_level) const {
|
||||||
TRACE(15,"PressureBc::show()");
|
TRACE(15,"PressureBc::show()");
|
||||||
|
@ -14,9 +14,17 @@
|
|||||||
class TaSystem;
|
class TaSystem;
|
||||||
class Variable;
|
class Variable;
|
||||||
|
|
||||||
class PressureBc: public DuctBc {
|
/**
|
||||||
Variable *_p,*_T,*_Ts;
|
* A PressureBc is a Duct boundary condition, where the pressure is
|
||||||
|
* prescribed on one side of a Duct. Besides the pressure it is
|
||||||
|
* necessary to also prescribe the temperature, and if a model is used
|
||||||
|
* to thermally interact with the solid, also a solid temperature is
|
||||||
|
* prescribed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PressureBc: public DuctBc {
|
||||||
|
vd _p,_T,_Ts; /**< Prescribed values for pressure,
|
||||||
|
temperature and solid temperature */
|
||||||
pb::DuctSide _side; /**< Duct side at which this b.c. works */
|
pb::DuctSide _side; /**< Duct side at which this b.c. works */
|
||||||
protected:
|
protected:
|
||||||
PressureBc(const PressureBc&);
|
PressureBc(const PressureBc&);
|
||||||
|
@ -88,15 +88,13 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Variable adiabaticTemp(const PerfectGas& gas,
|
vd adiabaticTemp(const PerfectGas& gas,
|
||||||
const Variable& pressure) {
|
const vd& p) {
|
||||||
|
|
||||||
|
|
||||||
TRACE(10,"adiabaticTemp()");
|
TRACE(10,"adiabaticTemp()");
|
||||||
Variable temp(pressure);
|
|
||||||
const vd p = pressure.tdata();
|
|
||||||
|
|
||||||
vd T = temp.tdata();
|
vd T(p.size());
|
||||||
|
|
||||||
AdiabaticTemp adt(gas,p(0)); // Equation
|
AdiabaticTemp adt(gas,p(0)); // Equation
|
||||||
|
|
||||||
@ -115,8 +113,7 @@ Variable adiabaticTemp(const PerfectGas& gas,
|
|||||||
VARTRACE(15,T(i));
|
VARTRACE(15,T(i));
|
||||||
|
|
||||||
}
|
}
|
||||||
temp.settdata(T);
|
return T;
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -3,17 +3,24 @@
|
|||||||
// Author: J.A. de Jong
|
// Author: J.A. de Jong
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Compute the adiabatic/isentropic temperature as a function of the pressure
|
//
|
||||||
// for a thermally perfect gas
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef ADIABATICTEMP_H
|
#ifndef ADIABATICTEMP_H
|
||||||
#define ADIABATICTEMP_H
|
#define ADIABATICTEMP_H
|
||||||
|
#include "tasmet_types.h"
|
||||||
class PerfectGas;
|
class PerfectGas;
|
||||||
class Variable;
|
/**
|
||||||
|
* Compute the adiabatic/isentropic temperature as a function of the pressure
|
||||||
Variable adiabaticTemp(const PerfectGas& gas,const Variable& pressure);
|
* for a thermally perfect gas.
|
||||||
|
*
|
||||||
|
* @param gas: The gas to compute the temperature for. Be aware of the
|
||||||
|
* value for T0 and p0 in the Gas.
|
||||||
|
* @param pressure the pressure to compute the temperature for
|
||||||
|
*
|
||||||
|
* @return the temperature
|
||||||
|
*/
|
||||||
|
vd adiabaticTemp(const PerfectGas& gas,const vd& pressure);
|
||||||
|
|
||||||
#endif // ADIABATICTEMP_H
|
#endif // ADIABATICTEMP_H
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -78,6 +78,16 @@ public:
|
|||||||
element_wise(rho);
|
element_wise(rho);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual d drhodT(d T,d p) const=0;
|
||||||
|
vd drhodT(const vd& T,const vd& p) const {
|
||||||
|
element_wise(drhodT);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual d drhodp(d T,d p) const=0;
|
||||||
|
vd drhodp(const vd& T,const vd& p) const {
|
||||||
|
element_wise(drhodp);
|
||||||
|
}
|
||||||
|
|
||||||
// Adiabatic speed of sound
|
// Adiabatic speed of sound
|
||||||
virtual d cm(d T,d p) const=0;
|
virtual d cm(d T,d p) const=0;
|
||||||
vd cm(const vd& T,const vd& p) const {
|
vd cm(const vd& T,const vd& p) const {
|
||||||
|
@ -63,6 +63,13 @@ public:
|
|||||||
checkzero(T);
|
checkzero(T);
|
||||||
return p/Rs()/T;
|
return p/Rs()/T;
|
||||||
}
|
}
|
||||||
|
d drhodT(d T,d p) const {
|
||||||
|
return -p/Rs()/pow(T,2);
|
||||||
|
}
|
||||||
|
d drhodp(d T,d p) const {
|
||||||
|
return Rs()/T;
|
||||||
|
}
|
||||||
|
|
||||||
d cv(d T,d p) const {
|
d cv(d T,d p) const {
|
||||||
return cp(T,p)-Rs();
|
return cp(T,p)-Rs();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "newton_raphson.h"
|
#include "newton_raphson.h"
|
||||||
#include "tasmet_tracer.h"
|
#include "tasmet_tracer.h"
|
||||||
|
|
||||||
|
#define DEBUG_TASMET_SYSTEM
|
||||||
|
|
||||||
void NewtonRaphson::start_implementation(GradientNonlinearSystem& system,
|
void NewtonRaphson::start_implementation(GradientNonlinearSystem& system,
|
||||||
progress_callback* callback) {
|
progress_callback* callback) {
|
||||||
|
|
||||||
@ -23,6 +25,17 @@ void NewtonRaphson::start_implementation(GradientNonlinearSystem& system,
|
|||||||
|
|
||||||
vd residual=system.residual();
|
vd residual=system.residual();
|
||||||
|
|
||||||
|
#ifdef DEBUG_TASMET_SYSTEM
|
||||||
|
cout << "Initial solution: " << endl;
|
||||||
|
cout << guess << endl;
|
||||||
|
#endif // DEBUG_TASMET_SYSTEM
|
||||||
|
|
||||||
|
#ifdef DEBUG_TASMET_SYSTEM
|
||||||
|
cout << "Initial residual: " << endl;
|
||||||
|
cout << residual << endl;
|
||||||
|
#endif // DEBUG_TASMET_SYSTEM
|
||||||
|
|
||||||
|
|
||||||
SolverProgress progress;
|
SolverProgress progress;
|
||||||
SolverAction action;
|
SolverAction action;
|
||||||
|
|
||||||
@ -40,7 +53,12 @@ void NewtonRaphson::start_implementation(GradientNonlinearSystem& system,
|
|||||||
system.updateSolution(guess);
|
system.updateSolution(guess);
|
||||||
|
|
||||||
residual = system.residual();
|
residual = system.residual();
|
||||||
|
#ifdef DEBUG_TASMET_SYSTEM
|
||||||
|
cout << "Residual: ";
|
||||||
|
cout << residual << endl;
|
||||||
|
#endif // DEBUG_TASMET_SYSTEM
|
||||||
|
|
||||||
|
|
||||||
progress.rel_err = norm(dx);
|
progress.rel_err = norm(dx);
|
||||||
progress.fun_err = norm(residual);
|
progress.fun_err = norm(residual);
|
||||||
progress.iteration++;
|
progress.iteration++;
|
||||||
|
@ -48,6 +48,11 @@ GlobalConf::GlobalConf(us Nf,d freq):
|
|||||||
setfreq(freq);
|
setfreq(freq);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
vd GlobalConf::timeInstances() const {
|
||||||
|
us Ns = this->Ns();
|
||||||
|
d lastt = (Ns-1)/(Ns*getfreq());
|
||||||
|
return arma::linspace<vd>(0,lastt,Ns);
|
||||||
|
}
|
||||||
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";
|
||||||
|
@ -44,6 +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());}
|
||||||
|
|
||||||
|
vd timeInstances() const;
|
||||||
|
|
||||||
void setfreq(d freq){setomg(2*number_pi*freq);}
|
void setfreq(d freq){setomg(2*number_pi*freq);}
|
||||||
void setomg(d omg);
|
void setomg(d omg);
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ TaSystem::TaSystem(const pb::System& sys):
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create all ducts
|
// Create all ductbcs
|
||||||
for(const auto& d : sys.ductbcs()) {
|
for(const auto& d : sys.ductbcs()) {
|
||||||
// d.first: id
|
// d.first: id
|
||||||
// d.second: duct description
|
// d.second: duct description
|
||||||
@ -61,6 +61,33 @@ TaSystem::TaSystem(const pb::System& sys):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the initial solution from the segments and store it
|
||||||
|
// here. Please be careful not to call any virtual functions!
|
||||||
|
vus ndofs = getNDofs();
|
||||||
|
vus dofend = arma::cumsum(ndofs);
|
||||||
|
us total_dofs = arma::sum(ndofs);
|
||||||
|
vd solution = vd(total_dofs);
|
||||||
|
|
||||||
|
us i=0;
|
||||||
|
const Segment* seg;
|
||||||
|
for(auto& seg_: _segs) {
|
||||||
|
seg = seg_.second;
|
||||||
|
|
||||||
|
if(ndofs(i)>0) {
|
||||||
|
if(i==0) {
|
||||||
|
solution.subvec(0,ndofs(0)-1) =
|
||||||
|
seg->initialSolution(*this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
solution.subvec(dofend(i-1),dofend(i)-1) =
|
||||||
|
seg->initialSolution(*this);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: work directly on the final solution array
|
||||||
|
_solution = solution;
|
||||||
|
|
||||||
// Copy solution vector, if valid
|
// Copy solution vector, if valid
|
||||||
// const auto& sol = sys.solution();
|
// const auto& sol = sys.solution();
|
||||||
// us size = sol.size(), i=0;
|
// us size = sol.size(), i=0;
|
||||||
@ -75,7 +102,8 @@ TaSystem::TaSystem(const pb::System& sys):
|
|||||||
}
|
}
|
||||||
TaSystem::TaSystem(const TaSystem& o):
|
TaSystem::TaSystem(const TaSystem& o):
|
||||||
GlobalConf(o), // Share a ptr to the Global conf
|
GlobalConf(o), // Share a ptr to the Global conf
|
||||||
_gas(o._gas->copy())
|
_gas(o._gas->copy()),
|
||||||
|
_solution(o._solution)
|
||||||
{
|
{
|
||||||
TRACE(25,"TaSystem::TaSystem(TaSystem&) copy");
|
TRACE(25,"TaSystem::TaSystem(TaSystem&) copy");
|
||||||
|
|
||||||
@ -150,6 +178,10 @@ vd TaSystem::residual() const {
|
|||||||
|
|
||||||
vd residual(total_neqs);
|
vd residual(total_neqs);
|
||||||
|
|
||||||
|
#ifdef TASMET_DEBUG
|
||||||
|
residual = arma::datum::nan*ones(total_neqs);
|
||||||
|
#endif
|
||||||
|
|
||||||
us i=0;
|
us i=0;
|
||||||
const Segment* seg;
|
const Segment* seg;
|
||||||
for(auto seg_: _segs) {
|
for(auto seg_: _segs) {
|
||||||
@ -172,6 +204,8 @@ vd TaSystem::residual() const {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE(15,"Obtained residual from all Segments");
|
||||||
|
|
||||||
#ifdef TASMET_DEBUG
|
#ifdef TASMET_DEBUG
|
||||||
assert(arbitrateMassEq< (int) total_neqs);
|
assert(arbitrateMassEq< (int) total_neqs);
|
||||||
#endif // TASMET_DEBUG
|
#endif // TASMET_DEBUG
|
||||||
@ -185,43 +219,16 @@ vd TaSystem::residual() const {
|
|||||||
}
|
}
|
||||||
vd TaSystem::getSolution() const {
|
vd TaSystem::getSolution() const {
|
||||||
|
|
||||||
if(_solution.size() == 0) {
|
|
||||||
// Create the initial solution from the segments
|
|
||||||
// and store it here
|
|
||||||
|
|
||||||
vus ndofs = getNDofs();
|
|
||||||
vus dofend = arma::cumsum(ndofs);
|
|
||||||
us total_dofs = arma::sum(ndofs);
|
|
||||||
vd solution = vd(total_dofs);
|
|
||||||
|
|
||||||
us i=0;
|
|
||||||
const Segment* seg;
|
|
||||||
for(auto& seg_: _segs) {
|
|
||||||
seg = seg_.second;
|
|
||||||
|
|
||||||
if(ndofs(i)>0) {
|
|
||||||
if(i==0) {
|
|
||||||
solution.subvec(0,ndofs(0)-1) =
|
|
||||||
seg->initialSolution(*this);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
solution.subvec(dofend(i-1),dofend(i)-1) =
|
|
||||||
seg->initialSolution(*this);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return solution;
|
|
||||||
} // if the solution did not yet exist
|
|
||||||
|
|
||||||
return _solution;
|
return _solution;
|
||||||
}
|
}
|
||||||
const arma::subview_col<d> TaSystem::getSolution(const us seg_id) const {
|
const arma::subview_col<d> TaSystem::getSolution(const us seg_id) const {
|
||||||
|
|
||||||
vus ndofs = getNDofs();
|
vus ndofs = getNDofs();
|
||||||
vus dofsend = arma::cumsum(ndofs);
|
vus dofsend = arma::cumsum(ndofs);
|
||||||
|
VARTRACE(15,dofsend);
|
||||||
|
VARTRACE(15,seg_id);
|
||||||
if(seg_id == 0) {
|
if(seg_id == 0) {
|
||||||
|
VARTRACE(15,_solution.size());
|
||||||
return _solution.subvec(0,dofsend(0)-1);
|
return _solution.subvec(0,dofsend(0)-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -96,14 +96,11 @@ namespace constants {
|
|||||||
|
|
||||||
// These variable numbers are important, as they determine the
|
// These variable numbers are important, as they determine the
|
||||||
// position of these variables in the array in cell.h
|
// position of these variables in the array in cell.h
|
||||||
// const int rho=1;
|
const int rho=0;
|
||||||
// const int m=2;
|
const int u=1;
|
||||||
// const int T=3;
|
const int T=2;
|
||||||
// const int p=4;
|
const int p=3;
|
||||||
// const int Ts=5;
|
const int Ts=4;
|
||||||
// Number of variables
|
|
||||||
const int nvars_reserve=7;
|
|
||||||
const int neqs_reserve=7;
|
|
||||||
|
|
||||||
const char* const model_fileext = ".tasmet";
|
const char* const model_fileext = ".tasmet";
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ inline void wrap_eval<void>(ChaiScript* chai,const string& script) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EvaluateFun::EvaluateFun(const string& fun_return,
|
EvaluateFun::EvaluateFun(const string& fun_return,
|
||||||
const string& err_msg):
|
const string& err_msg,
|
||||||
|
const string& vars):
|
||||||
_err_msg(err_msg),
|
_err_msg(err_msg),
|
||||||
_fun_return(fun_return)
|
_fun_return(fun_return)
|
||||||
{
|
{
|
||||||
@ -55,7 +56,7 @@ EvaluateFun::EvaluateFun(const string& fun_return,
|
|||||||
_chai = getChaiScriptInstance();
|
_chai = getChaiScriptInstance();
|
||||||
if(!_chai) throw TaSMETBadAlloc();
|
if(!_chai) throw TaSMETBadAlloc();
|
||||||
|
|
||||||
string script = "def myfun(x) {\n";
|
string script = string("def myfun(") + vars + ") {\n";
|
||||||
script += "return " + fun_return + "; }\n";
|
script += "return " + fun_return + "; }\n";
|
||||||
|
|
||||||
wrap_eval<void>(_chai.get(),script);
|
wrap_eval<void>(_chai.get(),script);
|
||||||
|
@ -23,7 +23,7 @@ class EvaluateFun {
|
|||||||
string _err_msg;
|
string _err_msg;
|
||||||
string _fun_return;
|
string _fun_return;
|
||||||
public:
|
public:
|
||||||
EvaluateFun(const string& fun_return,const string& err_msg = "Script error");
|
EvaluateFun(const string& fun_return,const string& err_msg = "Script error",const string& vars = "x");
|
||||||
|
|
||||||
// Add a global definition to the namespace
|
// Add a global definition to the namespace
|
||||||
void addGlobalDef(const string& name,
|
void addGlobalDef(const string& name,
|
||||||
|
@ -66,8 +66,8 @@ int main(){
|
|||||||
Helium helium(293.15,101325);
|
Helium helium(293.15,101325);
|
||||||
|
|
||||||
gc_ptr gc(new GlobalConf(10,100));
|
gc_ptr gc(new GlobalConf(10,100));
|
||||||
Variable pressure(gc,10*101325);
|
vd pressure(1); pressure(0) = 10*101325;
|
||||||
Variable temperature = adiabaticTemp(helium,pressure);
|
vd temperature = adiabaticTemp(helium,pressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user