Vectorized implementation. Does not work yet

This commit is contained in:
J.A. de Jong @ vulgaris 2015-02-21 19:46:54 +01:00
parent 5d673c57c9
commit 46c02945c3
11 changed files with 336 additions and 279 deletions

View File

@ -11,6 +11,9 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "-Wall") SET(CMAKE_SWIG_FLAGS "-Wall")
add_definitions(-DNDEBUG) #This is for BOOST functions, and to disable assertions!
# add_definitions(-DTRACER=0)
add_definitions(-DEIGEN_NO_DEBUG -DARMA_NO_DEBUG)
add_definitions(-DTRACERNAME=timedomaineulertracer -DARMA_USE_BLAS -DARMA_USE_LAPACK) add_definitions(-DTRACERNAME=timedomaineulertracer -DARMA_USE_BLAS -DARMA_USE_LAPACK)

View File

@ -1,3 +1,10 @@
// arma_numpy.cpp
//
// last-edit-by: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#define PY_ARRAY_UNIQUE_SYMBOL npy_array_api #define PY_ARRAY_UNIQUE_SYMBOL npy_array_api
#define NO_IMPORT_ARRAY #define NO_IMPORT_ARRAY
#include "arma_numpy.h" #include "arma_numpy.h"
@ -5,34 +12,30 @@
// Annes conversion functions. In a later stage they have to be // Annes conversion functions. In a later stage they have to be
// generalized for arrays of arbitrary dimensions // generalized for arrays of arbitrary dimensions
PyObject *npy_from_vd(const vd &in) {
long int size = in.size();
npy_intp dims[1] = {size};
PyObject* npy_from_vd(const vd& in){
long int size=in.size();
npy_intp dims[1]={size};
// This code should be improved massively? // This code should be improved massively?
if(size==0){ if (size == 0) {
std::cout << "Size is zero!\n"; std::cout << "Size is zero!\n";
return NULL; return NULL;
} }
cout << "SFSF\n"; PyArrayObject *array =
PyArrayObject* array = (PyArrayObject*) \ (PyArrayObject *)PyArray_SimpleNew(1, dims, NPY_DOUBLE);
PyArray_SimpleNew(1, dims, NPY_DOUBLE);
cout << "SFSF\n";
if (array == NULL) { if (array == NULL) {
return NULL; return NULL;
} }
double *pydat= (double*) PyArray_DATA(array); double *pydat = (double *)PyArray_DATA(array);
cout << "SFSF\n"; mempcpy(pydat, in.memptr(), size * sizeof(double));
mempcpy(pydat,in.memptr(),size*sizeof(double));
return PyArray_Return(array); return PyArray_Return(array);
} }
vd vd_from_npy(const PyArrayObject* const in){ vd vd_from_npy(const PyArrayObject *const in) {
double* pydata = (double*) PyArray_DATA(in); npy_intp size=PyArray_DIMS(in)[0]; // Extract first
vd result; double *pydata = (double *)PyArray_DATA(in);
// long int dims= vd result(size);
// PyArra memcpy(result.memptr(),pydata,size*sizeof(double));
// vd res()
return result; return result;
} }

View File

@ -1,13 +1,25 @@
// arma_numpy.h
//
// Author: J.A. de Jong
//
// Description: Header file for two function converting between Numpy
// arrays and armadillo matrices
//////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef ARMA_NUMPY_H #ifndef ARMA_NUMPY_H
#define ARMA_NUMPY_H #define ARMA_NUMPY_H 1
#include <Python.h> #include <Python.h>
#include <numpy/arrayobject.h> #include <numpy/arrayobject.h>
#include "vtypes.h" #include "vtypes.h"
SPOILNAMESPACE SPOILNAMESPACE
vd vd_from_npy(PyArrayObject const * const); vd vd_from_npy(PyArrayObject const * const);
PyObject* npy_from_vd(const vd& armavec); PyObject* npy_from_vd(const vd& armavec);
#endif // ARMA_NUMPY_H #endif // ARMA_NUMPY_H
//////////////////////////////////////////////////////////////////////

View File

@ -1,31 +0,0 @@
#include "solutionatgp.h"
#include "globalconf.h"
TRACETHIS
namespace td{
extern tasystem::Globalconf gc;
SolutionAtGp::SolutionAtGp() {
rho_=gc.rho0();
}
d SolutionAtGp::u() const {return m()/rho();}
d SolutionAtGp::ekin() const {return 0.5*rho()*pow(u(),2);}
d SolutionAtGp::estat() const {return rhoE()-ekin();}
d SolutionAtGp::p() const {return estat()*(gc.gas.gamma(gc.T0)-1);}
d SolutionAtGp::Cflux() const {return m();}
d SolutionAtGp::Mflux() const {return pow(m(),2)/rho()+p();}
d SolutionAtGp::Eflux() const {return (rhoE()+gc.p0/(gc.gas.gamma(gc.T0)-1)+p()+gc.p0)*u();}
} // namespace td

View File

@ -1,38 +0,0 @@
#pragma once
namespace td{
typedef double d;
typedef unsigned us;
class SolutionAtGp {
d rho_,m_=0,rhoE_=0;
public:
// Dependent variables
const d& rho() const {return rho_;}
const d& m() const {return m_;} // which is rho*u
const d& rhoE() const {return rhoE_;} // which is rho*E
// Derived from dependent
d u() const;
d ekin() const;
d estat() const;
d p() const;
d Cflux() const;
d Mflux() const;
d Eflux() const;
SolutionAtGp();
~SolutionAtGp(){}
void setData(d rho,d m=0,d rhoE=0){
rho_=rho;
m_=m;
rhoE_=rhoE;
}
};
} // namespace td

View File

@ -2,38 +2,18 @@
namespace td{ namespace td{
SolutionInstance::SolutionInstance(int gp) SolutionInstance::SolutionInstance(int gp,d rho)
{ {
TRACE(12,"SolutionInstance::SolutionInstance()"); TRACE(12,"SolutionInstance::SolutionInstance()");
gps.resize(gp); rho_=vd(gp,fillwith::zeros);
m_=vd(gp,fillwith::zeros);
rhoE_=vd(gp,fillwith::zeros);
} }
void SolutionInstance::setrho(d rho) { void SolutionInstance::setrho(d rho) {
TRACE(15,"SolutionInstance::setrho()"); TRACE(15,"SolutionInstance::setrho()");
rho_=ones(rho_.size())*rho;
for(auto gp=gps.begin();gp!=gps.end();gp++){
gp->setData(rho);
}
} // setrho() } // setrho()
vd SolutionInstance::getrho() const{
return gpsol_to_python(gps,&SolutionAtGp::rho);
}
vd SolutionInstance::getp() const{
return gpsol_to_python(gps,&SolutionAtGp::p);
}
int SolutionInstance::save(std::ofstream& str,data d){
TRACE(15,"SolutionInstance::save()");
if(d==data::p)
for(us j=0;j<gps.size();j++){
SolutionAtGp& solgp=get(j);
str << j << "\t" <<solgp.p() << "\n";
}
else if(d==data::u)
for(us j=0;j<gps.size();j++){
SolutionAtGp& solgp=get(j);
str << j << "\t" <<solgp.u() << "\n";
}
return 0;
}
} // namespace td } // namespace td

View File

@ -1,42 +1,53 @@
// solutioninstance.h
//
// Author: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#include "solutionatgp.h" #ifndef SOLUTIONINSTANCE_H
#include "vtypes.h" #define SOLUTIONINSTANCE_H 1
void do_arma_to_python(const vd& armavec,double** data,int* n); #include "vtypes.h"
#include "globalconf.h"
namespace td{ namespace td{
SPOILNAMESPACE SPOILNAMESPACE
extern tasystem::Globalconf gc;
template<typename funptr>
vd gpsol_to_python(const vector<SolutionAtGp>& gps,funptr fun){
int size=gps.size();
vd result(size);
for(int i=0;i<size;i++)
result(i)=((gps[i]).*fun)();
return result;
}
enum data{
p,u
};
class SolutionInstance{ class SolutionInstance{
vector<SolutionAtGp> gps;
vd rho_,m_,rhoE_;
d time=0; d time=0;
public: public:
SolutionInstance(int gp); SolutionInstance(int gp,d rho=1.2);
~SolutionInstance(){} ~SolutionInstance(){}
d getTime() const {return time;} d getTime() const {return time;}
void setTime(d t) {time=t;} void setTime(d t) {time=t;}
void setData(us i,SolutionAtGp& sol){ gps.at(i)=sol;}
SolutionAtGp& get(us i){ return gps.at(i); }
vd getp() const; vd& rho_ref(){ return rho_;}
vd getrho() const; vd& m_ref() {return m_;}
vd& rhoE_ref() {return rhoE_;}
const vd& rho() const {return rho_;}
const vd& m() const {return m_;}
const vd& rhoE() const {return rhoE_;}
vd p() const {return estat()*(gc.gas.gamma(gc.T0)-1);}
vd u() const {return m()/rho();}
vd ekin() const { return 0.5*rho()%pow(u(),2);}
vd estat() const {return rhoE()-ekin();}
vd Cflux() const {return m();}
vd Mflux() const {return pow(m(),2)/rho()+p();}
vd Eflux() const {return (rhoE()+gc.p0/(gc.gas.gamma(gc.T0)-1)+p()+gc.p0)%u();}
void setrho(d rho); void setrho(d rho);
int save(std::ofstream&,data d);
}; };
} // namespace td } // namespace td
#endif // SOLUTIONINSTANCE_H
//////////////////////////////////////////////////////////////////////

View File

@ -1,91 +1,92 @@
#include "tube.h" #include "tube.h"
namespace td{ TRACETHIS
tasystem::Globalconf gc;
d Tube::pleft(d t){ namespace td {
d pleft=std::sin(gc.getomg()*t); tasystem::Globalconf gc;
cout << "t:"<< t<<endl;
cout << "omg:" << gc.getomg()<< endl;
// cout << "pleft:"<< pleft<<endl;
return pleft;
d Tube::pleft(d t) {
d pleft = std::sin(gc.getomg() * t);
// cout << "t:" << t << endl;
// cout << "omg:" << gc.getomg() << endl;
cout << "pleft:"<< pleft<<endl;
return pleft;
}
Tube::Tube(d L, int gp) throw(int) : L(L), gp(gp), sol(SolutionInstance(gp)) {
TRACE(15, "Tube::Tube()");
dx = L / (gp - 1);
if(gp<5)
throw 1;
VARTRACE(15, gp);
sol.setrho(gc.rho0());
}
void Tube::DoIntegration(d dt, int n) {
TRACE(14, "Tube::DoIntegration()");
int integrationnumber = 0;
while (integrationnumber < n) {
Integrate(dt);
integrationnumber++;
} }
Tube::Tube(d L,int gp): }
L(L), void TubeLF::Integrate(d dt) {
gp(gp), // Integrate using Lax-Friedrich method
sol(SolutionInstance(gp)) { d newt = t + dt;
// Define new solutioninstance
SolutionInstance newsol(gp);
newsol.setTime(newt);
TRACE(15,"Tube::Tube()"); const vd& oldrho=sol.rho();
dx=L/(gp-1); const vd& oldm=sol.m();
VARTRACE(15,gp); const vd& oldrhoE=sol.rhoE();
sol.setrho(gc.rho0());
}
void Tube::DoIntegration(d dt,int n){ vd& rho=newsol.rho_ref();
TRACE(14,"Tube::DoIntegration()"); vd& m=newsol.m_ref();
int integrations=0; vd& rhoE=newsol.rhoE_ref();
while(integrations<n){
Integrate(dt);
integrations++;
}
}
void Tube::Integrate(d dt){
// Define new time // Fluxes from previous solution
d newt=t+dt; vd Cflux=sol.Cflux();
vd Mflux=sol.Mflux();
vd Eflux=sol.Eflux();
// Define new solutioninstance // std::cout << "poL" << sol.p()(0) << std::endl;
SolutionInstance newsol(gp); { // Left boundary
newsol.setTime(newt); d la = dt/dx;
SolutionAtGp newsolgp; rho(0) = oldrho(0);
d rho,m,rhoE; rho(0)+=-la*(Cflux(1)-Cflux(0));
d oldu0=oldm(0)/oldrho(0);
// std::cout << "oldu:"<< oldu0 << std::endl;
d momfluxl = oldrho(0)*pow(oldu0, 2) + pleft(t);
m(0) = oldm(0);
m(0)+=-la*(Mflux(1)-momfluxl);
rhoE(0) = oldrhoE(0);
rhoE(0)+=-la*(Eflux(1)-Eflux(0));
int i=0; } // End left boundary
// Left boundary { // Inner nodes
{ d lambda = dt/(2*dx);
SolutionAtGp& ip1=sol.get(i+1); rho.subvec(1,gp-2)=0.5*(oldrho.subvec(0,gp-3) + oldrho.subvec(2,gp-1));
SolutionAtGp& ip0=sol.get(i); rho.subvec(1,gp-2)+=-lambda*(Cflux.subvec(0,gp-3) -Cflux.subvec(2,gp-1));
d la=dt/(dx);
rho=ip0.rho()-la*(ip1.Cflux()-ip0.Cflux()); m.subvec(1,gp-2)=0.5*(oldm.subvec(0,gp-3) + oldm.subvec(2,gp-1));
d momfluxl=ip0.rho()*pow(ip0.u(),2)+pleft(t); m.subvec(1,gp-2)+=-lambda*(Mflux.subvec(0,gp-3) -Mflux.subvec(2,gp-1));
m=ip0.m()-la*(ip1.Mflux()-momfluxl);
rhoE=ip0.rhoE()-la*(ip1.Eflux()-ip0.Eflux());
newsolgp.setData(rho,m,rhoE);
newsol.setData(i,newsolgp);
} // Leftmost node rhoE.subvec(1,gp-2)=0.5*(oldrhoE.subvec(0,gp-3) + oldrhoE.subvec(2,gp-1));
// TRACE(15,"leftmost done"); rhoE.subvec(1,gp-2)+=-lambda*(Eflux.subvec(0,gp-3) -Eflux.subvec(2,gp-1));
// Inner nodes } // End inner nodes
for(i=1;i<gp-1;i++){ { // Right boundary
SolutionAtGp& im1=sol.get(i-1); int i = gp - 1;
SolutionAtGp& ip1=sol.get(i+1); d la = dt/dx;
d lambda=dt/(2*dx); rho(i) = oldrho(i);
rho=0.5*(im1.rho()+ip1.rho())-lambda*(ip1.Cflux()-im1.Cflux()); rho(i)+=-la*(0-Cflux(i-1));
m=0.5*(im1.m()+ip1.m())-lambda*(ip1.Mflux()-im1.Mflux()); m(i) = 0;
rhoE=0.5*(im1.rhoE()+ip1.rhoE())-lambda*(ip1.Eflux()-im1.Eflux()); rhoE(i) = oldrhoE(i);
rhoE(i)+=-la*(0-Eflux(i-1));
} // End right boundary
newsolgp.setData(rho,m,rhoE); // Finally, update time and solution
newsol.setData(i,newsolgp); sol = newsol;
t = newt;
} // for over all gridpoints in mid }
{
i=gp-1;
SolutionAtGp& im1=sol.get(i-1);
SolutionAtGp& ip0=sol.get(i);
d la=dt/(dx);
rho=ip0.rho()-la*(0-im1.Cflux());
m=0;
rhoE=ip0.rhoE()-la*(0-im1.Eflux());
newsolgp.setData(rho,m,rhoE);
newsol.setData(i,newsolgp);
}
// Finally, update time and solution
sol=newsol;
t=newt;
}
} // namespace td } // namespace td

View File

@ -1,29 +1,52 @@
#pragma once // tube.h
#ifndef _TUBE_H_ //
#define _TUBE_H_ // Author: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#pragma once
#ifndef TUBE_H
#define TUBE_H 1
#include "solutioninstance.h" #include "solutioninstance.h"
#include "globalconf.h" #include "globalconf.h"
namespace td{ namespace td {
typedef double d; typedef double d;
class Tube{ class Tube {
d dx,L; // Grid spacing, total length protected:
int gp; // Number of gridpoints d dx, L; // Grid spacing, total length
int gp; // Number of gridpoints
SolutionInstance sol; // Solutions at time instances SolutionInstance sol; // Solutions at time instances
d t=0; // Current time d t = 0; // Current time
d pleft(d t); // Compute pressure bc d pleft(d t); // Compute pressure bc
void Integrate(d dt); virtual void Integrate(d dt) = 0;
public:
Tube(double L,int gp); public:
~Tube(){} Tube(double L, int gp) throw(int);
SolutionInstance& getSol() { return sol;} virtual ~Tube() {}
void setSol(const SolutionInstance& sol) {this->sol=sol;} SolutionInstance &getSol() { return sol; }
void DoIntegration(d dt,int n=1); void setSol(const SolutionInstance &sol) { this->sol = sol; }
d getTime(){return t;} void DoIntegration(d dt, int n = 1);
}; d getTime() { return t; }
};
class TubeLF : public Tube { // Using Lax-Friedrichs method
protected:
virtual void Integrate(d dt);
public:
using Tube::Tube;
};
} // namespace td
#endif // TUBE_H
//////////////////////////////////////////////////////////////////////
} // namespace td
#endif /* _TUBE_H_ */

View File

@ -35,13 +35,12 @@ class vd{
return NULL; return NULL;
int ndims=PyArray_DIM(arr,0); int ndims=PyArray_DIM(arr,0);
if(ndims!=1){ if(ndims!=1){
PyErr_SetString(PyExc_TypeError,"Number of dimensions not equal to 1"); // PyErr_SetString(PyExc_TypeError,"Number of dimensions not equal to 1");
return NULL; return NULL;
} }
$1= vd_from_npy(arr); $1= vd_from_npy(arr);
} }
%typemap(out) vd { %typemap(out) vd {
cout << "Hoi\n";
$result=npy_from_vd($1); $result=npy_from_vd($1);
} }
typedef double d; typedef double d;
@ -95,46 +94,33 @@ namespace tasystem{
namespace td{ namespace td{
class SolutionAtGp {
public:
const d& rho() const;
const d& m() const;
const d& rhoE() const;
d u() const;
d ekin() const;
d estat() const;
d p() const;
d Cflux() const;
d Mflux() const;
d Eflux() const;
SolutionAtGp();
~SolutionAtGp(){}
void setData(d rho,d m=0,d rhoE=0);
};
class SolutionInstance{ class SolutionInstance{
public: public:
SolutionInstance(int gp); SolutionInstance(int gp,d rho=1.2);
~SolutionInstance(){} ~SolutionInstance(){}
d getTime() const; vd rho() const;
vd getrho() const; vd p() const;
vd getp() const; vd u() const;
void setTime(d t); void setTime(d t);
void setData(us i,SolutionAtGp& sol);
SolutionAtGp& get(us i);
void setrho(d rho); void setrho(d rho);
}; };
tasystem::Globalconf gc; tasystem::Globalconf gc;
class Tube{ class Tube{
virtual void Integrate(d dt)=0;
public: public:
Tube(double L,int gp); Tube(double L,int gp) throw(int);
~Tube(){} virtual ~Tube();
SolutionInstance& getSol(); SolutionInstance& getSol();
void setSol(const SolutionInstance& sol); void setSol(const SolutionInstance& sol);
void DoIntegration(d dt,int n=1); void DoIntegration(d dt,int n=1);
d getTime(); d getTime();
}; };
class TubeLF:public Tube{
virtual void Integrate(d dt);
public:
TubeLF(d L,int gp);
};
} }

File diff suppressed because one or more lines are too long