mirror of https://github.com/lammps/lammps.git
ATC version 2.0, date: Aug7
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10557 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
6d40d7c25d
commit
0e4d1e6b22
|
@ -1,47 +0,0 @@
|
|||
// ATC_Error : a base class for atom-continuum errors
|
||||
|
||||
#ifndef ATC_ERROR
|
||||
#define ATC_ERROR
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace ATC {
|
||||
|
||||
class ATC_Error {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ATC_Error(int procID, std::string errorDescription) {
|
||||
procID_ = procID;
|
||||
errorDescription_ = errorDescription;
|
||||
};
|
||||
|
||||
//ATC_Error(std::string errorDescription) {
|
||||
// procID_ = LammpsInterface::instance()->comm_rank();
|
||||
// errorDescription_ = errorDescription;
|
||||
//};
|
||||
|
||||
// data access
|
||||
virtual int get_id() {
|
||||
return procID_;
|
||||
};
|
||||
|
||||
virtual std::string get_error_description() {
|
||||
return errorDescription_;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// id of the processor reporting the error
|
||||
int procID_;
|
||||
|
||||
// string describing the type of error
|
||||
std::string errorDescription_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,386 +0,0 @@
|
|||
#include "ATC_HardyKernel.h"
|
||||
#include "math.h"
|
||||
#include <iostream> //for debugging purposes; take this out after I'm done
|
||||
#include <vector>
|
||||
#include "ATC_Error.h"
|
||||
#include "Quadrature.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const double Pi = 4.0*atan(1.0);
|
||||
static const double tol = 1.0e-8;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernel::ATC_HardyKernel(int nparameters, double* parameters):
|
||||
lammpsInterface_(LammpsInterface::instance()),
|
||||
Rc_(0),invRc_(0),nsd_(3)
|
||||
{
|
||||
Rc_ = parameters[0];
|
||||
invRc_ = 1.0/Rc_;
|
||||
Rc_ = parameters[0];
|
||||
invRc_ = 1.0/Rc_;
|
||||
invVol_ = 1.0/(4.0/3.0*Pi*pow(Rc_,3));
|
||||
|
||||
set_line_quadrature(line_ngauss,line_xg,line_wg);
|
||||
|
||||
// get periodicity and box bounds/lengths
|
||||
lammpsInterface_->get_box_periodicity(periodicity[0],
|
||||
periodicity[1],periodicity[2]);
|
||||
lammpsInterface_->get_box_bounds(box_bounds[0][0],box_bounds[1][0],
|
||||
box_bounds[0][1],box_bounds[1][1],
|
||||
box_bounds[0][2],box_bounds[1][2]);
|
||||
for (int k = 0; k < 3; k++) {
|
||||
box_length[k] = box_bounds[1][k] - box_bounds[0][k];
|
||||
}
|
||||
};
|
||||
|
||||
// bond function value via quadrature
|
||||
double ATC_HardyKernel::bond(DENS_VEC& xa, DENS_VEC&xb, double lam1, double lam2)
|
||||
{
|
||||
DENS_VEC xab(nsd_), q(nsd_);
|
||||
double lamg;
|
||||
double bhsum=0.0;
|
||||
xab = xa - xb;
|
||||
for (int i = 0; i < line_ngauss; i++) {
|
||||
lamg=0.5*((lam2-lam1)*line_xg[i]+(lam2+lam1));
|
||||
q = lamg*xab + xb;
|
||||
double locg_value=this->value(q);
|
||||
bhsum+=locg_value*line_wg[i];
|
||||
}
|
||||
return 0.5*(lam2-lam1)*bhsum;
|
||||
}
|
||||
|
||||
// localization-volume intercepts for bond calculation
|
||||
// bond intercept values assuming spherical support
|
||||
void ATC_HardyKernel::bond_intercepts(DENS_VEC& xa,
|
||||
DENS_VEC& xb, double &lam1, double &lam2)
|
||||
{
|
||||
if (nsd_ == 2) {// for cylinders, axis is always z!
|
||||
const int iaxis = 2;
|
||||
xa[iaxis] = 0.0;
|
||||
xb[iaxis] = 0.0;
|
||||
}
|
||||
lam1 = lam2 = -1;
|
||||
double ra_n = invRc_*xa.norm(); // lambda = 1
|
||||
double rb_n = invRc_*xb.norm(); // lambda = 0
|
||||
bool a_in = (ra_n <= 1.0);
|
||||
bool b_in = (rb_n <= 1.0);
|
||||
if (a_in && b_in) {
|
||||
lam1 = 0.0;
|
||||
lam2 = 1.0;
|
||||
return;
|
||||
}
|
||||
DENS_VEC xab = xa - xb;
|
||||
double rab_n = invRc_*xab.norm();
|
||||
double a = rab_n*rab_n; // always at least an interatomic distance
|
||||
double b = 2.0*invRc_*invRc_*xab.dot(xb);
|
||||
double c = rb_n*rb_n - 1.0;
|
||||
double discrim = b*b - 4.0*a*c; // discriminant
|
||||
if (discrim < 0) return; // no intersection
|
||||
// num recipes:
|
||||
double s1, s2;
|
||||
if (b < 0.0) {
|
||||
double aux = -0.5*(b-sqrt(discrim));
|
||||
s1 = c/aux;
|
||||
s2 = aux/a;
|
||||
}
|
||||
else {
|
||||
double aux = -0.5*(b+sqrt(discrim));
|
||||
s1 = aux/a;
|
||||
s2 = c/aux;
|
||||
}
|
||||
if (a_in && !b_in) {
|
||||
lam1 = s1;
|
||||
lam2 = 1.0;
|
||||
}
|
||||
else if (!a_in && b_in) {
|
||||
lam1 = 0.0;
|
||||
lam2 = s2;
|
||||
}
|
||||
else {
|
||||
if (s1 >= 0.0 && s2 <= 1.0) {
|
||||
lam1 = s1;
|
||||
lam2 = s2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernelStep::ATC_HardyKernelStep
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (Rc_ > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelStep::value(DENS_VEC& x_atom)
|
||||
{
|
||||
double rn=invRc_*x_atom.norm();
|
||||
if (rn <= 1.0) { return 1.0; }
|
||||
else { return 0.0; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** a step with rectangular support suitable for a rectangular grid */
|
||||
// constructor
|
||||
ATC_HardyKernelCell::ATC_HardyKernelCell
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
hx = parameters[0];
|
||||
hy = parameters[1];
|
||||
hz = parameters[2];
|
||||
invVol_ = 1.0/8.0/(hx*hy*hz);
|
||||
cellBounds_.reset(6);
|
||||
cellBounds_(0) = -hx;
|
||||
cellBounds_(1) = hx;
|
||||
cellBounds_(2) = -hy;
|
||||
cellBounds_(3) = hy;
|
||||
cellBounds_(4) = -hz;
|
||||
cellBounds_(5) = hz;
|
||||
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (parameters[k] > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelCell::value(DENS_VEC& x_atom)
|
||||
{
|
||||
if ((cellBounds_(0) <= x_atom(0)) && (x_atom(0) < cellBounds_(1))
|
||||
&& (cellBounds_(2) <= x_atom(1)) && (x_atom(1) < cellBounds_(3))
|
||||
&& (cellBounds_(4) <= x_atom(2)) && (x_atom(2) < cellBounds_(5))) {
|
||||
return 1.0;
|
||||
}
|
||||
else {
|
||||
return 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
// bond intercept values for rectangular region : origin is the node position
|
||||
void ATC_HardyKernelCell::bond_intercepts(DENS_VEC& xa,
|
||||
DENS_VEC& xb, double &lam1, double &lam2)
|
||||
{
|
||||
lam1 = 0.0; // start
|
||||
lam2 = 1.0; // end
|
||||
|
||||
bool a_in = (value(xa) > 0.0);
|
||||
bool b_in = (value(xb) > 0.0);
|
||||
|
||||
// (1) both in, no intersection needed
|
||||
if (a_in && b_in) {
|
||||
return;
|
||||
}
|
||||
// (2) for one in & one out -> one plane intersection
|
||||
// determine the points of intersection between the line joining
|
||||
// atoms a and b and the bounding planes of the localization volume
|
||||
else if (a_in || b_in) {
|
||||
DENS_VEC xab = xa - xb;
|
||||
for (int i = 0; i < nsd_; i++) {
|
||||
// check if segment is parallel to face
|
||||
if (fabs(xab(i)) > tol) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
double s = (cellBounds_(2*i+j) - xb(i))/xab(i);
|
||||
// check if between a & b
|
||||
if (s >= 0 && s <= 1) {
|
||||
bool in_bounds = false;
|
||||
DENS_VEC x = xb + s*xab;
|
||||
if (i == 0) {
|
||||
if ((cellBounds_(2) <= x(1)) && (x(1) <= cellBounds_(3))
|
||||
&& (cellBounds_(4) <= x(2)) && (x(2) <= cellBounds_(5))) {
|
||||
in_bounds = true;
|
||||
}
|
||||
}
|
||||
else if (i == 1) {
|
||||
if ((cellBounds_(0) <= x(0)) && (x(0) <= cellBounds_(1))
|
||||
&& (cellBounds_(4) <= x(2)) && (x(2) <= cellBounds_(5))) {
|
||||
in_bounds = true;
|
||||
}
|
||||
}
|
||||
else if (i == 2) {
|
||||
if ((cellBounds_(0) <= x(0)) && (x(0) <= cellBounds_(1))
|
||||
&& (cellBounds_(2) <= x(1)) && (x(1) <= cellBounds_(3))) {
|
||||
in_bounds = true;
|
||||
}
|
||||
}
|
||||
if (in_bounds) {
|
||||
if (a_in) { lam1 = s;}
|
||||
else { lam2 = s;}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw ATC_Error(0,"logic failure in HardyKernel Cell for single intersection\n");
|
||||
}
|
||||
// (3) both out -> corner intersection
|
||||
else {
|
||||
lam2 = lam1; // default to no intersection
|
||||
DENS_VEC xab = xa - xb;
|
||||
double ss[6] = {-1,-1,-1,-1,-1,-1};
|
||||
int is = 0;
|
||||
for (int i = 0; i < nsd_; i++) {
|
||||
// check if segment is parallel to face
|
||||
if (fabs(xab(i)) > tol) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
double s = (cellBounds_(2*i+j) - xb(i))/xab(i);
|
||||
// check if between a & b
|
||||
if (s >= 0 && s <= 1) {
|
||||
// check if in face
|
||||
DENS_VEC x = xb + s*xab;
|
||||
if (i == 0) {
|
||||
if ((cellBounds_(2) <= x(1)) && (x(1) <= cellBounds_(3))
|
||||
&& (cellBounds_(4) <= x(2)) && (x(2) <= cellBounds_(5))) {
|
||||
ss[is++] = s;
|
||||
}
|
||||
}
|
||||
else if (i == 1) {
|
||||
if ((cellBounds_(0) <= x(0)) && (x(0) <= cellBounds_(1))
|
||||
&& (cellBounds_(4) <= x(2)) && (x(2) <= cellBounds_(5))) {
|
||||
ss[is++] = s;
|
||||
}
|
||||
}
|
||||
else if (i == 2) {
|
||||
if ((cellBounds_(0) <= x(0)) && (x(0) <= cellBounds_(1))
|
||||
&& (cellBounds_(2) <= x(1)) && (x(1) <= cellBounds_(3))) {
|
||||
ss[is++] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is == 1) {
|
||||
// intersection occurs at a box edge - leave lam1 = lam2
|
||||
}
|
||||
else if (is == 2) {
|
||||
lam1 = min(ss[0],ss[1]);
|
||||
lam2 = max(ss[0],ss[1]);
|
||||
}
|
||||
else if (is == 3) {
|
||||
// intersection occurs at a box vertex - leave lam1 = lam2
|
||||
}
|
||||
else {
|
||||
if (is != 0) throw ATC_Error(0,"logic failure in HardyKernel Cell for corner intersection\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernelCubicSphere::ATC_HardyKernelCubicSphere
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (Rc_ > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelCubicSphere::value(DENS_VEC& x_atom)
|
||||
{
|
||||
double r=x_atom.norm();
|
||||
double rn=r/Rc_;
|
||||
if (rn < 1.0) { return 5.0*(1.0-3.0*rn*rn+2.0*rn*rn*rn); }
|
||||
else { return 0.0; }
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernelQuarticSphere::ATC_HardyKernelQuarticSphere
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (Rc_ > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelQuarticSphere::value(DENS_VEC& x_atom)
|
||||
{
|
||||
double r=x_atom.norm();
|
||||
double rn=r/Rc_;
|
||||
if (rn < 1.0) { return 35.0/8.0*pow((1.0-rn*rn),2); }
|
||||
else { return 0.0; }
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernelCubicCyl::ATC_HardyKernelCubicCyl
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
nsd_ = 2;
|
||||
double Lz = box_length[2];
|
||||
invVol_ = 1.0/(Pi*pow(Rc_,2)*Lz);
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (Rc_ > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelCubicCyl::value(DENS_VEC& x_atom)
|
||||
{
|
||||
double r=sqrt(pow(x_atom(0),2)+pow(x_atom(1),2));
|
||||
double rn=r/Rc_;
|
||||
if (rn < 1.0) { return 10.0/3.0*(1.0-3.0*rn*rn+2.0*rn*rn*rn); }
|
||||
else { return 0.0; }
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// constructor
|
||||
ATC_HardyKernelQuarticCyl::ATC_HardyKernelQuarticCyl
|
||||
(int nparameters, double* parameters):
|
||||
ATC_HardyKernel(nparameters, parameters)
|
||||
{
|
||||
nsd_ = 2;
|
||||
double Lz = box_length[2];
|
||||
invVol_ = 1.0/(Pi*pow(Rc_,2)*Lz);
|
||||
for (int k = 0; k < nsd_; k++ ) {
|
||||
if ((bool) periodicity[k]) {
|
||||
if (Rc_ > 0.5*box_length[k]) {
|
||||
throw ATC_Error(0,"Size of localization volume is too large for periodic boundary condition");
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// function value
|
||||
double ATC_HardyKernelQuarticCyl::value(DENS_VEC& x_atom)
|
||||
{
|
||||
double r=sqrt(pow(x_atom(0),2)+pow(x_atom(1),2));
|
||||
double rn=r/Rc_;
|
||||
if (rn < 1.0) { return 3.0*pow((1.0-rn*rn),2); }
|
||||
else { return 0.0; }
|
||||
}
|
||||
};
|
|
@ -1,127 +0,0 @@
|
|||
/** ATC_HardyKernel: Hardy smoothing */
|
||||
#ifndef ATC_HARDY_KERNEL_H
|
||||
#define ATC_HARDY_KERNEL_H
|
||||
|
||||
#include "LammpsInterface.h"
|
||||
#include "MatrixLibrary.h"
|
||||
|
||||
|
||||
namespace ATC {
|
||||
|
||||
|
||||
class ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ATC_HardyKernel(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernel() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom)=0;
|
||||
// bond function value via quadrature
|
||||
virtual double bond(DENS_VEC& xa, DENS_VEC&xb, double lam1, double lam2);
|
||||
// localization-volume intercepts for bond calculation
|
||||
virtual void bond_intercepts(DENS_VEC& xa,
|
||||
DENS_VEC& xb, double &lam1, double &lam2);
|
||||
double inv_vol(void) { return invVol_; }
|
||||
|
||||
protected:
|
||||
double invVol_; // normalization factor
|
||||
double Rc_, invRc_; // cutoff radius
|
||||
int nsd_ ; // number of dimensions
|
||||
|
||||
/** pointer to lammps interface class */
|
||||
LammpsInterface * lammpsInterface_;
|
||||
|
||||
/** periodicity flags and lengths */
|
||||
int periodicity[3];
|
||||
double box_bounds[2][3];
|
||||
double box_length[3];
|
||||
|
||||
};
|
||||
|
||||
/** a step with spherical support */
|
||||
class ATC_HardyKernelStep : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ATC_HardyKernelStep(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelStep() {};
|
||||
// function value
|
||||
double value(DENS_VEC& x_atom);
|
||||
// bond function value
|
||||
virtual double bond(DENS_VEC& xa, DENS_VEC&xb, double lam1, double lam2)
|
||||
{return lam2 -lam1;}
|
||||
};
|
||||
|
||||
/** a step with rectangular support suitable for a rectangular grid */
|
||||
class ATC_HardyKernelCell : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ATC_HardyKernelCell(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelCell() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom);
|
||||
// bond function value
|
||||
virtual double bond(DENS_VEC& xa, DENS_VEC&xb, double lam1, double lam2)
|
||||
{return lam2 -lam1;}
|
||||
// bond intercept values : origin is the node position
|
||||
void bond_intercepts(DENS_VEC& xa,
|
||||
DENS_VEC& xb, double &lam1, double &lam2);
|
||||
|
||||
protected:
|
||||
double hx, hy, hz;
|
||||
DENS_VEC cellBounds_;
|
||||
};
|
||||
|
||||
class ATC_HardyKernelCubicSphere : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ATC_HardyKernelCubicSphere(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelCubicSphere() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom);
|
||||
};
|
||||
|
||||
class ATC_HardyKernelQuarticSphere : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ATC_HardyKernelQuarticSphere(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelQuarticSphere() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom);
|
||||
};
|
||||
|
||||
|
||||
class ATC_HardyKernelCubicCyl : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ATC_HardyKernelCubicCyl(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelCubicCyl() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom) ;
|
||||
};
|
||||
|
||||
class ATC_HardyKernelQuarticCyl : public ATC_HardyKernel {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ATC_HardyKernelQuarticCyl(int nparameters, double* parameters);
|
||||
// destructor
|
||||
virtual ~ATC_HardyKernelQuarticCyl() {};
|
||||
// function value
|
||||
virtual double value(DENS_VEC& x_atom);
|
||||
};
|
||||
};
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,952 +0,0 @@
|
|||
// ATC_Transfer : a base class for atom-continuum transfers & control
|
||||
// (derived classes are physics dependent)
|
||||
// note init() must be called before most functions will work
|
||||
// we expect only one derived class to exist, i.e. don't call initilize/modify/etc more than once
|
||||
|
||||
// NOTE: implement print
|
||||
|
||||
#ifndef ATC_TRANSFER_H
|
||||
#define ATC_TRANSFER_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "PhysicsModel.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "Array.h"
|
||||
#include "Array2D.h"
|
||||
#include "OutputManager.h"
|
||||
#include "XT_Function.h"
|
||||
#include "FE_Element.h"
|
||||
#include "TimeFilter.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "FE_Engine.h"
|
||||
#include "ExtrinsicModel.h"
|
||||
|
||||
// Other headers
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// Forward declarations
|
||||
class PrescribedDataManager;
|
||||
class TimeIntegrator;
|
||||
|
||||
/**
|
||||
* @class ATC_Transfer
|
||||
* @brief Base class for atom-continuum transfer operators
|
||||
*/
|
||||
|
||||
class ATC_Transfer {
|
||||
|
||||
public:
|
||||
// NOTE should remove friends and use existing ATC hooks
|
||||
friend class ExtrinsicModel; // friend is not inherited
|
||||
friend class ExtrinsicModelTwoTemperature;
|
||||
friend class ExtrinsicModelDriftDiffusion;
|
||||
friend class ExtrinsicModelElectrostatic;
|
||||
friend class ExtrinsicModelElectrostaticElastic;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name enumerated types */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** boundary integration */
|
||||
enum BoundaryIntegrationType {
|
||||
NO_QUADRATURE=0,
|
||||
FE_QUADRATURE,
|
||||
FE_INTERPOLATION
|
||||
};
|
||||
/** boundary integration */
|
||||
enum IntegrationDomainType {
|
||||
FULL_DOMAIN=0,
|
||||
ATOM_DOMAIN,
|
||||
FE_DOMAIN
|
||||
};
|
||||
/** atomic weight specification */
|
||||
enum AtomicWeightType {
|
||||
USER=0,
|
||||
LATTICE,
|
||||
ELEMENT,
|
||||
REGION,
|
||||
GROUP,
|
||||
MULTISCALE
|
||||
};
|
||||
/** shape function location with respect to MD domain */
|
||||
enum ShapeFunctionType {
|
||||
FE_ONLY = 0,
|
||||
MD_ONLY,
|
||||
BOUNDARY
|
||||
};
|
||||
/** */
|
||||
enum AtomToElementMapType {
|
||||
LAGRANGIAN=0,
|
||||
EULERIAN
|
||||
};
|
||||
/* enumerated type for coupling matrix structure */
|
||||
enum MatrixStructure {
|
||||
FULL=0, // contributions from all nodes
|
||||
LOCALIZED, // contributions only from nodes with sources
|
||||
LUMPED // row-sum lumped version of full matrix
|
||||
};
|
||||
/** */
|
||||
enum GroupThermostatType {
|
||||
RESCALE_TEMPERATURE,
|
||||
RESCALE_TEMPERATURE_RATE,
|
||||
RESCALE_RATE
|
||||
};
|
||||
/** */
|
||||
enum GroupThermostatMomentumControl {
|
||||
NO_MOMENTUM_CONTROL,
|
||||
ZERO_MOMENTUM,
|
||||
PRESERVE_MOMENTUM
|
||||
};
|
||||
/** */
|
||||
enum ATC_GroupComputes { LAMBDA_POWER };
|
||||
/*@}*/
|
||||
|
||||
/** constructor */
|
||||
ATC_Transfer(void);
|
||||
|
||||
/** destructor */
|
||||
virtual ~ATC_Transfer();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre integration run */
|
||||
virtual void initialize();
|
||||
|
||||
/** post integration run : called at end of run or simulation */
|
||||
virtual void finish();
|
||||
|
||||
/** Predictor phase, executed before Verlet */
|
||||
virtual void pre_init_integrate() = 0;
|
||||
|
||||
/** Predictor phase, Verlet first step for velocity */
|
||||
virtual void init_integrate_velocity();
|
||||
|
||||
/** Predictor phase, executed between velocity and position Verlet */
|
||||
virtual void mid_init_integrate() = 0;
|
||||
|
||||
/** Predictor phase, Verlet first step for position */
|
||||
virtual void init_integrate_position();
|
||||
|
||||
/** Predictor phase, executed after Verlet */
|
||||
virtual void post_init_integrate() = 0;
|
||||
|
||||
/** Corrector phase, executed before Verlet */
|
||||
virtual void pre_final_integrate();
|
||||
|
||||
/** Corrector phase, Verlet second step for velocity */
|
||||
virtual void final_integrate();
|
||||
|
||||
/** Corrector phase, executed after Verlet*/
|
||||
virtual void post_final_integrate()=0;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name memory management and processor information exchange */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** pre_exchange is our indicator that atoms have moved across processors */
|
||||
void pre_exchange() {
|
||||
atomSwitch_ = true;
|
||||
}
|
||||
int memory_usage();
|
||||
void grow_arrays(int);
|
||||
void copy_arrays(int, int);
|
||||
int pack_exchange(int, double *);
|
||||
int unpack_exchange(int, double *);
|
||||
int pack_comm(int , int *, double *, int, int *);
|
||||
void unpack_comm(int, int, double *);
|
||||
/*@}*/
|
||||
|
||||
/** Get grouping bit for LAMMPS compatability */
|
||||
int get_groupbit() { return groupbit_; }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name Wrappers for calls to lammps region.h information */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
bool get_region_bounds(const char * regionName,
|
||||
double &xmin, double &xmax,
|
||||
double &ymin, double & ymax,
|
||||
double &zmin, double &zmax,
|
||||
double &xscale,
|
||||
double &yscale,
|
||||
double &zscale);
|
||||
|
||||
/** return pointer to PrescribedDataManager */
|
||||
PrescribedDataManager * get_prescribed_data_manager() {
|
||||
return prescribedDataMgr_;
|
||||
}
|
||||
|
||||
/** return referece to ExtrinsicModelManager */
|
||||
ExtrinsicModelManager & get_extrinsic_model_manager() {
|
||||
return extrinsicModelManager_;
|
||||
}
|
||||
|
||||
/** compute scalar for output */
|
||||
virtual double compute_scalar() {return 0.;}
|
||||
|
||||
/** compute vector for output */
|
||||
virtual double compute_vector(int n) {return 0.;}
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name access methods for output computation data */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
int scalar_flag() const {return scalarFlag_;}
|
||||
int vector_flag() const {return vectorFlag_;}
|
||||
int size_vector() const {return sizeVector_;}
|
||||
int global_freq() const {return globalFreq_;};
|
||||
int extscalar() const {return extScalar_;};
|
||||
int extvector() const {return extVector_;};
|
||||
int * extlist() {return extList_;};
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name Access methods for data used by various methods */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** access to name FE fields */
|
||||
DENS_MAT &get_field(FieldName thisField){return fields_[thisField];};
|
||||
/** access to FE field time derivatives */
|
||||
DENS_MAT &get_dot_field(FieldName thisField){return dot_fields_[thisField];};
|
||||
/** access to name FE source terms */
|
||||
DENS_MAT &get_source(FieldName thisField){return sources_[thisField];};
|
||||
/** access to name atomic source terms */
|
||||
DENS_MAT &get_atomic_source(FieldName thisField){return atomicSources_[thisField];};
|
||||
/** access to name extrinsic source terms */
|
||||
DENS_MAT &get_extrinsic_source(FieldName thisField){return extrinsicSources_[thisField];};
|
||||
/** access to boundary fluxes */
|
||||
DENS_MAT &get_boundary_flux(FieldName thisField){return boundaryFlux_[thisField];};
|
||||
/** access to nodal fields of atomic variables */
|
||||
DENS_MAT &get_atomic_field(FieldName thisField)
|
||||
{ return fieldNdFiltered_[thisField]; };
|
||||
/** access to auxilliary storage */
|
||||
DENS_MAT &get_aux_storage(FieldName thisField)
|
||||
{ return auxStorage_[thisField]; };
|
||||
/** access to all fields */
|
||||
FIELDS &get_fields() {return fields_;};
|
||||
/** access to all fields rates of change (roc) */
|
||||
FIELDS &get_fields_roc() {return dot_fields_;};
|
||||
/** access to all boundary fluxes */
|
||||
FIELDS &get_boundary_fluxes() {return boundaryFlux_;};
|
||||
/** add a new field */
|
||||
void add_fields(map<FieldName,int> & newFieldSizes);
|
||||
/** access to finite element right-hand side data */
|
||||
DENS_MAT &get_field_rhs(FieldName thisField)
|
||||
{ return rhs_[thisField]; };
|
||||
/** access to inverse mass matrices */
|
||||
DIAG_MAT &get_mass_mat_inv(FieldName thisField)
|
||||
{ return massMatInv_[thisField];};
|
||||
DIAG_MAT &get_mass_mat_md(FieldName thisField)
|
||||
{ return massMatsMD_[thisField];};
|
||||
/** access FE rate of change */
|
||||
DENS_MAT &get_field_roc(FieldName thisField)
|
||||
{ return dot_fields_[thisField]; };
|
||||
/** access atomic rate of change contributions to finite element equation */
|
||||
DENS_MAT &get_fe_atomic_field_roc(FieldName thisField)
|
||||
{ return fieldRateNdFiltered_[thisField]; };
|
||||
/** access to atomic rate of change */
|
||||
DENS_MAT &get_atomic_field_roc(FieldName thisField)
|
||||
{return dot_fieldRateNdFiltered_[thisField]; };
|
||||
/** access to second time derivative (2roc) */
|
||||
DENS_MAT &get_field_2roc(FieldName thisField)
|
||||
{ return ddot_fields_[thisField]; };
|
||||
/** access for field mask */
|
||||
Array2D<bool> &get_field_mask() {return fieldMask_;};
|
||||
/** access for shape function weigths */
|
||||
DIAG_MAT &get_shape_function_weights(){return shpWeight_;};
|
||||
/** access to template matrix for control equations */
|
||||
SPAR_MAT &get_m_t_template(){return M_T_Template;};
|
||||
/** access for mapping from global nodes to nodes overlapping MD */
|
||||
Array<int> &get_node_to_overlap_map(){return nodeToOverlapMap_;};
|
||||
/** access for mapping from nodes overlapping MD to global nodes */
|
||||
Array<int> &get_overlap_to_node_map(){return overlapToNodeMap_;};
|
||||
/** number of nodes whose shape function support overlaps with MD */
|
||||
int get_nNode_overlap(){return nNodeOverlap_;};
|
||||
/** check if atomic quadrature is being used for MD_ONLY nodes */
|
||||
bool atom_quadrature_on(){return atomQuadForInternal_;};
|
||||
/** check if lambda is localized */
|
||||
bool use_localized_lambda(){return useLocalizedLambda_;};
|
||||
/** check if matrix should be lumpted for lambda solve */
|
||||
bool use_lumped_lambda_solve(){return useLumpedLambda_;};
|
||||
/** get scaled shape function matrix */
|
||||
SPAR_MAT &get_nhat_overlap() {return NhatOverlap_;};
|
||||
/** get scaled shape function matrix weights */
|
||||
DENS_VEC &get_nhat_overlap_weights() {return NhatOverlapWeights_;};
|
||||
/** get map general atomic shape function matrix to overlap region */
|
||||
SPAR_MAT &get_atom_to_overlap_map() {return Trestrict_;};
|
||||
/** internal atom to global map */
|
||||
Array<int> &get_internal_to_atom_map() {return internalToAtom_;};
|
||||
/** ghost atom to global map */
|
||||
Array<int> &get_ghost_to_atom_map() {return ghostToAtom_;};
|
||||
/** get number of unique FE nodes */
|
||||
int get_nNodes() {return nNodes_;};
|
||||
/** get number of spatial dimensions */
|
||||
int get_nsd() {return nsd_;};
|
||||
/** get number of ATC internal atoms on this processor */
|
||||
int get_nlocal() {return nLocal_;};
|
||||
/** get total number of LAMMPS atoms on this processor */
|
||||
int get_nlocal_total() {return nLocalTotal_;};
|
||||
/** get number of ATC ghost atoms on this processor */
|
||||
int get_nlocal_ghost() {return nLocalGhost_;};
|
||||
/** get number of ATC mask atoms on this processor */
|
||||
int get_nlocal_mask() {return nLocalMask_;};
|
||||
/** get number of ATC atoms used in lambda computation on this processor */
|
||||
int get_nlocal_lambda() {return nLocalLambda_;};
|
||||
/** get number of ATC internal atoms */
|
||||
int get_ninternal() {return nInternal_;}
|
||||
/** get number of ATC ghost atoms */
|
||||
int get_nghost() {return nGhost_;};
|
||||
/** get the current simulation time */
|
||||
double get_sim_time() {return simTime_;};
|
||||
/** access to lammps atomic positions */
|
||||
double ** get_x() {return lammpsInterface_->xatom();};
|
||||
/** access to lammps atomic velocities */
|
||||
double ** get_v() {return lammpsInterface_->vatom();};
|
||||
/** access to lammps atomic forces */
|
||||
double ** get_f() {return lammpsInterface_->fatom();};
|
||||
/** access to physics model */
|
||||
PhysicsModel * get_physics_model() {return physicsModel_; };
|
||||
/** access to time filter */
|
||||
TimeFilterManager * get_time_filter_manager() {return &timeFilterManager_;};
|
||||
/** access to time integrator */
|
||||
TimeIntegrator * get_time_integrator() {return timeIntegrator_;};
|
||||
/** access to FE engine */
|
||||
FE_Engine * get_fe_engine() {return feEngine_;};
|
||||
/** access to faceset names */
|
||||
const set<PAIR> &get_faceset(const string & name) const {return (feEngine_->get_feMesh())->get_faceset(name);};
|
||||
/** access to overlapped ghost shape function */
|
||||
SPAR_MAT & get_shape_function_ghost_overlap(){return shpFcnGhostOverlap_;};
|
||||
/** return fixed node flag for a field */
|
||||
Array2D<bool> & get_fixed_node_flags(FieldName thisField) {return isFixedNode_[thisField];};
|
||||
Array<int> & get_node_type() {return nodeType_;};
|
||||
void get_field(/*const*/ char ** args, int &argIndex,
|
||||
FieldName &thisField, int &thisIndex);
|
||||
DIAG_MAT & get_atomic_weights() {return atomicWeights_;};
|
||||
bool track_charge() {return trackCharge_;};
|
||||
/** access to set of DENS_MATs accessed by tagging */
|
||||
DENS_MAT & get_tagged_dens_mat(const string & tag) {return taggedDensMats_[tag];};
|
||||
/** access to set of SPAR_MATs accessed by tagging */
|
||||
SPAR_MAT & get_tagged_spar_mat(const string & tag) {return taggedSparMats_[tag];};
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name boundary integration */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
void set_boundary_integration_type(int boundaryIntegrationType)
|
||||
{bndyIntType_ = boundaryIntegrationType;};
|
||||
void set_boundary_face_set(const set< pair<int,int> > * boundaryFaceSet)
|
||||
{bndyFaceSet_ = boundaryFaceSet;};
|
||||
BoundaryIntegrationType parse_boundary_integration
|
||||
(int narg, char **arg, const set< pair<int,int> > * boundaryFaceSet);
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name FE nodesets/sidesets functions */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** mask for computation of fluxes */
|
||||
void set_fixed_nodes();
|
||||
|
||||
/** set initial conditions by changing fields */
|
||||
void set_initial_conditions();
|
||||
|
||||
/** calculate and set matrix of sources_ */
|
||||
void set_sources();
|
||||
|
||||
/** array indicating fixed nodes for all fields */
|
||||
map<FieldName, Array2D<bool> > isFixedNode_;
|
||||
|
||||
/** array indicating if the node is boundary, MD, or FE */
|
||||
Array<int> nodeType_;
|
||||
|
||||
/** wrapper for FE_Engine's compute_flux functions */
|
||||
void compute_flux(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
GRAD_FIELDS &flux,
|
||||
const PhysicsModel * physicsModel=NULL);
|
||||
/** wrapper for FE_Engine's compute_boundary_flux functions */
|
||||
void compute_boundary_flux(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &rhs);
|
||||
|
||||
/** wrapper for FE_Engine's compute_rhs_vector functions */
|
||||
void compute_rhs_vector(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &rhs,
|
||||
const IntegrationDomainType domain, // = FULL_DOMAIN
|
||||
const PhysicsModel * physicsModel=NULL);
|
||||
|
||||
/** evaluate rhs on a specified domain defined by mask and physics model */
|
||||
void evaluate_rhs_integral(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &rhs,
|
||||
const IntegrationDomainType domain,
|
||||
const PhysicsModel * physicsModel=NULL);
|
||||
|
||||
/** assemble various contributions to the heat flux in the atomic region */
|
||||
void compute_atomic_sources(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &atomicSources);
|
||||
|
||||
/** multiply inverse mass matrix times given data in place */
|
||||
// NOTE change massMatInv to map of pointers and allow for consistent mass matrices
|
||||
// inverted using CG
|
||||
void apply_inverse_mass_matrix(MATRIX & data, FieldName thisField)
|
||||
{
|
||||
data = massMatInv_[thisField]*data;
|
||||
};
|
||||
/** multiply inverse mass matrix times given data and return result */
|
||||
void apply_inverse_mass_matrix(const MATRIX & data_in, MATRIX & data_out,
|
||||
FieldName thisField)
|
||||
{
|
||||
data_out = massMatInv_[thisField]*data_in;
|
||||
};
|
||||
|
||||
void apply_inverse_md_mass_matrix(MATRIX & data, FieldName thisField)
|
||||
{ data = massMatMDInv_[thisField]*data; };
|
||||
void apply_inverse_md_mass_matrix(const MATRIX & data_in, MATRIX & data_out,
|
||||
FieldName thisField)
|
||||
{ data_out = massMatMDInv_[thisField]*data_in; };
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name FE mapping operations */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** Mapping between unique nodes and nodes overlapping MD region */
|
||||
void map_unique_to_overlap(const MATRIX & uniqueData,
|
||||
MATRIX & overlapData);
|
||||
|
||||
/** Mapping between nodes overlapping MD region to unique nodes */
|
||||
void map_overlap_to_unique(const MATRIX & overlapData,
|
||||
MATRIX & uniqueData);
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name Interscale operators */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** Restrict (number density) : given w_\alpha, w_I = 1/V_I \sum_\alpha N_{I\alpha} w_\alpha */
|
||||
void restrict(const MATRIX &atomData,
|
||||
MATRIX &nodeData);
|
||||
|
||||
/** Restrict based on atomic volume integration : given w_\alpha, w_I = \sum_\alpha N_{I\alpha} w_\alpha V_\alpha */
|
||||
void restrict_unscaled(const MATRIX &atomData,
|
||||
MATRIX &nodeData);
|
||||
|
||||
/** Restrict based on atomic volume integration for volumetric quantities : given w_\alpha, w_I = \sum_\alpha N_{I\alpha} w_\alpha */
|
||||
void restrict_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData);
|
||||
void restrict_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
const SPAR_MAT &shpFcn);
|
||||
|
||||
/** Project based on an atomic volume integration : given w_\alpha, \sum_\alpha M_\alpha w_I = \sum_\alpha N_{I\alpha} w_\alpha V_\alpha (note mass matrix has V_\alpha in it) */
|
||||
void project(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
FieldName thisField);
|
||||
void project_md(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
FieldName thisField);
|
||||
|
||||
/** Project based on an atomic volume integration for volumetric quantities : given w_\alpha, \sum_\alpha M_\alpha w_I = \sum_\alpha N_{I\alpha} w_\alpha */
|
||||
void project_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
FieldName thisField);
|
||||
void project_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
const SPAR_MAT &shpFcn,
|
||||
FieldName thisField);
|
||||
void project_md_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
FieldName thisField);
|
||||
void project_md_volumetric_quantity(const MATRIX &atomData,
|
||||
MATRIX &nodeData,
|
||||
const SPAR_MAT &shpFcn,
|
||||
FieldName thisField);
|
||||
|
||||
/** Prolong : given w_I, w_\alpha = \sum_I N_{I\alpha} w_I */
|
||||
void prolong(const MATRIX &nodeData,
|
||||
MATRIX &atomData);
|
||||
|
||||
/** Prolong based on scaled shape functions : given w_I, w_\alpha = \sum_I 1/V_I N_{I\alpha} w_I */
|
||||
void prolong_scaled(const MATRIX &nodeData,
|
||||
MATRIX &atomData);
|
||||
|
||||
/** Prolong onto ghost atoms*/
|
||||
void prolong_ghost(const MATRIX &nodeData,
|
||||
MATRIX &atomData);
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name Interscale physics constructors */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** Compute atomic masses */
|
||||
void compute_atomic_mass(MATRIX &atomicMasses);
|
||||
|
||||
/** Compute atomic charges */
|
||||
void compute_atomic_charge(MATRIX &atomicCharges);
|
||||
|
||||
/** Compute atomic temperature
|
||||
possibly using dot product of two velocities */
|
||||
void compute_atomic_temperature(MATRIX &T,
|
||||
const double * const* v,
|
||||
double ** v2 = NULL);
|
||||
/** Compute atomic kinetic energy
|
||||
possibly using dot product of two velocities */
|
||||
void compute_atomic_kinetic_energy(MATRIX &T,
|
||||
const double * const* v,
|
||||
double ** v2 = NULL);
|
||||
/** Compute atomic power : in units dT/dt */
|
||||
void compute_atomic_power(MATRIX &dot_T,
|
||||
const double * const* v,
|
||||
const double * const* f);
|
||||
void compute_atomic_temperature_roc(MATRIX &dot_T,
|
||||
const double * const* v,
|
||||
const double * const* f);
|
||||
void compute_atomic_power(MATRIX &dot_T,
|
||||
const double * const* v,
|
||||
const MATRIX & f);
|
||||
void compute_atomic_temperature_roc(MATRIX &dot_T,
|
||||
const double * const* v,
|
||||
const MATRIX & f);
|
||||
|
||||
// NOTE change these when physical mass matrix is used
|
||||
/** Compute magnitude of atomic force */
|
||||
void compute_atomic_force_strength(MATRIX &forceStrength,
|
||||
const double * const* f);
|
||||
void compute_atomic_force_strength(MATRIX &forceStrength,
|
||||
const MATRIX & f);
|
||||
void compute_atomic_force_dot(MATRIX &forceDot,
|
||||
const double * const* f1,
|
||||
const MATRIX & f2);
|
||||
|
||||
/** Compute lambda power at atoms : in units dT/dt */
|
||||
void compute_atomic_temperature_roc(MATRIX &atomicVdotflam,
|
||||
const MATRIX &lambda,
|
||||
const double * const* v);
|
||||
void compute_atomic_power(MATRIX &atomicVdotflam,
|
||||
const MATRIX &lambda,
|
||||
const double * const* v);
|
||||
|
||||
/** Compute lambda power at atoms : in units dT/dt */
|
||||
void compute_atomic_lambda_power(MATRIX &atomicPower,
|
||||
const MATRIX &force,
|
||||
const double * const* v);
|
||||
void compute_atomic_temperature_lambda_roc(MATRIX &atomicPower,
|
||||
const MATRIX &force,
|
||||
const double * const* v);
|
||||
|
||||
/** Compute lambda power at atoms with explicit application */
|
||||
void compute_lambda_power_explicit(MATRIX &lambdaPower,
|
||||
const MATRIX &lambda,
|
||||
const double * const* v,
|
||||
const double dt);
|
||||
|
||||
/** Compute atomic position */
|
||||
void compute_atomic_position(DENS_MAT &atomicDisplacement,
|
||||
const double * const* x);
|
||||
|
||||
/** Compute atomic center of mass */
|
||||
void compute_atomic_centerOfMass(DENS_MAT &atomicCom,
|
||||
const double * const* x);
|
||||
|
||||
/** Compute atomic displacement */
|
||||
void compute_atomic_displacement(DENS_MAT &atomicDisplacement,
|
||||
const double * const* x);
|
||||
|
||||
/** Compute atomic mass displacement */
|
||||
void compute_atomic_centerOfMass_displacement(DENS_MAT &atomicMd,
|
||||
const double * const* x);
|
||||
|
||||
/** Compute atomic velocity */
|
||||
void compute_atomic_velocity(DENS_MAT &atomicVelocity,
|
||||
const double * const* v);
|
||||
|
||||
/** Compute atomic momentum */
|
||||
void compute_atomic_momentum(DENS_MAT &atomicMomentum,
|
||||
const double * const* v);
|
||||
|
||||
/** Compute atomic acceleration */
|
||||
void compute_atomic_acceleration(DENS_MAT &atomicAcceleration,
|
||||
const double * const* f);
|
||||
|
||||
/** Compute atomic force */
|
||||
void compute_atomic_force(DENS_MAT &atomicForce,
|
||||
const double * const* f);
|
||||
/*@}*/
|
||||
|
||||
/** allow FE_Engine to construct ATC structures after mesh is constructed */
|
||||
void initialize_mesh_data(void);
|
||||
|
||||
protected:
|
||||
|
||||
/** pointer to lammps interface class */
|
||||
LammpsInterface * lammpsInterface_;
|
||||
|
||||
/** pointer to physics model */
|
||||
PhysicsModel * physicsModel_;
|
||||
|
||||
/** manager for extrinsic models */
|
||||
ExtrinsicModelManager extrinsicModelManager_;
|
||||
|
||||
/** method to create physics model */
|
||||
void create_physics_model(const PhysicsType & physicsType,
|
||||
string matFileName);
|
||||
|
||||
/** global flag to indicate atoms have changed processor
|
||||
keyed off of atomSwitch (see pre_exchange() which sets atomSwitch =true)
|
||||
*/
|
||||
int globalSwitch_ ;
|
||||
|
||||
/** a global flag to trigger reset of shape function at will */
|
||||
bool resetSwitch_;
|
||||
|
||||
/** flag on if initialization has been performed */
|
||||
bool initialized_;
|
||||
|
||||
/** flag to determine if charge is tracked */
|
||||
bool trackCharge_;
|
||||
|
||||
TimeFilterManager timeFilterManager_;
|
||||
TimeIntegrator * timeIntegrator_;
|
||||
|
||||
/** finite element handler */
|
||||
FE_Engine * feEngine_;
|
||||
|
||||
/** prescribed data handler */
|
||||
PrescribedDataManager * prescribedDataMgr_;
|
||||
|
||||
/** reference atomic coordinates */
|
||||
DENS_MAT atomicCoords_;
|
||||
DENS_MAT atomicCoordsMask_;
|
||||
|
||||
/** number of unique FE nodes */
|
||||
int nNodes_;
|
||||
|
||||
/** Number of Spatial Dimensions */
|
||||
int nsd_;
|
||||
|
||||
/** data for handling atoms crossing processors */
|
||||
bool atomSwitch_;
|
||||
|
||||
/** reference position of the atoms */
|
||||
double ** xref_;
|
||||
double Xprd_,Yprd_,Zprd_;
|
||||
double XY_,YZ_,XZ_;
|
||||
void set_xref();
|
||||
|
||||
/** current time in simulation */
|
||||
double simTime_;
|
||||
|
||||
/** re-read reference positions */
|
||||
bool readXref_;
|
||||
string xRefFile_;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name FE nodesets/sidesets data */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** mask for computation of fluxes */
|
||||
Array2D<bool> fieldMask_;
|
||||
|
||||
/** sources */
|
||||
FIELDS sources_;
|
||||
FIELDS atomicSources_;
|
||||
FIELDS extrinsicSources_;
|
||||
|
||||
/** boundary flux quadrature */
|
||||
int bndyIntType_;
|
||||
const set< pair<int,int> > * bndyFaceSet_;
|
||||
set<string> boundaryFaceNames_;
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name output data */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** base name for output files */
|
||||
string outputPrefix_;
|
||||
|
||||
/** output frequency */
|
||||
int outputFrequency_;
|
||||
|
||||
/** sample frequency */
|
||||
int sampleFrequency_;
|
||||
|
||||
/** step counter */
|
||||
int stepCounter_;
|
||||
|
||||
/** sample counter */
|
||||
int sampleCounter_;
|
||||
|
||||
/** atomic output */
|
||||
/** base name for output files */
|
||||
string outputPrefixAtom_;
|
||||
|
||||
/** output frequency */
|
||||
int outputFrequencyAtom_;
|
||||
|
||||
/** output object */
|
||||
OutputManager mdOutputManager_;
|
||||
set<string> atomicOutputMask_;
|
||||
/*@}*/
|
||||
//---------------------------------------------------------------
|
||||
/** \name output functions */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
void output();
|
||||
void atomic_output();
|
||||
/*@}*/
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name member data related to compute_scalar() and compute_vector() */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
int scalarFlag_; // 0/1 if compute_scalar() function exists
|
||||
int vectorFlag_; // 0/1 if compute_vector() function exists
|
||||
int sizeVector_; // N = size of global vector
|
||||
int globalFreq_; // frequency global data is available at
|
||||
int extScalar_; // 0/1 if scalar is intensive/extensive
|
||||
int extVector_; // 0/1/-1 if vector is all int/ext/extlist
|
||||
int *extList_; // list of 0/1 int/ext for each vec component
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name fields and necessary data for FEM */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
map<FieldName,int> fieldSizes_;
|
||||
FIELDS fields_;
|
||||
map<FieldName,DIAG_MAT > massMats_;
|
||||
map<FieldName,DIAG_MAT > massMatInv_;
|
||||
map<FieldName,DIAG_MAT > massMatsMD_;
|
||||
map<FieldName,DIAG_MAT > massMatMDInv_;
|
||||
virtual void compute_md_mass_matrix(FieldName thisField,
|
||||
map<FieldName,DIAG_MAT> & massMats) {};
|
||||
DENS_MAT consistentMassInverse_;
|
||||
FIELDS rhs_; // for pde
|
||||
FIELDS rhsAtomDomain_; // for thermostat
|
||||
FIELDS boundaryFlux_; // for thermostat & rhs pde
|
||||
/*@}*/
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name time integration and filtering fields */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
|
||||
FIELDS dot_fields_;
|
||||
FIELDS ddot_fields_;
|
||||
FIELDS dddot_fields_;
|
||||
FIELDS dot_fieldsMD_;
|
||||
FIELDS ddot_fieldsMD_;
|
||||
FIELDS dot_dot_fieldsMD_;
|
||||
|
||||
/** Restricted Fields */
|
||||
FIELDS fieldNdOld_;
|
||||
FIELDS fieldNdFiltered_;
|
||||
FIELDS fieldRateNdOld_;
|
||||
FIELDS fieldRateNdFiltered_;
|
||||
FIELDS dot_fieldRateNdOld_;
|
||||
FIELDS dot_fieldRateNdFiltered_;
|
||||
|
||||
/** auxilliary storage */
|
||||
FIELDS auxStorage_;
|
||||
/*@}*/
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name quadrature weights */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
DIAG_MAT NodeVolumes_;
|
||||
DIAG_MAT invNodeVolumes_;
|
||||
/** atomic quadrature integration weights (V_\alpha) */
|
||||
DIAG_MAT atomicWeights_;
|
||||
DIAG_MAT atomicWeightsMask_;
|
||||
double atomicVolume_; // global atomic volume for homogeneous set of atoms
|
||||
map<int,double> Valpha_;
|
||||
AtomicWeightType atomWeightType_;
|
||||
/** weighting factor per shape function:
|
||||
shpWeight_(I,I) = 1/N_I = 1/(\sum_\alpha N_{I\alpha}) */
|
||||
DIAG_MAT shpWeight_;
|
||||
DIAG_MAT fluxMask_;
|
||||
DIAG_MAT fluxMaskComplement_;
|
||||
/*@}*/
|
||||
//---------------------------------------------------------------
|
||||
/** \name quadrature weight function */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** determine weighting method for atomic integration */
|
||||
void reset_atomicWeightsLattice();
|
||||
void reset_atomicWeightsElement();
|
||||
void reset_atomicWeightsRegion();
|
||||
void reset_atomicWeightsGroup();
|
||||
void reset_atomicWeightsMultiscale(const SPAR_MAT & shapeFunctionMatrix,
|
||||
DIAG_MAT & atomicVolumeMatrix);
|
||||
|
||||
void compute_consistent_md_mass_matrix(const SPAR_MAT & shapeFunctionMatrix,
|
||||
SPAR_MAT & mdMassMatrix);
|
||||
|
||||
/** resets shape function matrices based on atoms on this processor */
|
||||
virtual void reset_nlocal();
|
||||
void reset_coordinates();
|
||||
void set_atomic_weights();
|
||||
virtual void reset_shape_functions();
|
||||
void reset_NhatOverlap();
|
||||
/*@}*/
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name atom data */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** bitwise comparisons for boundary (ghost) atoms */
|
||||
int groupbit_;
|
||||
int groupbitGhost_;
|
||||
set<int> igroups_;
|
||||
set<int> igroupsGhost_;
|
||||
|
||||
/** number of atoms of correct type,
|
||||
ghosts are atoms outside our domain of interest
|
||||
boundary are atoms contributing to boundary flux terms */
|
||||
/** Number of "internal" atoms on this processor */
|
||||
int nLocal_;
|
||||
/** Number of atoms on this processor */
|
||||
int nLocalTotal_;
|
||||
int nLocalGhost_;
|
||||
int nLocalMask_;
|
||||
int nLocalLambda_;
|
||||
int nInternal_;
|
||||
int nGhost_;
|
||||
Array<int> internalToAtom_;
|
||||
std::map<int,int> atomToInternal_;
|
||||
Array<int> ghostToAtom_;
|
||||
DENS_MAT ghostAtomCoords_;
|
||||
/*@}*/
|
||||
//----------------------------------------------------------------
|
||||
/** \name maps and masks */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
AtomToElementMapType atomToElementMapType_;
|
||||
int atomToElementMapFrequency_;
|
||||
Array<int> atomToElementMap_;
|
||||
Array<int> ghostAtomToElementMap_;
|
||||
/** overlap map, from shapeWeights */
|
||||
// -1 is no overlap, otherwise entry is overlap index
|
||||
Array<int> nodeToOverlapMap_;
|
||||
// mapping from overlap nodes to unique nodes
|
||||
Array<int> overlapToNodeMap_;
|
||||
int nNodeOverlap_;
|
||||
Array<bool> elementMask_;
|
||||
Array<int> elementToMaterialMap_;
|
||||
Array< set <int> > atomMaterialGroups_;
|
||||
int regionID_;
|
||||
bool atomQuadForInternal_;
|
||||
bool useLocalizedLambda_;
|
||||
bool useLumpedLambda_;
|
||||
/*@}*/
|
||||
//----------------------------------------------------------------
|
||||
/** \name Map related functions */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
bool check_internal(int eltIdx);
|
||||
int check_shape_function_type(int nodeIdx);
|
||||
bool intersect_ghost(int eltIdx);
|
||||
virtual void set_ghost_atoms() = 0;
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name shape function matrices */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
// sparse matrix where columns correspond to global node numbering
|
||||
// dimensions are numAtoms X numNodes (the transpose of N_{I\alpha} )
|
||||
/** shpFcn_ is N_{I\alpha} the un-normalized shape function evaluated at the atoms */
|
||||
SPAR_MAT shpFcn_;
|
||||
vector<SPAR_MAT > shpFcnDerivs_;
|
||||
SPAR_MAT shpFcnGhost_;
|
||||
SPAR_MAT shpFcnGhostOverlap_;
|
||||
vector<SPAR_MAT > shpFcnDerivsGhost_;
|
||||
SPAR_MAT shpFcnMasked_;
|
||||
vector<SPAR_MAT > shpFcnDerivsMask_;
|
||||
Array<bool> atomMask_;
|
||||
|
||||
/** map from species string tag to the species density */
|
||||
map<string,DENS_MAT> taggedDensMats_;
|
||||
/** map from species string tag to shape function and weight matrices */
|
||||
map<string,SPAR_MAT> taggedSparMats_;
|
||||
|
||||
/** weighted shape function matrices at overlap nodes
|
||||
for use with thermostats */
|
||||
// dimensions are numAtoms X numNodesOverlap
|
||||
SPAR_MAT NhatOverlap_;
|
||||
SPAR_MAT Trestrict_;
|
||||
DENS_VEC NhatOverlapWeights_;
|
||||
/*@}*/
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name thermostat data */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** sparse matrix to store elements needed for CG solve */
|
||||
SPAR_MAT M_T_Template;
|
||||
DIAG_MAT maskMat_;
|
||||
|
||||
bool equilibriumStart_;
|
||||
//---------------------------------------------------------------
|
||||
/** \name time filtering */
|
||||
//---------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** allocate memory for time filter */
|
||||
void init_filter();
|
||||
void update_filter(MATRIX &filteredQuantity,
|
||||
const MATRIX &unfilteredQuantity,
|
||||
MATRIX &unfilteredQuantityOld,
|
||||
const double dt);
|
||||
|
||||
double get_unfiltered_coef(const double dt);
|
||||
|
||||
void update_filter_implicit(MATRIX &filteredQuantity,
|
||||
const MATRIX &unfilteredQuantity,
|
||||
const double dt);
|
||||
/*@}*/
|
||||
|
||||
/** group computes : type, group_id -> value */
|
||||
map< pair < int, int > , double> groupCompute_;
|
||||
|
||||
/** group computes : type, group_id -> value */
|
||||
map< pair < string, FieldName > , double> nsetCompute_;
|
||||
|
||||
/** allow FE_Engine to construct data manager after mesh is constructed */
|
||||
void construct_prescribed_data_manager (void);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name restart procedures */
|
||||
//---------------------------------------------------------------
|
||||
bool useRestart_;
|
||||
string restartFileName_;
|
||||
virtual void read_restart_data(string fileName_, OUTPUT_LIST & data);
|
||||
virtual void write_restart_data(string fileName_, OUTPUT_LIST & data);
|
||||
void pack_fields(OUTPUT_LIST & data);
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/** \name neighbor reset frequency */
|
||||
//---------------------------------------------------------------
|
||||
int neighborResetFrequency_;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,346 +0,0 @@
|
|||
/** ATC_TransferHardy : Hardy smoothing */
|
||||
#ifndef ATC_TRANSFER_HARDY_H
|
||||
#define ATC_TRANSFER_HARDY_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "ATC_Transfer.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "ATC_HardyKernel.h"
|
||||
#include "TimeFilter.h"
|
||||
|
||||
// Other headers
|
||||
#include <map>
|
||||
#include <list>
|
||||
using std::list;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
enum hardyNormalization {
|
||||
NO_NORMALIZATION=0,
|
||||
VOLUME_NORMALIZATION, NUMBER_NORMALIZATION, MASS_NORMALIZATION
|
||||
};
|
||||
|
||||
enum hardyFieldName {
|
||||
HARDY_DENSITY=0,
|
||||
HARDY_DISPLACEMENT,
|
||||
HARDY_MOMENTUM,
|
||||
HARDY_VELOCITY,
|
||||
HARDY_PROJECTED_VELOCITY,
|
||||
HARDY_TEMPERATURE,
|
||||
HARDY_KINETIC_TEMPERATURE,
|
||||
HARDY_STRESS,
|
||||
HARDY_HEAT_FLUX,
|
||||
HARDY_ENERGY,
|
||||
HARDY_NUMBER_DENSITY,
|
||||
HARDY_ESHELBY_STRESS,
|
||||
HARDY_CAUCHY_BORN_STRESS,
|
||||
HARDY_TRANSFORMED_STRESS,
|
||||
HARDY_VACANCY_CONCENTRATION,
|
||||
HARDY_TYPE_CONCENTRATION,
|
||||
NUM_HARDY_FIELDS
|
||||
};
|
||||
|
||||
/** string to field enum */
|
||||
static bool string_to_hardy_field(const string & name, hardyFieldName & index) {
|
||||
if (name=="density")
|
||||
index = HARDY_DENSITY;
|
||||
else if (name=="displacement")
|
||||
index = HARDY_DISPLACEMENT;
|
||||
else if (name=="momentum")
|
||||
index = HARDY_MOMENTUM;
|
||||
else if (name=="velocity")
|
||||
index = HARDY_VELOCITY;
|
||||
else if (name=="projected_velocity")
|
||||
index = HARDY_PROJECTED_VELOCITY;
|
||||
else if (name=="temperature")
|
||||
index = HARDY_TEMPERATURE;
|
||||
else if (name=="kinetic_temperature")
|
||||
index = HARDY_KINETIC_TEMPERATURE; // temperature from full KE
|
||||
else if (name=="stress")
|
||||
index = HARDY_STRESS;
|
||||
else if (name=="eshelby_stress")
|
||||
index = HARDY_ESHELBY_STRESS;
|
||||
else if (name=="cauchy_born_stress")
|
||||
index = HARDY_CAUCHY_BORN_STRESS;
|
||||
else if (name=="heat_flux")
|
||||
index = HARDY_HEAT_FLUX;
|
||||
else if (name=="energy")
|
||||
index = HARDY_ENERGY;
|
||||
else if (name=="number_density")
|
||||
index = HARDY_NUMBER_DENSITY;
|
||||
else if (name=="transformed_stress")
|
||||
index = HARDY_TRANSFORMED_STRESS;
|
||||
else if (name=="vacancy_concentration")
|
||||
index = HARDY_VACANCY_CONCENTRATION;
|
||||
else if (name=="type_concentration")
|
||||
index = HARDY_TYPE_CONCENTRATION;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/** string to field enum */
|
||||
static bool hardy_field_to_string(const int & index,string & name)
|
||||
{
|
||||
if (index==HARDY_DENSITY)
|
||||
name = "density";
|
||||
else if (index==HARDY_DISPLACEMENT)
|
||||
name = "displacement";
|
||||
else if (index==HARDY_MOMENTUM)
|
||||
name = "momentum";
|
||||
else if (index == HARDY_VELOCITY)
|
||||
name="velocity";
|
||||
else if (index == HARDY_PROJECTED_VELOCITY)
|
||||
name="projected_velocity";
|
||||
else if (index == HARDY_TEMPERATURE)
|
||||
name="temperature";
|
||||
else if (index == HARDY_KINETIC_TEMPERATURE)
|
||||
name="kinetic_temperature";
|
||||
else if (index == HARDY_STRESS)
|
||||
name="stress";
|
||||
else if (index == HARDY_ESHELBY_STRESS)
|
||||
name="eshelby_stress";
|
||||
else if (index == HARDY_CAUCHY_BORN_STRESS)
|
||||
name="cauchy_born_stress";
|
||||
else if (index == HARDY_HEAT_FLUX)
|
||||
name="heat_flux";
|
||||
else if (index == HARDY_ENERGY)
|
||||
name="energy";
|
||||
else if (index == HARDY_NUMBER_DENSITY)
|
||||
name="number_density";
|
||||
else if (index == HARDY_TRANSFORMED_STRESS)
|
||||
name="transformed_stress";
|
||||
else if (index == HARDY_VACANCY_CONCENTRATION)
|
||||
name="vacancy_concentration";
|
||||
else if (index == HARDY_TYPE_CONCENTRATION)
|
||||
name="type_concentration";
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Forward declarations
|
||||
class FE_Engine;
|
||||
class StressCauchyBorn;
|
||||
|
||||
class ATC_TransferHardy : public ATC_Transfer {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ATC_TransferHardy(std::string groupName, std::string matParamFile = "none");
|
||||
|
||||
// destructor
|
||||
~ATC_TransferHardy();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
/** post time integration */
|
||||
virtual void finish();
|
||||
|
||||
/** first time substep routines */
|
||||
virtual void pre_init_integrate();
|
||||
virtual void init_integrate_velocity(){};
|
||||
virtual void mid_init_integrate(){};
|
||||
virtual void init_integrate_position(){};
|
||||
virtual void post_init_integrate();
|
||||
|
||||
|
||||
/** second time substep routine */
|
||||
virtual void pre_final_integrate();
|
||||
virtual void final_integrate(){};
|
||||
virtual void post_final_integrate();
|
||||
|
||||
virtual void set_ghost_atoms() {};
|
||||
|
||||
private:
|
||||
/** pointer to position data : either x_reference or x_current */
|
||||
double ** xPointer_;
|
||||
|
||||
/** data */
|
||||
map <string, DENS_MAT > hardyData_;
|
||||
map <string, DENS_MAT > hardyDataOld_;
|
||||
map <string, DENS_MAT > filteredHardyData_;
|
||||
DENS_MAT atomicTemperature_;
|
||||
DENS_MAT atomicKineticTemperature_;
|
||||
DENS_MAT atomicDensity_;
|
||||
DENS_MAT atomicMomentum_;
|
||||
DENS_MAT atomicDisplacement_;
|
||||
DENS_MAT atomicVelocity_;
|
||||
DENS_MAT atomicStress_;
|
||||
DENS_MAT atomicHeat_;
|
||||
DENS_MAT atomicEnergy_;
|
||||
|
||||
/** reference data */
|
||||
bool setRefPE_;
|
||||
DENS_MAT nodalRefPotentialEnergy_;
|
||||
double nodalRefPEvalue_;
|
||||
bool setRefPEvalue_;
|
||||
|
||||
/** contour/boundary integral data */
|
||||
map < pair<string,string>, const set< PAIR > * > bndyIntegralData_;
|
||||
map < pair<string,string>, const set< PAIR > * > contourIntegralData_;
|
||||
|
||||
/** workset data */
|
||||
SPAR_MAT kernelShpFcn_;
|
||||
SPAR_MAT atomicBondTable_;
|
||||
DENS_MAT vbar_;
|
||||
DENS_MAT ubar_;
|
||||
DENS_MAT atomicForceTable_;
|
||||
DENS_MAT atomicHeatTable_;
|
||||
DENS_MAT uVariationVelocity_;
|
||||
vector< SPAR_MAT > gradientTable_;
|
||||
|
||||
/** calculation flags */
|
||||
Array<bool> fieldFlags_;
|
||||
Array<bool> outputFlags_;
|
||||
Array<bool> gradFlags_;
|
||||
Array<bool> rateFlags_;
|
||||
map<string,int> computes_;
|
||||
|
||||
/** calculation flags */
|
||||
Array<int> fieldSizes_;
|
||||
|
||||
/** compute nodal quantities */
|
||||
void compute_potential_energy(DENS_MAT & nodalPE);
|
||||
void compute_number_density(DENS_MAT & density);
|
||||
void compute_mass_density(DENS_MAT & density);
|
||||
void compute_displacement(DENS_MAT & displacement,
|
||||
const DENS_MAT & density);
|
||||
void compute_momentum(DENS_MAT & momentum);
|
||||
void compute_projected_velocity(DENS_MAT & velocity);
|
||||
void compute_velocity(DENS_MAT & velocity,
|
||||
const DENS_MAT & density, const DENS_MAT & momentum);
|
||||
void compute_variation_velocity(DENS_MAT & velocity,
|
||||
const DENS_MAT & vI);
|
||||
void compute_temperature(DENS_MAT & temperature);
|
||||
void compute_kinetic_temperature(DENS_MAT & temperature);
|
||||
void compute_stress(DENS_MAT & stress);
|
||||
void compute_heatflux(DENS_MAT & flux);
|
||||
void compute_total_energy(DENS_MAT & energy);
|
||||
void compute_eshelby_stress(DENS_MAT & eshebly_stress,
|
||||
const DENS_MAT & energy, const DENS_MAT & stress,
|
||||
const DENS_MAT & displacement_gradient);
|
||||
void compute_cauchy_born_stress(DENS_MAT & cb_stress,
|
||||
const DENS_MAT & displacement_gradient);
|
||||
void compute_transformed_stress(DENS_MAT & stress,
|
||||
const DENS_MAT & T, const DENS_MAT & displacement_gradient);
|
||||
void compute_vacancy_concentration(DENS_MAT & vacancy_concentration,
|
||||
const DENS_MAT & displacement_gradient,
|
||||
const DENS_MAT & number_density);
|
||||
void compute_type_concentration(DENS_MAT & type_concentration);
|
||||
|
||||
/** compute smooth fields */
|
||||
void compute_fields(void);
|
||||
void time_filter_pre (double dt, bool output_now = true);
|
||||
void time_filter_post(double dt, bool output_now = true);
|
||||
|
||||
/** compute boundary integral */
|
||||
void compute_boundary_integrals(void);
|
||||
|
||||
/** output function */
|
||||
void output();
|
||||
|
||||
/** physics specific filter initialization */
|
||||
void init_filter();
|
||||
|
||||
/** kernel */
|
||||
ATC_HardyKernel* kernelFunction_;
|
||||
|
||||
/** mapping of atomic pairs to pair index value */
|
||||
map< pair< int,int >,int > pairMap_;
|
||||
int nPairs_;
|
||||
|
||||
/** routine to compute pair map */
|
||||
void compute_pair_map();
|
||||
|
||||
/** routine to calculate matrix of Hardy bond functions */
|
||||
void compute_bond_matrix();
|
||||
|
||||
/** routine to calculate matrix of kernel shape functions */
|
||||
void compute_kernel_matrix();
|
||||
|
||||
/** routine to calculate matrix of gradient of Hardy functions */
|
||||
void compute_gradient_matrix();
|
||||
|
||||
/** routine to check pair map */
|
||||
void check_pair_map();
|
||||
|
||||
/** routine to calculate matrix of force & position dyads */
|
||||
void compute_force_matrix();
|
||||
|
||||
/** routine to calculate matrix of heat flux vector components */
|
||||
void compute_heat_matrix();
|
||||
|
||||
/** routine to calculate stress on-the-fly */
|
||||
void compute_potential_stress(DENS_MAT& stress);
|
||||
|
||||
/** routine to calculate force part of the heat flux on-the-fly */
|
||||
void compute_potential_heatflux(DENS_MAT& flux);
|
||||
|
||||
/** periodicity flags and lengths */
|
||||
int periodicity[3];
|
||||
double box_bounds[2][3];
|
||||
double box_length[3];
|
||||
|
||||
/** routine to adjust node-pair distances due to periodicity */
|
||||
void periodicity_correction(DENS_VEC& xaI);
|
||||
|
||||
/** routine to set xPointer to xref or xatom */
|
||||
void set_xPointer();
|
||||
|
||||
/** number of atom types */
|
||||
int nTypes_;
|
||||
|
||||
protected:
|
||||
|
||||
/** project (number density): given w_\alpha,
|
||||
w_I = \sum_\alpha N_{I\alpha} w_\alpha */
|
||||
void project_count_normalized(const DENS_MAT & atomData,
|
||||
DENS_MAT & nodeData);
|
||||
|
||||
/** hardy_project (volume density): given w_\alpha,
|
||||
w_I = 1/\Omega_I \sum_\alpha N_{I\alpha} w_\alpha
|
||||
where \Omega_I = \int_{support region of node I} N_{I} dV */
|
||||
void project_volume_normalized(const DENS_MAT & atomData,
|
||||
DENS_MAT & nodeData);
|
||||
|
||||
/** gradient_compute: given w_I,
|
||||
w_J = \sum_I N_I'{xJ} \dyad w_I
|
||||
where N_I'{xJ} is the gradient of the normalized
|
||||
shape function of node I evaluated at node J */
|
||||
void gradient_compute(const DENS_MAT & inNodeData,
|
||||
DENS_MAT & outNodeData);
|
||||
|
||||
int nNodesGlobal_;
|
||||
|
||||
/** compute kernel shape functions on-the-fly w/o storing N_Ia */
|
||||
bool kernelOnTheFly_;
|
||||
|
||||
/** compute stress or heat flux on-the-fly w/o storing B_Iab */
|
||||
bool bondOnTheFly_;
|
||||
|
||||
/** if false, no coarse velocity is calculated for kernel-based estimates */
|
||||
bool useAtomicShapeFunctions_;
|
||||
|
||||
/** a continuum model to compare to and/or estimate Hardy quantities */
|
||||
StressCauchyBorn * cauchyBornStress_;
|
||||
|
||||
const LammpsInterface * constLammpsInterface_;
|
||||
|
||||
Array<TimeFilter *> timeFilters_;
|
||||
|
||||
/** check consistency of fieldFlags_ */
|
||||
void check_fieldFlags_consistency();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,541 +0,0 @@
|
|||
// ATC_Transfer headers
|
||||
#include "ATC_TransferThermal.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "PrescribedDataManager.h"
|
||||
|
||||
// Other Headers
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
ATC_TransferThermal::ATC_TransferThermal(string groupName,
|
||||
string matParamFile,
|
||||
ExtrinsicModelType extrinsicModel)
|
||||
: ATC_Transfer(),
|
||||
thermostat_(this),
|
||||
pmfcOn_(false)
|
||||
{
|
||||
// assign default "internal" group
|
||||
int igroup = lammpsInterface_->find_group(groupName.c_str());
|
||||
groupbit_ |= lammpsInterface_->group_bit(igroup);
|
||||
igroups_.insert(igroup);
|
||||
|
||||
// Allocate PhysicsModel
|
||||
create_physics_model(THERMAL, matParamFile);
|
||||
|
||||
// create extrinsic physics model
|
||||
if (extrinsicModel != NO_MODEL) {
|
||||
extrinsicModelManager_.create_model(extrinsicModel,matParamFile);
|
||||
}
|
||||
|
||||
simTime_ = 0.;
|
||||
integrationType_ = TimeIntegrator::VERLET;
|
||||
atomicOutputMask_.insert("temperature");
|
||||
|
||||
// set up field data based on physicsModel
|
||||
physicsModel_->get_num_fields(fieldSizes_,fieldMask_);
|
||||
|
||||
// output variable vector info:
|
||||
// output[1] = total coarse scale thermal energy
|
||||
// output[2] = average temperature
|
||||
vectorFlag_ = 1;
|
||||
sizeVector_ = 2;
|
||||
globalFreq_ = 1;
|
||||
extVector_ = 1;
|
||||
if (extrinsicModel != NO_MODEL)
|
||||
sizeVector_ += extrinsicModelManager_.size_vector(sizeVector_);
|
||||
}
|
||||
|
||||
ATC_TransferThermal::~ATC_TransferThermal()
|
||||
{
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::initialize()
|
||||
{
|
||||
// Base class initalizations
|
||||
ATC_Transfer::initialize();
|
||||
|
||||
if (!timeFilterManager_.filter_dynamics()) {
|
||||
DENS_VEC atomicKineticEnergy(nLocal_);
|
||||
compute_atomic_kinetic_energy(atomicKineticEnergy, lammpsInterface_->vatom());
|
||||
project_volumetric_quantity(atomicKineticEnergy,fieldNdFiltered_[TEMPERATURE],TEMPERATURE);
|
||||
fieldNdFiltered_[TEMPERATURE] *= 2.;
|
||||
}
|
||||
|
||||
thermostat_.initialize();
|
||||
extrinsicModelManager_.initialize();
|
||||
|
||||
if (!initialized_) {
|
||||
// initialize sources based on initial FE temperature
|
||||
double dt = lammpsInterface_->dt();
|
||||
prescribedDataMgr_->set_sources(simTime_+.5*dt,sources_);
|
||||
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||||
thermostat_.compute_boundary_flux(fields_);
|
||||
compute_atomic_sources(fieldMask_,fields_,atomicSources_);
|
||||
}
|
||||
|
||||
if (timeFilterManager_.need_reset()) {
|
||||
init_filter();
|
||||
timeFilterManager_.initialize();
|
||||
}
|
||||
|
||||
// reset integration field mask
|
||||
temperatureMask_.reset(NUM_FIELDS,NUM_FLUX);
|
||||
temperatureMask_ = false;
|
||||
for (int i = 0; i < NUM_FLUX; i++)
|
||||
temperatureMask_(TEMPERATURE,i) = fieldMask_(TEMPERATURE,i);
|
||||
initialized_ = true;
|
||||
|
||||
|
||||
if (pmfcOn_) {
|
||||
oldFieldTemp_.reset(nNodes_,1);
|
||||
}
|
||||
|
||||
// read in field data if necessary
|
||||
if (useRestart_) {
|
||||
OUTPUT_LIST data;
|
||||
read_restart_data(restartFileName_,data);
|
||||
useRestart_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::init_filter()
|
||||
{
|
||||
// NOTE assume total filtered time derivatives are zero
|
||||
ATC_Transfer::init_filter();
|
||||
|
||||
if (integrationType_==TimeIntegrator::VERLET) {
|
||||
// initialize restricted fields
|
||||
// NOTE: comment in to initialize fieldRateNdOld_ to current time deriviative
|
||||
// current assumption is that it is zero
|
||||
//DenseMatrix<double> atomicPower(nLocal_,1);
|
||||
//compute_atomic_power(atomicPower,
|
||||
// lammpsInterface_->vatom(),
|
||||
// lammpsInterface_->fatom());
|
||||
//restrict(atomicPower,fieldRateNdOld_[TEMPERATURE]);
|
||||
//fieldRateNdOld *= 2.;
|
||||
|
||||
DENS_MAT atomicKineticEnergy(nLocal_,1);
|
||||
DENS_MAT nodalAtomicTemperature(nNodes_,1);
|
||||
compute_atomic_temperature(atomicKineticEnergy,
|
||||
lammpsInterface_->vatom());
|
||||
restrict(atomicKineticEnergy, nodalAtomicTemperature);
|
||||
nodalAtomicTemperature *= 2.;
|
||||
fieldNdOld_[TEMPERATURE] = nodalAtomicTemperature;
|
||||
}
|
||||
|
||||
if (timeFilterManager_.end_equilibrate()) { // set up correct initial lambda power to enforce initial temperature rate of 0
|
||||
if (integrationType_==TimeIntegrator::VERLET) {
|
||||
if (equilibriumStart_) {
|
||||
if (thermostat_.get_thermostat_type()==Thermostat::FLUX) { // based on FE equation
|
||||
DENS_MAT vdotflamMat(-2.*fieldRateNdFiltered_[TEMPERATURE]); // note 2 is for 1/2 vdotflam addition
|
||||
thermostat_.reset_lambda_power(vdotflamMat);
|
||||
}
|
||||
else { // based on MD temperature equation
|
||||
DENS_MAT vdotflamMat(-1.*fieldRateNdFiltered_[TEMPERATURE]);
|
||||
thermostat_.reset_lambda_power(vdotflamMat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // set up space for filtered atomic power
|
||||
// should set up all data structures common to equilibration and filtering,
|
||||
// specifically filtered atomic power
|
||||
if (integrationType_==TimeIntegrator::FRACTIONAL_STEP) {
|
||||
dot_atomicTemp.reset(nNodes_,1);
|
||||
dot_atomicTempOld.reset(nNodes_,1);
|
||||
dot_dot_atomicTemp.reset(nNodes_,1);
|
||||
dot_dot_atomicTempOld.reset(nNodes_,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::compute_md_mass_matrix(FieldName thisField,
|
||||
map<FieldName,DIAG_MAT> & massMats)
|
||||
{
|
||||
if (thisField == TEMPERATURE) {
|
||||
DENS_VEC atomicCapacity(nLocal_);
|
||||
atomicCapacity = nsd_*(LammpsInterface::instance()->kBoltzmann());
|
||||
DENS_VEC nodalAtomicCapacity(nNodes_);
|
||||
restrict_volumetric_quantity(atomicCapacity,nodalAtomicCapacity);
|
||||
massMats[thisField].reset(nodalAtomicCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ATC_TransferThermal::finish()
|
||||
{
|
||||
// base class
|
||||
ATC_Transfer::finish();
|
||||
|
||||
// nothing specific to thermal
|
||||
}
|
||||
|
||||
bool ATC_TransferThermal::modify(int narg, char **arg)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
int argIndx = 0;
|
||||
|
||||
// check to see if input is a transfer class command
|
||||
// check derived class before base class
|
||||
if (strcmp(arg[argIndx],"transfer")==0) {
|
||||
argIndx++;
|
||||
|
||||
// pass-through to thermostat
|
||||
if (strcmp(arg[argIndx],"thermal")==0) {
|
||||
argIndx++;
|
||||
if (strcmp(arg[argIndx],"control")==0) {
|
||||
argIndx++;
|
||||
foundMatch = thermostat_.modify(narg-argIndx,&arg[argIndx]);
|
||||
}
|
||||
}
|
||||
|
||||
// switch for equilibrium filtering start
|
||||
/*! \page man_equilibrium_start fix_modify AtC transfer equilibrium_start
|
||||
\section syntax
|
||||
fix_modify AtC transfer equilibrium_start <on|off>
|
||||
|
||||
\section examples
|
||||
<TT> fix_modify atc transfer equilibrium_start on </TT> \n
|
||||
|
||||
\section description
|
||||
Starts filtered calculations assuming they start in equilibrium, i.e. perfect finite element force balance.
|
||||
|
||||
\section restrictions
|
||||
only needed before filtering is begun
|
||||
|
||||
\section related
|
||||
see \ref man_time_filter
|
||||
|
||||
\section default
|
||||
on
|
||||
*/
|
||||
else if (strcmp(arg[argIndx],"equilibrium_start")==0) {
|
||||
argIndx++;
|
||||
if (strcmp(arg[argIndx],"on")==0) {
|
||||
equilibriumStart_ = true;
|
||||
foundMatch = true;
|
||||
}
|
||||
else if (strcmp(arg[argIndx],"off")==0) {
|
||||
equilibriumStart_ = false;
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
// time integration scheme
|
||||
/*! \page man_time_integration fix_modify AtC transfer pmfc
|
||||
\section syntax
|
||||
fix_modify AtC transfer pmfc <on|off>
|
||||
|
||||
\section examples
|
||||
<TT> fix_modify atc transfer pmfc on </TT>
|
||||
|
||||
\section description
|
||||
Switches the poor man's fractional step algorithm on where the finite element data lags the exact atomic data by one time step for overlap nodes
|
||||
|
||||
\section restrictions
|
||||
\section related
|
||||
\section default
|
||||
off
|
||||
*/
|
||||
else if (strcmp(arg[argIndx],"pmfc")==0) {
|
||||
if (integrationType_!=TimeIntegrator::VERLET || timeFilterManager_.filter_dynamics())
|
||||
throw ATC_Error(0,"Can only use poor man's fractional step with Verlet integration without filtering");
|
||||
pmfcOn_ = !pmfcOn_;
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
// no match, call base class parser
|
||||
if (!foundMatch) {
|
||||
foundMatch = ATC_Transfer::modify(narg, arg);
|
||||
}
|
||||
|
||||
return foundMatch;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// pack_fields
|
||||
// bundle all allocated field matrices into a list
|
||||
// for output needs
|
||||
//--------------------------------------------------
|
||||
void ATC_TransferThermal::pack_thermal_fields(OUTPUT_LIST & data)
|
||||
{
|
||||
data["ddFieldTemp"] = & oldFieldTemp_;
|
||||
data["lambdaPowerFiltered"] = &(thermostat_.get_filtered_lambda_power());
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// write_restart_file
|
||||
// bundle matrices that need to be saved and call
|
||||
// fe_engine to write the file
|
||||
//--------------------------------------------------
|
||||
void ATC_TransferThermal::write_restart_data(string fileName, OUTPUT_LIST & data)
|
||||
{
|
||||
pack_thermal_fields(data);
|
||||
ATC_Transfer::write_restart_data(fileName,data);
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// write_restart_file
|
||||
// bundle matrices that need to be saved and call
|
||||
// fe_engine to write the file
|
||||
//--------------------------------------------------
|
||||
void ATC_TransferThermal::read_restart_data(string fileName, OUTPUT_LIST & data)
|
||||
{
|
||||
pack_thermal_fields(data);
|
||||
ATC_Transfer::read_restart_data(fileName,data);
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::reset_nlocal()
|
||||
{
|
||||
ATC_Transfer::reset_nlocal();
|
||||
thermostat_.reset_nlocal();
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::pre_init_integrate()
|
||||
{
|
||||
//ATC_Transfer::pre_init_integrate();
|
||||
double dt = lammpsInterface_->dt();
|
||||
double dtLambda = 0.5*dt;
|
||||
|
||||
if (pmfcOn_) {
|
||||
oldFieldTemp_ = fields_[TEMPERATURE];
|
||||
}
|
||||
|
||||
// Apply thermostat to atom velocities
|
||||
thermostat_.apply_pre_predictor(dtLambda,lammpsInterface_->ntimestep());
|
||||
|
||||
|
||||
// Predict nodal temperatures and time derivatives based on FE data
|
||||
// 4th order Gear
|
||||
// switch call based on filter
|
||||
if (timeFilterManager_.filter_dynamics())
|
||||
gear1_4_predict(fields_[TEMPERATURE],dot_fields_[TEMPERATURE],
|
||||
ddot_fields_[TEMPERATURE],dddot_fields_[TEMPERATURE],dt);
|
||||
else
|
||||
gear1_3_predict(fields_[TEMPERATURE],dot_fields_[TEMPERATURE],
|
||||
ddot_fields_[TEMPERATURE],dt);
|
||||
|
||||
extrinsicModelManager_.pre_init_integrate();
|
||||
|
||||
// fixed values, non-group bcs handled through FE
|
||||
set_fixed_nodes();
|
||||
|
||||
simTime_ += .5*dt;
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::post_init_integrate()
|
||||
{
|
||||
// Nothing to do here
|
||||
//ATC_Transfer::post_init_integrate();
|
||||
}
|
||||
|
||||
void ATC_TransferThermal::pre_final_integrate()
|
||||
{
|
||||
ATC_Transfer::pre_final_integrate();
|
||||
}
|
||||
|
||||
|
||||
void ATC_TransferThermal::post_final_integrate()
|
||||
{
|
||||
//ATC_Transfer::post_final_integrate();
|
||||
double dt = lammpsInterface_->dt();
|
||||
double dtLambda = dt*0.5;
|
||||
// predict thermostat contributions
|
||||
// compute sources based on predicted FE temperature
|
||||
prescribedDataMgr_->set_sources(simTime_+.5*dt,sources_);
|
||||
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||||
thermostat_.compute_boundary_flux(fields_);
|
||||
compute_atomic_sources(temperatureMask_,fields_,atomicSources_);
|
||||
thermostat_.apply_pre_corrector(dtLambda,lammpsInterface_->ntimestep());
|
||||
|
||||
// Determine FE contributions to d theta/dt
|
||||
// Compute atom-integrated rhs
|
||||
// parallel communication happens within FE_Engine
|
||||
compute_rhs_vector(temperatureMask_,fields_,rhs_,FE_DOMAIN);
|
||||
|
||||
// For flux matching, add 1/2 of "drag" power
|
||||
thermostat_.add_to_rhs(rhs_);
|
||||
|
||||
extrinsicModelManager_.post_final_integrate();
|
||||
// add in atomic FE contributions for verlet method
|
||||
if (integrationType_==TimeIntegrator::VERLET) {
|
||||
DENS_MAT atomicPower(nLocal_,1);
|
||||
compute_atomic_power(atomicPower,
|
||||
lammpsInterface_->vatom(),
|
||||
lammpsInterface_->fatom());
|
||||
DENS_MAT nodalAtomicPower(nNodes_,1);
|
||||
restrict_volumetric_quantity(atomicPower,nodalAtomicPower);
|
||||
nodalAtomicPower *= 2.;
|
||||
|
||||
if (timeFilterManager_.filter_variables())
|
||||
update_filter_implicit(fieldRateNdFiltered_[TEMPERATURE],nodalAtomicPower,dt);
|
||||
else
|
||||
fieldRateNdFiltered_[TEMPERATURE] = nodalAtomicPower;
|
||||
if (!timeFilterManager_.filter_variables() || timeFilterManager_.filter_dynamics())
|
||||
rhs_[TEMPERATURE] += fieldRateNdFiltered_[TEMPERATURE];
|
||||
else
|
||||
rhs_[TEMPERATURE] += nodalAtomicPower;
|
||||
}
|
||||
|
||||
// Finish updating temperature
|
||||
DENS_MAT R_theta(nNodes_,1);
|
||||
apply_inverse_mass_matrix(rhs_[TEMPERATURE],TEMPERATURE);
|
||||
R_theta = (rhs_[TEMPERATURE] - dot_fields_[TEMPERATURE])*dt;
|
||||
if (timeFilterManager_.filter_dynamics())
|
||||
gear1_4_correct(fields_[TEMPERATURE],dot_fields_[TEMPERATURE],
|
||||
ddot_fields_[TEMPERATURE],dddot_fields_[TEMPERATURE],
|
||||
R_theta,dt);
|
||||
else
|
||||
gear1_3_correct(fields_[TEMPERATURE],dot_fields_[TEMPERATURE],
|
||||
ddot_fields_[TEMPERATURE],R_theta,dt);
|
||||
|
||||
// only requirecd for poor man's fractional step
|
||||
if (pmfcOn_) {
|
||||
DENS_MAT atomicKineticEnergy(nLocal_,1);
|
||||
compute_atomic_kinetic_energy(atomicKineticEnergy,
|
||||
lammpsInterface_->vatom());
|
||||
DENS_MAT temperatureNd(nNodes_,1);
|
||||
project_md_volumetric_quantity(atomicKineticEnergy,
|
||||
temperatureNd,
|
||||
TEMPERATURE);
|
||||
temperatureNd *= 2.;
|
||||
dot_fields_[TEMPERATURE] = 1.0/dt * ( temperatureNd - oldFieldTemp_);
|
||||
fields_[TEMPERATURE] = temperatureNd;
|
||||
}
|
||||
|
||||
// fix nodes, non-group bcs applied through FE
|
||||
set_fixed_nodes();
|
||||
|
||||
// compute sources based on final FE updates
|
||||
prescribedDataMgr_->set_sources(simTime_+.5*dt,sources_);
|
||||
extrinsicModelManager_.set_sources(fields_,extrinsicSources_);
|
||||
thermostat_.compute_boundary_flux(fields_);
|
||||
compute_atomic_sources(temperatureMask_,fields_,atomicSources_);
|
||||
|
||||
// apply corrector phase of thermostat
|
||||
thermostat_.apply_post_corrector(dtLambda,lammpsInterface_->ntimestep());
|
||||
|
||||
// add in MD contributions to time derivative
|
||||
// update filtered temperature
|
||||
DENS_MAT atomicKineticEnergy(nLocal_,1);
|
||||
compute_atomic_kinetic_energy(atomicKineticEnergy,
|
||||
lammpsInterface_->vatom());
|
||||
DENS_MAT temperatureNd(nNodes_,1);
|
||||
project_md_volumetric_quantity(atomicKineticEnergy,temperatureNd,TEMPERATURE);
|
||||
temperatureNd *= 2.;
|
||||
if (!timeFilterManager_.filter_dynamics())
|
||||
fieldNdFiltered_[TEMPERATURE] = temperatureNd;
|
||||
else if (integrationType_==TimeIntegrator::VERLET)
|
||||
update_filter_implicit(fieldNdFiltered_[TEMPERATURE],temperatureNd,dt);
|
||||
|
||||
simTime_ += .5*dt;
|
||||
output();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// compute_vector
|
||||
//--------------------------------------------------------------------
|
||||
// this is for direct output to lammps thermo
|
||||
double ATC_TransferThermal::compute_vector(int n)
|
||||
{
|
||||
// output[1] = total coarse scale thermal energy
|
||||
// output[2] = average temperature
|
||||
|
||||
double mvv2e = lammpsInterface_->mvv2e(); // convert to lammps energy units
|
||||
|
||||
if (n == 0) {
|
||||
Array<FieldName> mask(1);
|
||||
FIELDS energy;
|
||||
mask(0) = TEMPERATURE;
|
||||
feEngine_->compute_energy(mask, // NOTE make this a base class function
|
||||
fields_,
|
||||
physicsModel_,
|
||||
elementToMaterialMap_,
|
||||
energy,
|
||||
&elementMask_);
|
||||
|
||||
double phononEnergy = mvv2e * energy[TEMPERATURE].col_sum();
|
||||
return phononEnergy;
|
||||
}
|
||||
else if (n == 1) {
|
||||
double aveT = fields_[TEMPERATURE].col_sum()/nNodes_;
|
||||
return aveT;
|
||||
}
|
||||
else if (n > 1) {
|
||||
double extrinsicValue = extrinsicModelManager_.compute_vector(n);
|
||||
return extrinsicValue;
|
||||
}
|
||||
|
||||
return 0.;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// output
|
||||
//--------------------------------------------------------------------
|
||||
void ATC_TransferThermal::output()
|
||||
{
|
||||
double dt = lammpsInterface_->dt();
|
||||
|
||||
double step = (double) lammpsInterface_->ntimestep();
|
||||
++stepCounter_;
|
||||
|
||||
if ((outputFrequency_ > 0)
|
||||
&& ((stepCounter_ ==1) || (stepCounter_ % outputFrequency_ == 0)) ) {
|
||||
|
||||
OUTPUT_LIST output_data;
|
||||
|
||||
// Add some outputs only on Proc 0
|
||||
if (lammpsInterface_->comm_rank() == 0) {
|
||||
// base class output
|
||||
ATC_Transfer::output();
|
||||
|
||||
// global data
|
||||
double T_mean = fields_[TEMPERATURE].col_sum(0)/nNodes_;
|
||||
feEngine_->add_global("temperature_mean", T_mean);
|
||||
double T_stddev = fields_[TEMPERATURE].col_stdev(0);
|
||||
feEngine_->add_global("temperature_std_dev", T_stddev);
|
||||
double Ta_mean = fieldNdFiltered_[TEMPERATURE].col_sum(0)/nNodes_;
|
||||
feEngine_->add_global("atomic_temperature_mean", Ta_mean);
|
||||
double Ta_stddev = fieldNdFiltered_[TEMPERATURE].col_stdev(0);
|
||||
feEngine_->add_global("atomic_temperature_std_dev", Ta_stddev);
|
||||
|
||||
// mesh data
|
||||
output_data["nodalAtomicTemperature"] = & fieldNdFiltered_[TEMPERATURE];
|
||||
output_data["dot_temperature"] = & dot_fields_[TEMPERATURE];
|
||||
output_data["ddot_temperature"] = & ddot_fields_[TEMPERATURE];
|
||||
output_data["nodalAtomicPower"] = & fieldRateNdFiltered_[TEMPERATURE];
|
||||
|
||||
// auxilliary data
|
||||
thermostat_.output(dt,output_data);
|
||||
extrinsicModelManager_.output(dt,output_data);
|
||||
}
|
||||
|
||||
|
||||
// Output fe data on proc 0
|
||||
if (lammpsInterface_->comm_rank() == 0) {
|
||||
feEngine_->write_data(simTime_, fields_, & output_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((outputFrequencyAtom_ > 0)
|
||||
&& ((stepCounter_ ==1) || (stepCounter_ % outputFrequencyAtom_ == 0)) )
|
||||
atomic_output();
|
||||
}
|
||||
|
||||
|
||||
void ATC_TransferThermal::set_ghost_atoms()
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
};
|
|
@ -1,96 +0,0 @@
|
|||
/** ATC_TransferThermal : a class for atom-continuum transfers &
|
||||
control involving heat transport */
|
||||
|
||||
#ifndef ATC_TRANSFER_THERMAL_H
|
||||
#define ATC_TRANSFER_THERMAL_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "ATC_Transfer.h"
|
||||
#include "Thermostat.h"
|
||||
#include "TimeIntegrator.h"
|
||||
|
||||
// Other headers
|
||||
#include <map>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
class ATC_TransferThermal : public ATC_Transfer {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ATC_TransferThermal(std::string groupName, std::string matParamFile,
|
||||
ExtrinsicModelType extrinsic = NO_MODEL);
|
||||
|
||||
// destructor
|
||||
~ATC_TransferThermal();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
/** post time integration */
|
||||
virtual void finish();
|
||||
|
||||
/** first time substep routines */
|
||||
virtual void pre_init_integrate();
|
||||
virtual void mid_init_integrate(){};
|
||||
virtual void post_init_integrate();
|
||||
|
||||
/** second time substep routine */
|
||||
virtual void pre_final_integrate();
|
||||
virtual void post_final_integrate();
|
||||
|
||||
/** compute vector for output */
|
||||
virtual double compute_vector(int n);
|
||||
|
||||
private:
|
||||
|
||||
/** sets the position/velocity of the ghost atoms */
|
||||
virtual void set_ghost_atoms();
|
||||
|
||||
/** resets any arrays associated with local atom count */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
/** compute the mass matrix components coming from MD integration */
|
||||
virtual void compute_md_mass_matrix(FieldName thisField,
|
||||
map<FieldName,DIAG_MAT> & massMats);
|
||||
|
||||
/** time integration flag and access method */
|
||||
TimeIntegrator::TimeIntegrationType integrationType_;
|
||||
virtual TimeIntegrator::TimeIntegrationType get_integration_type(){return integrationType_;};
|
||||
|
||||
/** fractional step auxilliary storage */
|
||||
DENS_MAT delTheta;
|
||||
DENS_MAT delThetaV;
|
||||
DENS_MAT dot_atomicTemp;
|
||||
DENS_MAT dot_atomicTempOld;
|
||||
DENS_MAT dot_dot_atomicTemp;
|
||||
DENS_MAT dot_dot_atomicTempOld;
|
||||
|
||||
/** physics specific filter initialization */
|
||||
void init_filter();
|
||||
|
||||
/** field mask for velocity integration */
|
||||
Array2D<bool> temperatureMask_;
|
||||
|
||||
void output();
|
||||
|
||||
/** thermostat manager */
|
||||
Thermostat thermostat_;
|
||||
|
||||
// Data for poor man's fractional step
|
||||
bool pmfcOn_;
|
||||
DENS_MAT oldFieldTemp_;
|
||||
|
||||
// Add in fields for restarting
|
||||
virtual void read_restart_data(string fileName_, OUTPUT_LIST & data);
|
||||
virtual void write_restart_data(string fileName_, OUTPUT_LIST & data);
|
||||
void pack_thermal_fields(OUTPUT_LIST & data);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,207 +0,0 @@
|
|||
#ifndef ATC_TYPEDEFS_H
|
||||
#define ATC_TYPEDEFS_H
|
||||
|
||||
#include <set>
|
||||
using std::pair;
|
||||
using std::set;
|
||||
|
||||
#include "Array.h"
|
||||
#include "Array2D.h"
|
||||
#include "XT_Function.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
namespace ATC
|
||||
{
|
||||
/** Material types */
|
||||
enum FieldName { // Intrinsic Fields
|
||||
TEMPERATURE=0,
|
||||
DISPLACEMENT,
|
||||
VELOCITY,
|
||||
MASS_DENSITY,
|
||||
CHARGE_DENSITY,
|
||||
ELECTRON_DENSITY, // Extrinsic Fields
|
||||
ELECTRON_VELOCITY,
|
||||
ELECTRON_TEMPERATURE,
|
||||
ELECTRIC_POTENTIAL,
|
||||
NUM_FIELDS
|
||||
};
|
||||
|
||||
/** solver types */
|
||||
enum SolverType { DIRECT=0, ITERATIVE};
|
||||
|
||||
/** physics types */
|
||||
enum PhysicsType
|
||||
{
|
||||
NO_PHYSICS=0, // for post-processing only
|
||||
THERMAL,
|
||||
ELASTIC,
|
||||
THERMO_ELASTIC,
|
||||
SPECIES
|
||||
};
|
||||
|
||||
/** rhs types */
|
||||
enum FluxType
|
||||
{
|
||||
FLUX = 0, // has a source weighted by gradient of shape function
|
||||
SOURCE, // has a source term weighted by the shape function
|
||||
PRESCRIBED_SOURCE, // has a prescribed source term
|
||||
EXTRINSIC_SOURCE, // has an extrinsic source term
|
||||
NUM_FLUX
|
||||
};
|
||||
|
||||
/** stiffness/ derivative of rhs types */
|
||||
enum StiffnessType
|
||||
{
|
||||
BB_STIFFNESS = 0,
|
||||
NN_STIFFNESS,
|
||||
BN_STIFFNESS,
|
||||
NB_STIFFNESS,
|
||||
NUM_STIFFNESS
|
||||
};
|
||||
|
||||
/** typedefs for N and B integrand functions */
|
||||
typedef DenseMatrix<double> FIELD;
|
||||
typedef vector<DenseMatrix<double> > GRAD_FIELD;
|
||||
typedef map<FieldName, DenseMatrix<double> > FIELDS;
|
||||
typedef map<FieldName, vector<DenseMatrix<double> > > GRAD_FIELDS;
|
||||
|
||||
/** typedefs for input/output */
|
||||
typedef map<string, Matrix<double>*> OUTPUT_LIST;
|
||||
|
||||
/** misc typedefs */
|
||||
typedef pair<int, int> PAIR;
|
||||
typedef map<FieldName, map<PAIR, Array<XT_Function*> > > SURFACE_SOURCE;
|
||||
typedef map<FieldName, Array2D<XT_Function *> > VOLUME_SOURCE;
|
||||
typedef vector<SparseMatrix<double> > GRAD_SHPFCN;
|
||||
|
||||
/** typedefs for FE_Mesh */
|
||||
typedef map<string, set<int > > NODE_SET_MAP;
|
||||
typedef map<string, set<int > > ELEMENT_SET_MAP;
|
||||
typedef map<string, set<PAIR> > FACE_SET_MAP;
|
||||
|
||||
/** string to index */
|
||||
static bool string_to_index(const string & dim, int & index, int & sgn)
|
||||
{
|
||||
char dir;
|
||||
if (dim.empty()) return false;
|
||||
sgn = (dim[0] == '-') ? -1 : 1;
|
||||
dir = dim[dim.size()-1]; // dir is last character
|
||||
if (dir == 'x') index = 0;
|
||||
else if (dir == 'y') index = 1;
|
||||
else if (dir == 'z') index = 2;
|
||||
else return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
/** string to index */
|
||||
static string index_to_string(const int &index)
|
||||
{
|
||||
if (index==0) return "x";
|
||||
else if (index==1) return "y";
|
||||
else if (index==2) return "z";
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
/** string to index */
|
||||
static bool string_to_index(const string &dim, int &index)
|
||||
{
|
||||
if (dim=="x")
|
||||
index = 0;
|
||||
else if (dim=="y")
|
||||
index = 1;
|
||||
else if (dim=="z")
|
||||
index = 2;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/** field name enum to string */
|
||||
static string field_to_string(const FieldName index)
|
||||
{
|
||||
switch (index) {
|
||||
case TEMPERATURE:
|
||||
return "temperature";
|
||||
case DISPLACEMENT:
|
||||
return "displacement";
|
||||
case VELOCITY:
|
||||
return "velocity";
|
||||
case MASS_DENSITY:
|
||||
return "mass_density";
|
||||
case CHARGE_DENSITY:
|
||||
return "charge_density";
|
||||
case ELECTRON_DENSITY:
|
||||
return "electron_density";
|
||||
case ELECTRON_VELOCITY:
|
||||
return "electron_velocity";
|
||||
case ELECTRON_TEMPERATURE:
|
||||
return "electron_temperature";
|
||||
case ELECTRIC_POTENTIAL:
|
||||
return "electric_potential";
|
||||
default:
|
||||
throw ATC_Error(0,"field not found in field_to_string");
|
||||
}
|
||||
};
|
||||
|
||||
/** string to field enum */
|
||||
static FieldName string_to_field(const string & name)
|
||||
{
|
||||
if (name=="temperature")
|
||||
return TEMPERATURE;
|
||||
else if (name=="displacement")
|
||||
return DISPLACEMENT;
|
||||
else if (name=="velocity")
|
||||
return VELOCITY;
|
||||
else if (name=="mass_density")
|
||||
return MASS_DENSITY;
|
||||
else if (name=="charge_density")
|
||||
return CHARGE_DENSITY;
|
||||
else if (name=="electron_density")
|
||||
return ELECTRON_DENSITY;
|
||||
else if (name=="electron_velocity")
|
||||
return ELECTRON_VELOCITY;
|
||||
else if (name=="electron_temperature")
|
||||
return ELECTRON_TEMPERATURE;
|
||||
else if (name=="electric_potential")
|
||||
return ELECTRIC_POTENTIAL;
|
||||
else
|
||||
throw ATC_Error(0,name + " is not a valid field");
|
||||
};
|
||||
|
||||
static bool is_intrinsic(const FieldName & field_enum)
|
||||
{
|
||||
if (field_enum==TEMPERATURE
|
||||
|| field_enum==DISPLACEMENT
|
||||
|| field_enum==VELOCITY
|
||||
|| field_enum==MASS_DENSITY
|
||||
|| field_enum==CHARGE_DENSITY) return true;
|
||||
else return false;
|
||||
};
|
||||
|
||||
|
||||
static void print_mask(const Array2D<bool> & rhsMask)
|
||||
{
|
||||
for (int i = 0; i < NUM_FIELDS; i++) {
|
||||
FieldName field = (FieldName) i;
|
||||
string name = field_to_string(field);
|
||||
if (rhsMask(field,FLUX)
|
||||
|| rhsMask(field,SOURCE)
|
||||
|| rhsMask(field,PRESCRIBED_SOURCE)
|
||||
|| rhsMask(field,EXTRINSIC_SOURCE)) {
|
||||
cout << "RHS_MASK: " << name;
|
||||
if (rhsMask(field,FLUX)) cout << " flux";
|
||||
if (rhsMask(field,SOURCE)) cout << " source";
|
||||
if (rhsMask(field,PRESCRIBED_SOURCE)) cout << " prescribed_src";
|
||||
if (rhsMask(field,EXTRINSIC_SOURCE)) cout << " extrinsic_src";
|
||||
cout << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
170
lib/atc/Array.h
170
lib/atc/Array.h
|
@ -1,170 +0,0 @@
|
|||
#ifndef ARRAY_H
|
||||
#define ARRAY_H
|
||||
|
||||
//#include<stdlib.h>
|
||||
//#include<stdio.h>
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<cstdio>
|
||||
|
||||
template<typename T>
|
||||
class Array {
|
||||
public:
|
||||
Array();
|
||||
Array(int len);
|
||||
Array(const Array<T>& A);
|
||||
~Array();
|
||||
|
||||
// Resize and reinitialize the array
|
||||
void reset(int len);
|
||||
// Access method to get the element i:
|
||||
T& operator() (int i);
|
||||
// Access method to get the element i:
|
||||
const T& operator() (int i) const;
|
||||
// Assignment
|
||||
Array<T>& operator= (const Array<T> &other);
|
||||
Array<T>& operator= (const T &value);
|
||||
// Get length of array
|
||||
int get_length() const;
|
||||
int size() const;
|
||||
// Do I have this element?
|
||||
bool has_member(T val) const;
|
||||
// Return pointer to internal data
|
||||
const T* get_data() const;
|
||||
T* get_ptr() const;
|
||||
// print
|
||||
void print(std::string name = "") const;
|
||||
// Dump templated type to disk; operation not safe for all types
|
||||
void write_restart(FILE *f) const;
|
||||
|
||||
private:
|
||||
int len_;
|
||||
T *data_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Array<T>::Array(void) {
|
||||
len_ = 0;
|
||||
data_ = NULL;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array<T>::Array(int len) {
|
||||
len_ = len;
|
||||
data_ = new T[len_];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array<T>::Array(const Array<T>& A) {
|
||||
len_ = A.len_;
|
||||
if (A.data_==NULL)
|
||||
data_ = NULL;
|
||||
else {
|
||||
data_ = new T[len_];
|
||||
for(int i=0;i<len_;i++)
|
||||
data_[i] = A.data_[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array<T>::reset(int len) {
|
||||
if (len_ == len) { // no size change; don't realloc memory
|
||||
return;
|
||||
}
|
||||
else { // size change, realloc memory
|
||||
len_ = len;
|
||||
if (data_ != NULL)
|
||||
delete[] data_;
|
||||
if (len_ > 0)
|
||||
data_ = new T[len_];
|
||||
else {
|
||||
data_ = NULL;
|
||||
len_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& Array<T>::operator() (int i) {
|
||||
// Array bounds checking
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array<T>& Array<T>::operator= (const Array<T> &other) {
|
||||
if (data_ == NULL) { // initialize my internal storage to match LHS
|
||||
len_ = other.len_;
|
||||
if (other.data_==NULL)
|
||||
data_ = NULL;
|
||||
else
|
||||
data_ = new T[len_];
|
||||
}
|
||||
for(int i=0;i<len_;i++)
|
||||
data_[i] = other.data_[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array<T>& Array<T>::operator= (const T &value) {
|
||||
for(int i=0;i<len_;i++)
|
||||
data_[i] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& Array<T>::operator() (int i) const {
|
||||
// Array bounds checking
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Array<T>::get_length(void) const {
|
||||
return len_;
|
||||
}
|
||||
template<typename T>
|
||||
int Array<T>::size(void) const {
|
||||
return len_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Array<T>::has_member(T val) const {
|
||||
int i;
|
||||
bool retval = false;
|
||||
for(i=0;i<len_;i++)
|
||||
if (val == data_[i])
|
||||
retval = true;
|
||||
return(retval);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array<T>::write_restart(FILE *f) const {
|
||||
fwrite(&len_,sizeof(int),1,f);
|
||||
if (len_ > 0)
|
||||
fwrite(data_,sizeof(T),len_,f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* Array<T>::get_data() const {
|
||||
return data_;
|
||||
}
|
||||
template<typename T>
|
||||
T* Array<T>::get_ptr() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array<T>::~Array() {
|
||||
if (data_ != NULL)
|
||||
delete[] data_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array<T>::print(std::string name) const {
|
||||
std::cout << "------- Begin "<<name<<" -----------------\n";
|
||||
if (data_ != NULL) {
|
||||
for(int i=0;i<len_;i++) std::cout << data_[i] << " ";
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << "\n------- End "<<name<<" -------------------\n";
|
||||
}
|
||||
#endif // Array.h
|
|
@ -1,172 +0,0 @@
|
|||
#ifndef ARRAY2D_H
|
||||
#define ARRAY2D_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
template<typename T>
|
||||
class Array2D {
|
||||
public:
|
||||
Array2D();
|
||||
Array2D(int nrows, int ncols);
|
||||
Array2D(const Array2D<T>& A); // copy constructor
|
||||
~Array2D();
|
||||
|
||||
// Resize and reinitalize matrix
|
||||
void reset(int nrows, int ncols);
|
||||
// Access method to get the (i,j) element:
|
||||
T& operator() (int i, int j);
|
||||
// Access method to get the (i,j) element:
|
||||
const T& operator() (int i, int j) const;
|
||||
// Copy operator
|
||||
Array2D<T>& operator= (const Array2D<T>& other);
|
||||
// assignment operator
|
||||
Array2D<T>& operator= (const T other);
|
||||
// Get size of Array2D
|
||||
int nRows() const;
|
||||
int nCols() const;
|
||||
// Do I have this element?
|
||||
bool has_member(T val) const;
|
||||
// print
|
||||
void print(std::string name ="") const;
|
||||
// Dump templated type to disk; operation not safe for all types
|
||||
void write_restart(FILE *f) const;
|
||||
|
||||
private:
|
||||
int nrows_, ncols_;
|
||||
T *data_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>::Array2D() {
|
||||
nrows_ = 0;
|
||||
ncols_ = 0;
|
||||
data_ = NULL;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>::Array2D(int nrows, int ncols) {
|
||||
nrows_ = nrows;
|
||||
ncols_ = ncols;
|
||||
data_ = new T[nrows_ * ncols_];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>::Array2D(const Array2D<T>& A) {
|
||||
nrows_ = A.nrows_;
|
||||
ncols_ = A.ncols_;
|
||||
if (A.data_==NULL)
|
||||
data_ = NULL;
|
||||
else {
|
||||
data_ = new T[nrows_ * ncols_];
|
||||
for(int i=0;i<nrows_*ncols_;i++)
|
||||
data_[i] = A.data_[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array2D<T>::reset(int nrows, int ncols) {
|
||||
if (nrows_ == nrows && ncols_ == ncols) { // no size change; don't realloc memory
|
||||
return;
|
||||
}
|
||||
else { // size changed; realloc memory
|
||||
nrows_ = nrows;
|
||||
ncols_ = ncols;
|
||||
if (data_ != NULL)
|
||||
delete [] data_;
|
||||
if (ncols_ > 0 && nrows_ > 0)
|
||||
data_ = new T[nrows_ * ncols_];
|
||||
else {
|
||||
data_ = NULL;
|
||||
nrows_ = 0;
|
||||
ncols_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& Array2D<T>::operator() (int row, int col) {
|
||||
// Array bounds checking
|
||||
return data_[col*nrows_ + row];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& Array2D<T>::operator() (int row, int col) const {
|
||||
// Array bounds checking
|
||||
return data_[col*nrows_ + row];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>& Array2D<T>::operator= (const Array2D<T>& other) {
|
||||
if (data_ == NULL) { // initialize my internal storage to match LHS
|
||||
nrows_ = other.nrows_;
|
||||
ncols_ = other.ncols_;
|
||||
if (other.data_==NULL)
|
||||
data_ = NULL;
|
||||
else
|
||||
data_ = new T[nrows_ * ncols_];
|
||||
}
|
||||
for(int i=0;i<nrows_*ncols_;i++)
|
||||
data_[i] = other.data_[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>& Array2D<T>::operator= (const T other) {
|
||||
for(int i=0;i<nrows_*ncols_;i++)
|
||||
data_[i] = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Array2D<T>::nRows() const {
|
||||
return nrows_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Array2D<T>::nCols() const {
|
||||
return ncols_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Array2D<T>::has_member(T val) const {
|
||||
int i;
|
||||
bool retval = false;
|
||||
for(i=0;i<nrows_*ncols_;i++)
|
||||
if (val == data_[i])
|
||||
retval = true;
|
||||
return(retval);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array2D<T>::write_restart(FILE *f) const {
|
||||
fwrite(&nrows_,sizeof(int),1,f);
|
||||
fwrite(&ncols_,sizeof(int),1,f);
|
||||
if (nrows_*ncols_ > 0)
|
||||
fwrite(data_,sizeof(T),nrows_*ncols_,f);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Array2D<T>::~Array2D() {
|
||||
if (data_ != NULL)
|
||||
delete[] data_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Array2D<T>::print(std::string name) const {
|
||||
std::cout << "------- Begin "<<name<<" -----------------\n";
|
||||
if (data_ != NULL) {
|
||||
for(int col=0;col<ncols_;col++) {
|
||||
for(int row=0;row<nrows_;row++) {
|
||||
std::cout << data_[col*nrows_ + row] << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "\n------- End "<<name<<" -------------------\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // Array2D.h
|
|
@ -1,419 +0,0 @@
|
|||
// ATC_Transfer Headers
|
||||
#include "AtomicRegulator.h"
|
||||
#include "CG.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "PrescribedDataManager.h"
|
||||
#include "TimeIntegrator.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class AtomicRegulator
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
AtomicRegulator::AtomicRegulator(ATC_Transfer * atcTransfer) :
|
||||
atcTransfer_(atcTransfer),
|
||||
howOften_(1),
|
||||
timeFilter_(NULL),
|
||||
regulatorMethod_(NULL),
|
||||
boundaryIntegrationType_(ATC_Transfer::NO_QUADRATURE),
|
||||
nNodes_(0),
|
||||
nsd_(0),
|
||||
nLocal_(0),
|
||||
needReset_(true),
|
||||
resetData_(true)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
AtomicRegulator::~AtomicRegulator()
|
||||
{
|
||||
if (timeFilter_)
|
||||
delete timeFilter_;
|
||||
destroy();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// destroy:
|
||||
// deallocates all memory
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::destroy()
|
||||
{
|
||||
if (regulatorMethod_)
|
||||
delete regulatorMethod_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// modify:
|
||||
// parses and adjusts controller state based on
|
||||
// user input, in the style of LAMMPS user input
|
||||
//--------------------------------------------------------
|
||||
bool AtomicRegulator::modify(int narg, char **arg)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
|
||||
return foundMatch;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// reset_nlocal:
|
||||
// resizes lambda force if necessary
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::reset_nlocal()
|
||||
{
|
||||
nLocal_ = atcTransfer_->get_nlocal();
|
||||
if (nLocal_ > 0)
|
||||
lambdaForce_.reset(nLocal_,nsd_);
|
||||
if (regulatorMethod_)
|
||||
regulatorMethod_->reset_nlocal();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// reset_data:
|
||||
// sets up storage for all data structures
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::reset_data()
|
||||
{
|
||||
nNodes_ = atcTransfer_->get_nNodes();
|
||||
nsd_ = atcTransfer_->get_nsd();
|
||||
|
||||
if (timeFilter_)
|
||||
delete timeFilter_;
|
||||
timeFilter_ = NULL;
|
||||
|
||||
resetData_ = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// reset_method:
|
||||
// sets up methods, if necessary
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::reset_method()
|
||||
{
|
||||
// set up defaults for anything that didn't get set
|
||||
if (!regulatorMethod_)
|
||||
regulatorMethod_ = new RegulatorMethod(this);
|
||||
if (!timeFilter_)
|
||||
timeFilter_ = (atcTransfer_->get_time_filter_manager())->construct();
|
||||
|
||||
needReset_ = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize:
|
||||
// sets up methods before a run
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::initialize()
|
||||
{
|
||||
// make sure consistent boundary integration is being used
|
||||
atcTransfer_->set_boundary_integration_type(boundaryIntegrationType_);
|
||||
|
||||
// reset data related to local atom count
|
||||
reset_nlocal();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// output:
|
||||
// pass through to appropriate output methods
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::output(double dt, OUTPUT_LIST & outputData) const
|
||||
{
|
||||
regulatorMethod_->output(dt,outputData);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// apply_pre_predictor:
|
||||
// applies the controller in the pre-predictor
|
||||
// phase of the time integrator
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::apply_pre_predictor(double dt, int timeStep)
|
||||
{
|
||||
if (timeStep % howOften_==0) // apply full integration scheme, including filter
|
||||
regulatorMethod_->apply_pre_predictor(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// apply_mid_predictor:
|
||||
// applies the controller in the mid-predictor
|
||||
// phase of the time integrator
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::apply_mid_predictor(double dt, int timeStep)
|
||||
{
|
||||
if (timeStep % howOften_==0) // apply full integration scheme, including filter
|
||||
regulatorMethod_->apply_mid_predictor(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// apply_post_predictor:
|
||||
// applies the controller in the post-predictor
|
||||
// phase of the time integrator
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::apply_post_predictor(double dt, int timeStep)
|
||||
{
|
||||
if (timeStep % howOften_==0) // apply full integration scheme, including filter
|
||||
regulatorMethod_->apply_post_predictor(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// apply_pre_corrector:
|
||||
// applies the controller in the pre-corrector phase
|
||||
// of the time integrator
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::apply_pre_corrector(double dt, int timeStep)
|
||||
{
|
||||
if (timeStep % howOften_==0) // apply full integration scheme, including filter
|
||||
regulatorMethod_->apply_pre_corrector(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// apply_post_corrector:
|
||||
// applies the controller in the post-corrector phase
|
||||
// of the time integrator
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::apply_post_corrector(double dt, int timeStep)
|
||||
{
|
||||
if (timeStep % howOften_==0) // apply full integration scheme, including filter
|
||||
regulatorMethod_->apply_post_corrector(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// compute_boundary_flux:
|
||||
// computes the boundary flux to be consistent with
|
||||
// the controller
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::compute_boundary_flux(FIELDS & fields)
|
||||
{
|
||||
regulatorMethod_->compute_boundary_flux(fields);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// add_to_rhs:
|
||||
// adds any controller contributions to the FE rhs
|
||||
//--------------------------------------------------------
|
||||
void AtomicRegulator::add_to_rhs(FIELDS & rhs)
|
||||
{
|
||||
regulatorMethod_->add_to_rhs(rhs);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class RegulatorMethod
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
RegulatorMethod::RegulatorMethod(AtomicRegulator * atomicRegulator) :
|
||||
atomicRegulator_(atomicRegulator),
|
||||
atcTransfer_(atomicRegulator->get_atc_transfer()),
|
||||
fieldMask_(NUM_FIELDS,NUM_FLUX),
|
||||
boundaryFlux_(atcTransfer_->get_boundary_fluxes()),
|
||||
nNodes_(atomicRegulator_->get_nNodes())
|
||||
{
|
||||
fieldMask_ = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// compute_boundary_flux
|
||||
// default computation of boundary flux based on
|
||||
// finite
|
||||
//--------------------------------------------------------
|
||||
void RegulatorMethod::compute_boundary_flux(FIELDS & fields)
|
||||
{
|
||||
atcTransfer_->compute_boundary_flux(fieldMask_,
|
||||
fields,
|
||||
boundaryFlux_);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class RegulatorShapeFunction
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
RegulatorShapeFunction::RegulatorShapeFunction(AtomicRegulator * atomicRegulator) :
|
||||
RegulatorMethod(atomicRegulator),
|
||||
maxIterations_(50),
|
||||
tolerance_(1.e-10),
|
||||
nNodeOverlap_(atcTransfer_->get_nNode_overlap()),
|
||||
nsd_(atomicRegulator_->get_nsd()),
|
||||
lambda_(atomicRegulator_->get_lambda()),
|
||||
shapeFunctionMatrix_(atcTransfer_->get_nhat_overlap()),
|
||||
glcMatrixTemplate_(atcTransfer_->get_m_t_template()),
|
||||
shapeFunctionGhost_(atcTransfer_->get_shape_function_ghost_overlap()),
|
||||
internalToAtom_(atcTransfer_->get_internal_to_atom_map()),
|
||||
internalToOverlapMap_(atcTransfer_->get_atom_to_overlap_map()),
|
||||
ghostToAtom_(atcTransfer_->get_ghost_to_atom_map()),
|
||||
nLocal_(0),
|
||||
nLocalLambda_(0),
|
||||
nLocalGhost_(0)
|
||||
{
|
||||
if (atcTransfer_->use_lumped_lambda_solve())
|
||||
matrixSolver_ = new LambdaMatrixSolverLumped(glcMatrixTemplate_,
|
||||
shapeFunctionMatrix_,
|
||||
maxIterations_,
|
||||
tolerance_);
|
||||
else
|
||||
matrixSolver_ = new LambdaMatrixSolverCg(glcMatrixTemplate_,
|
||||
shapeFunctionMatrix_,
|
||||
maxIterations_,
|
||||
tolerance_);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
RegulatorShapeFunction::~RegulatorShapeFunction()
|
||||
{
|
||||
if (matrixSolver_)
|
||||
delete matrixSolver_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// solve_for_lambda
|
||||
// solves matrix equation for lambda using given rhs
|
||||
//--------------------------------------------------------
|
||||
void RegulatorShapeFunction::solve_for_lambda(const DENS_MAT & rhs)
|
||||
{
|
||||
// set up weighting matrix
|
||||
DIAG_MAT weights;
|
||||
if (nLocalLambda_>0)
|
||||
set_weights(weights);
|
||||
|
||||
// solve on overlap nodes
|
||||
DENS_MAT rhsOverlap(nNodeOverlap_,rhs.nCols());
|
||||
atcTransfer_->map_unique_to_overlap(rhs, rhsOverlap);
|
||||
DENS_MAT lambdaOverlap(nNodeOverlap_,lambda_.nCols());
|
||||
|
||||
for (int i = 0; i < rhs.nCols(); i++) {
|
||||
CLON_VEC tempRHS(rhsOverlap,CLONE_COL,i);
|
||||
CLON_VEC tempLambda(lambdaOverlap,CLONE_COL,i);
|
||||
matrixSolver_->execute(tempRHS,tempLambda,weights,atcTransfer_);
|
||||
}
|
||||
|
||||
// map solution back to all nodes
|
||||
atcTransfer_->map_overlap_to_unique(lambdaOverlap,lambda_);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// reset_nlocal:
|
||||
// resets data dependent on local atom count
|
||||
//--------------------------------------------------------
|
||||
void RegulatorShapeFunction::reset_nlocal()
|
||||
{
|
||||
RegulatorMethod::reset_nlocal();
|
||||
nLocal_ = atomicRegulator_->get_nLocal();
|
||||
nLocalLambda_ = atcTransfer_->get_nlocal_lambda();
|
||||
nLocalGhost_ = atcTransfer_->get_nlocal_ghost();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolver
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab references to necessary data
|
||||
//--------------------------------------------------------
|
||||
LambdaMatrixSolver::LambdaMatrixSolver(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance) :
|
||||
matrixTemplate_(matrixTemplate),
|
||||
shapeFunctionMatrix_(shapeFunctionMatrix),
|
||||
maxIterations_(maxIterations),
|
||||
tolerance_(tolerance)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolverLumped
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab references to necessary data
|
||||
//--------------------------------------------------------
|
||||
LambdaMatrixSolverLumped::LambdaMatrixSolverLumped(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance) :
|
||||
LambdaMatrixSolver(matrixTemplate,shapeFunctionMatrix,maxIterations,tolerance)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void LambdaMatrixSolverLumped::execute(VECTOR & rhs, VECTOR & lambda, DIAG_MAT & weights, ATC_Transfer * atcTransfer)
|
||||
{
|
||||
// form matrix : sum_a N_Ia * W_a * N_Ja
|
||||
SPAR_MAT myMatrixLocal(matrixTemplate_);
|
||||
if (weights.nRows()>0)
|
||||
myMatrixLocal.WeightedLeastSquares(shapeFunctionMatrix_,weights);
|
||||
|
||||
// swap contributions
|
||||
SPAR_MAT myMatrix(matrixTemplate_);
|
||||
LammpsInterface::instance()->allsum(myMatrixLocal.get_ptr(),
|
||||
myMatrix.get_ptr(), myMatrix.size());
|
||||
|
||||
DIAG_MAT lumpedMatrix(myMatrix.nRows(),myMatrix.nCols());
|
||||
for (int i = 0; i < myMatrix.nRows(); i++)
|
||||
for (int j = 0; j < myMatrix.nCols(); j++)
|
||||
lumpedMatrix(i,i) += myMatrix(i,j);
|
||||
|
||||
// solve lumped equation
|
||||
for (int i = 0; i < rhs.size(); i++)
|
||||
lambda(i) = rhs(i)/lumpedMatrix(i,i);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolverCg
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab references to necessary data
|
||||
//--------------------------------------------------------
|
||||
LambdaMatrixSolverCg::LambdaMatrixSolverCg(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance) :
|
||||
LambdaMatrixSolver(matrixTemplate,shapeFunctionMatrix,maxIterations,tolerance)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void LambdaMatrixSolverCg::execute(VECTOR & rhs, VECTOR & lambda, DIAG_MAT & weights, ATC_Transfer * atcTransfer)
|
||||
{
|
||||
// form matrix : sum_a N_Ia * W_a * N_Ja
|
||||
SPAR_MAT myMatrixLocal(matrixTemplate_);
|
||||
if (weights.nRows()>0)
|
||||
myMatrixLocal.WeightedLeastSquares(shapeFunctionMatrix_,weights);
|
||||
|
||||
// swap contributions
|
||||
SPAR_MAT myMatrix(matrixTemplate_);
|
||||
LammpsInterface::instance()->allsum(myMatrixLocal.get_ptr(),
|
||||
myMatrix.get_ptr(), myMatrix.size());
|
||||
|
||||
|
||||
DIAG_MAT preConditioner = myMatrix.get_diag();
|
||||
int myMaxIt = 2*myMatrix.nRows(); // note could also use the fixed parameter
|
||||
double myTol = tolerance_;
|
||||
|
||||
int convergence = CG(myMatrix, lambda, rhs, preConditioner, myMaxIt, myTol);
|
||||
|
||||
// error if didn't converge
|
||||
if (convergence>0)
|
||||
throw ATC_Error(0,"CG solver did not converge in LambdaMatrixSolverCg::execute()");
|
||||
}
|
||||
|
||||
};
|
|
@ -1,394 +0,0 @@
|
|||
/** Atomic Regulator : a base class class for atom-continuum control */
|
||||
|
||||
#ifndef ATOMICREGULATOR_H
|
||||
#define ATOMICREGULATOR_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "ATC_Transfer.h"
|
||||
|
||||
// other headers
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class TimeFilter;
|
||||
class RegulatorMethod;
|
||||
class LambdaMatrixSolver;
|
||||
|
||||
/**
|
||||
* @class AtomicRegulator
|
||||
* @brief Base class for atom-continuum control
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class AtomicRegulator
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class AtomicRegulator {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
AtomicRegulator(ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
~AtomicRegulator();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
/** add output information */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData) const;
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
// application steps
|
||||
/** apply the thermostat in the pre-predictor phase */
|
||||
virtual void apply_pre_predictor(double dt, int timeStep);
|
||||
/** apply the thermostat in the mid-predictor phase */
|
||||
virtual void apply_mid_predictor(double dt, int timeStep);
|
||||
/** apply the thermostat in the post-predictor phase */
|
||||
virtual void apply_post_predictor(double dt, int timeStep);
|
||||
/** apply the thermostat in the pre-correction phase */
|
||||
virtual void apply_pre_corrector(double dt, int timeStep);
|
||||
/** apply the thermostat in the post-correction phase */
|
||||
virtual void apply_post_corrector(double dt, int timeStep);
|
||||
|
||||
// coupling to FE state
|
||||
/** compute the thermal boundary flux, must be consistent with thermostat */
|
||||
virtual void compute_boundary_flux(FIELDS & fields);
|
||||
/** add contributions (if any) to the finite element right-hand side */
|
||||
virtual void add_to_rhs(FIELDS & rhs);
|
||||
|
||||
// data access, intended for method objects
|
||||
/** return value of lambda */
|
||||
DENS_MAT & get_lambda() {return lambda_;};
|
||||
/** return the atomic force defined by lambda */
|
||||
DENS_MAT & get_lambda_force() {return lambdaForce_;};
|
||||
/** access for ATC transfer */
|
||||
ATC_Transfer * get_atc_transfer() {return atcTransfer_;};
|
||||
/** access for time filter */
|
||||
TimeFilter * get_time_filter() {return timeFilter_;};
|
||||
/** access for number of nodes */
|
||||
int get_nNodes() {return nNodes_;};
|
||||
/** access for number of spatial dimensions */
|
||||
int get_nsd() {return nsd_;};
|
||||
/** access for number of local atoms */
|
||||
int get_nLocal() {return nLocal_;};
|
||||
/** access for boundary integration methods */
|
||||
ATC_Transfer::BoundaryIntegrationType get_boundary_integration_type()
|
||||
{return boundaryIntegrationType_;};
|
||||
/** access for boundary face sets */
|
||||
const set< pair<int,int> > * get_face_sets()
|
||||
{ return boundaryFaceSet_;};
|
||||
|
||||
protected:
|
||||
|
||||
void destroy();
|
||||
|
||||
/** point to atc_transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** how often in number of time steps thermostat is applied */
|
||||
int howOften_;
|
||||
|
||||
// reset/reinitialize flags
|
||||
/** flag to see if data requires a reset */
|
||||
bool resetData_;
|
||||
/** flag to reset data */
|
||||
bool needReset_;
|
||||
/** resets data structures */
|
||||
void reset_data();
|
||||
/** reinitialize method */
|
||||
void reset_method();
|
||||
|
||||
// regulator data
|
||||
/** control parameter */
|
||||
DENS_MAT lambda_;
|
||||
/** lambda force computed by controller */
|
||||
DENS_MAT lambdaForce_;
|
||||
|
||||
/** number of nodes */
|
||||
int nNodes_;
|
||||
/** number of spatial dimensions */
|
||||
int nsd_;
|
||||
/** number of local atoms */
|
||||
int nLocal_;
|
||||
|
||||
// method pointers
|
||||
/** time filtering object */
|
||||
TimeFilter * timeFilter_;
|
||||
/** sets up and solves the thermostat equations */
|
||||
RegulatorMethod * regulatorMethod_;
|
||||
|
||||
// boundary flux information
|
||||
ATC_Transfer::BoundaryIntegrationType boundaryIntegrationType_;
|
||||
const set< pair<int,int> > * boundaryFaceSet_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
AtomicRegulator();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class RegulatorMethod
|
||||
* @brief Base class for implementation of control algorithms
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class RegulatorMethod
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class RegulatorMethod {
|
||||
|
||||
public:
|
||||
|
||||
RegulatorMethod(AtomicRegulator * atomicRegulator);
|
||||
|
||||
~RegulatorMethod(){};
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal(){};
|
||||
|
||||
/** applies thermostat to atoms in the pre-predictor phase */
|
||||
virtual void apply_pre_predictor(double dt){};
|
||||
|
||||
/** applies thermostat to atoms in the mid-predictor phase */
|
||||
virtual void apply_mid_predictor(double dt){};
|
||||
|
||||
/** applies thermostat to atoms in the post-predictor phase */
|
||||
virtual void apply_post_predictor(double dt){};
|
||||
|
||||
/** applies thermostat to atoms in the pre-corrector phase */
|
||||
virtual void apply_pre_corrector(double dt){};
|
||||
|
||||
/** applies thermostat to atoms in the post-corrector phase */
|
||||
virtual void apply_post_corrector(double dt){};
|
||||
|
||||
/** compute boundary flux, requires thermostat input since it is part of the coupling scheme */
|
||||
virtual void compute_boundary_flux(FIELDS & fields);
|
||||
|
||||
/** add contributions (if any) to the finite element right-hand side */
|
||||
virtual void add_to_rhs(FIELDS & rhs){};
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData){};
|
||||
|
||||
protected:
|
||||
|
||||
/** pointer to ATC_transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** pointer to atomic regulator object for data */
|
||||
AtomicRegulator * atomicRegulator_;
|
||||
|
||||
/** boundary flux */
|
||||
FIELDS & boundaryFlux_;
|
||||
|
||||
/** field mask for specifying boundary flux */
|
||||
Array2D<bool> fieldMask_;
|
||||
|
||||
/** number of nodes */
|
||||
int nNodes_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
RegulatorMethod();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class RegulatorShapeFunction
|
||||
* @brief Base class for implementation of regulation algorithms using the shape function matrices
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class RegulatorShapeFunction
|
||||
// base class for all regulators of general form
|
||||
// of N^T w N lambda = rhs
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class RegulatorShapeFunction : public RegulatorMethod {
|
||||
|
||||
public:
|
||||
|
||||
RegulatorShapeFunction(AtomicRegulator * atomicRegulator);
|
||||
|
||||
~RegulatorShapeFunction();
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** solve matrix equation */
|
||||
void solve_for_lambda(const DENS_MAT & rhs);
|
||||
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights){};
|
||||
|
||||
// member data
|
||||
/** lambda coupling parameter */
|
||||
DENS_MAT & lambda_;
|
||||
|
||||
/** shape function matrix for use in GLC solve */
|
||||
SPAR_MAT & shapeFunctionMatrix_;
|
||||
|
||||
/** pre-templated sparsity pattern for N^T * T * N */
|
||||
SPAR_MAT & glcMatrixTemplate_;
|
||||
|
||||
/** reference to ATC unity shape function on ghost atoms */
|
||||
SPAR_MAT & shapeFunctionGhost_;
|
||||
|
||||
/** maximum number of iterations used in solving for lambda */
|
||||
int maxIterations_;
|
||||
|
||||
/** tolerance used in solving for lambda */
|
||||
double tolerance_;
|
||||
|
||||
/** matrix solver object */
|
||||
LambdaMatrixSolver * matrixSolver_;
|
||||
|
||||
/** maps internal atom ids to LAMMPS atom ids */
|
||||
Array<int> & internalToAtom_;
|
||||
|
||||
/** maps internal atoms to overlap atoms */
|
||||
SPAR_MAT & internalToOverlapMap_;
|
||||
|
||||
/** maps ghost atom and LAMMPS atom ids */
|
||||
Array<int> & ghostToAtom_;
|
||||
|
||||
/** number of overlapping nodes */
|
||||
int nNodeOverlap_;
|
||||
|
||||
/** number of spatial dimensions */
|
||||
int nsd_;
|
||||
|
||||
/** number of ATC internal atoms on this processor */
|
||||
int nLocal_;
|
||||
|
||||
/** number of thermostatted ATC internal atoms on this processor */
|
||||
int nLocalLambda_;
|
||||
|
||||
/** number of ATC ghost atoms on this processor */
|
||||
int nLocalGhost_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
RegulatorShapeFunction();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolver
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class LambdaMatrixSolver {
|
||||
|
||||
public:
|
||||
|
||||
LambdaMatrixSolver(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance);
|
||||
|
||||
~LambdaMatrixSolver(){};
|
||||
|
||||
/** execute the solver */
|
||||
virtual void execute(VECTOR & rhs, VECTOR & lambda, DIAG_MAT & weights,ATC_Transfer * atcTransfer_=NULL) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** sparse template for the matrix */
|
||||
SPAR_MAT & matrixTemplate_;
|
||||
|
||||
/** non-symmetric part of the matrix */
|
||||
SPAR_MAT & shapeFunctionMatrix_;
|
||||
|
||||
/** maximum number of iterations */
|
||||
int maxIterations_;
|
||||
|
||||
/** relative tolerance to solve to */
|
||||
double tolerance_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
LambdaMatrixSolver();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolverLumped
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class LambdaMatrixSolverLumped : public LambdaMatrixSolver {
|
||||
|
||||
public:
|
||||
|
||||
LambdaMatrixSolverLumped(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance);
|
||||
|
||||
~LambdaMatrixSolverLumped(){};
|
||||
|
||||
/** execute the solver */
|
||||
virtual void execute(VECTOR & rhs, VECTOR & lambda, DIAG_MAT & weights,ATC_Transfer * atcTransfer_=NULL);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
LambdaMatrixSolverLumped();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class LambdaMatrixSolverCg
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class LambdaMatrixSolverCg : public LambdaMatrixSolver {
|
||||
|
||||
public:
|
||||
|
||||
LambdaMatrixSolverCg(SPAR_MAT & matrixTemplate, SPAR_MAT & shapeFunctionMatrix, int maxIterations, double tolerance);
|
||||
|
||||
~LambdaMatrixSolverCg(){};
|
||||
|
||||
/** execute the solver */
|
||||
virtual void execute(VECTOR & rhs, VECTOR & lambda, DIAG_MAT & weights,ATC_Transfer * atcTransfer_=NULL);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
LambdaMatrixSolverCg();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
79
lib/atc/CG.h
79
lib/atc/CG.h
|
@ -1,79 +0,0 @@
|
|||
//*****************************************************************
|
||||
// Iterative template routine -- CG
|
||||
//
|
||||
// CG solves the symmetric positive definite linear
|
||||
// system Ax=b using the Conjugate Gradient method.
|
||||
//
|
||||
// CG follows the algorithm described on p. 15 in the
|
||||
// SIAM Templates book.
|
||||
//
|
||||
// The return value indicates convergence within max_iter (input)
|
||||
// iterations (0), or no convergence within max_iter iterations (1).
|
||||
//
|
||||
// Upon successful return, output arguments have the following values:
|
||||
//
|
||||
// x -- approximate solution to Ax = b
|
||||
// max_iter -- the number of iterations performed before the
|
||||
// tolerance was reached
|
||||
// tol -- the residual after the final iteration
|
||||
//
|
||||
//*****************************************************************
|
||||
|
||||
template < class Matrix, class Vector, class DataVector, class Preconditioner, class Real >
|
||||
int
|
||||
CG(const Matrix &A, Vector &x, const DataVector &b, const Preconditioner &M, int &max_iter, Real &tol) {
|
||||
Real resid;
|
||||
DenseVector<Real> p, z, q;
|
||||
Real alpha, beta, rho, rho_1;
|
||||
DenseVector<Real> tmp;
|
||||
tmp.reset(b.size());
|
||||
|
||||
p.reset(b.size());
|
||||
z.reset(b.size());
|
||||
q.reset(b.size());
|
||||
|
||||
Real normb = b.norm();
|
||||
DenseVector<Real> r;
|
||||
tmp = A*x;
|
||||
r = b - tmp;
|
||||
// Implicit assumption that only diagonal matrices are being used for preconditioning
|
||||
Preconditioner Minv = M.inv();
|
||||
|
||||
if (normb == 0.0)
|
||||
normb = 1;
|
||||
|
||||
if ((resid = r.norm() / normb) <= tol) {
|
||||
tol = resid;
|
||||
max_iter = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < max_iter; i++) {
|
||||
z = Minv*r;
|
||||
rho = r.dot(z);
|
||||
|
||||
if (i == 0)
|
||||
p = z;
|
||||
else {
|
||||
beta = rho / rho_1;
|
||||
tmp = p*beta;
|
||||
p = z + tmp;
|
||||
}
|
||||
|
||||
q = A*p;
|
||||
alpha = rho / p.dot(q);
|
||||
|
||||
x += p*alpha;
|
||||
r -= q*alpha;
|
||||
|
||||
if ((resid = r.norm() / normb) <= tol)
|
||||
{
|
||||
tol = resid;
|
||||
max_iter = i+1;
|
||||
return 0;
|
||||
}
|
||||
rho_1 = rho;
|
||||
}
|
||||
tol = resid;
|
||||
return 1;
|
||||
}
|
|
@ -1,243 +0,0 @@
|
|||
#ifndef CLONEVECTOR_H
|
||||
#define CLONEVECTOR_H
|
||||
|
||||
#include "Vector.h"
|
||||
|
||||
|
||||
template<typename T>
|
||||
class CloneVector : public Vector<T>
|
||||
{
|
||||
public:
|
||||
CloneVector(); // do not implement
|
||||
CloneVector(const Vector<T> &c);
|
||||
CloneVector(const Matrix<T> &c, int dim, INDEX idx=0);
|
||||
CloneVector(const DiagonalMatrix<T> &c, INDEX idx=0);
|
||||
|
||||
// overloaded virtual functions
|
||||
T& operator[](INDEX i);
|
||||
T operator[](INDEX i) const;
|
||||
T operator()(INDEX i, INDEX j=0) const;
|
||||
T& operator()(INDEX i, INDEX j=0);
|
||||
INDEX nRows() const;
|
||||
|
||||
CloneVector<T>& operator=(const T &v);
|
||||
CloneVector<T>& operator=(const CloneVector<T> &C);
|
||||
CloneVector<T>& operator=(const Matrix<T> &C);
|
||||
|
||||
virtual bool memory_contiguous() const;
|
||||
T* get_ptr() const;
|
||||
void resize(INDEX nRows, INDEX nCols=0, bool copy=false);
|
||||
void reset(INDEX nRows, INDEX nCols=0, bool zero=true);
|
||||
void copy(const T * ptr, INDEX nRows, INDEX nCols=0);
|
||||
|
||||
private:
|
||||
void _resize(INDEX nRows, INDEX nCols, bool copy, bool zero);
|
||||
|
||||
Vector<T> * const _baseV; // ptr to a base vector
|
||||
Matrix<T> * const _baseM; // ptr to a base matrix
|
||||
int _clone_type; // what to clown (see enum CLONE_TYPE)
|
||||
INDEX _idx; // index of matrix dimension to clone
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Template definitions ///////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
// Construct from another vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>::CloneVector(const Vector<T> &c)
|
||||
: Vector<T>(), _baseV(const_cast<Vector<T>*>(&c)), _baseM(NULL)
|
||||
{}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Construct from a matrix, the const_cast isn't pretty
|
||||
/* CloneVector(const Matrix<T> &c, int dim, INDEX idx)
|
||||
/ attaches to a slice of a matrix
|
||||
/ Arguments: c = pointer to the matrix
|
||||
/ dim = type of slice CLONE_ROW, CLONE_COL, CLONE_DIAG
|
||||
/ idx = index of row or column (no effect on diag currently)
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>::CloneVector(const Matrix<T> &c, int dim, INDEX idx)
|
||||
: Vector<T>(), _baseV(NULL), _baseM(const_cast<Matrix<T>*>(&c))
|
||||
, _clone_type(dim), _idx(idx)
|
||||
{}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Construct from a DiagonalMatrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>::CloneVector(const DiagonalMatrix<T> &c, INDEX idx)
|
||||
: Vector<T>(), _baseV(NULL), _baseM(const_cast<DiagonalMatrix<T>*>(&c))
|
||||
, _clone_type(CLONE_DIAG), _idx(0)
|
||||
{}
|
||||
//-----------------------------------------------------------------------------
|
||||
// value (const) indexing operator
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T CloneVector<T>::operator()(INDEX i, INDEX j) const
|
||||
{
|
||||
return (*this)[i];
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// reference index operator
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T& CloneVector<T>::operator()(INDEX i, INDEX j)
|
||||
{
|
||||
return (*this)[i];
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indexes the cloned vector either from another vector or a matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T CloneVector<T>::operator[](INDEX i) const
|
||||
{
|
||||
if (_baseV) return (*_baseV)(i);
|
||||
if (_clone_type == CLONE_ROW) return (*_baseM)(_idx, i);
|
||||
else if (_clone_type == CLONE_COL) return (*_baseM)(i,_idx);
|
||||
else if (_clone_type == CLONE_DIAG) return (*_baseM)(i,i);
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indexes the cloned vector either from another vector or a matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T& CloneVector<T>::operator[](INDEX i)
|
||||
{
|
||||
if (_baseV) return (*_baseV)(i);
|
||||
if (_clone_type == CLONE_ROW) return (*_baseM)(_idx, i);
|
||||
if (_clone_type == CLONE_COL) return (*_baseM)(i,_idx);
|
||||
if (_clone_type == CLONE_DIAG) return (*_baseM)(i,i);
|
||||
return (*_baseV)(i);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the size of the base vector or of the row/col of the base matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX CloneVector<T>::nRows() const
|
||||
{
|
||||
using std::min;
|
||||
if (_baseV) return _baseV->size();
|
||||
if (_clone_type == CLONE_ROW) return _baseM->nCols();
|
||||
if (_clone_type == CLONE_COL) return _baseM->nRows();
|
||||
if (_clone_type == CLONE_DIAG) return min(_baseM->nRows(), _baseM->nCols());
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns all elements to a constant
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>& CloneVector<T>::operator=(const T &v)
|
||||
{
|
||||
this->set_all_elements_to(v); // NOTE: DO NOT do _baseX->set_elements_to()
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns all elements to the corresponding elements in C
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>& CloneVector<T>::operator=(const CloneVector<T> &C)
|
||||
{
|
||||
GCK(*this, C, this->size()!=C.size(), "Error in CloneVector:operator=");
|
||||
FORi VIDX(i) = C[i];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns all elements to the corresponding elements in C
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
CloneVector<T>& CloneVector<T>::operator=(const Matrix<T> &C)
|
||||
{
|
||||
GCK(*this, C, this->size()!=C.size(), "Error in CloneVector:operator=");
|
||||
FORi VIDX(i) = C[i];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns true only if its guaranteed memory is contiguous
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool CloneVector<T>::memory_contiguous() const
|
||||
{
|
||||
// drill down through clone of clones
|
||||
if (_baseV) return _baseV->memory_contiguous();
|
||||
// could be okay if DiagonalMatrix, but can't guarantee this
|
||||
if (_clone_type == CLONE_DIAG) return false;
|
||||
#ifdef ROW_STORAGE
|
||||
return _clone_type == CLONE_ROW;
|
||||
#else
|
||||
return _clone_type == CLONE_COL;
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a pointer to the data unless the data is a column of a matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T* CloneVector<T>::get_ptr() const
|
||||
{
|
||||
if (_baseV) return _baseV->get_ptr();
|
||||
#ifdef ROW_STORAGE
|
||||
if (_clone_type == CLONE_ROW) return _baseM->get_ptr() + this->size()*_idx;
|
||||
if (_clone_type == CLONE_COL) return _baseM->get_ptr() + this->size();
|
||||
if (_clone_type == CLONE_DIAG) return _baseM->get_ptr();
|
||||
#else
|
||||
if (_clone_type == CLONE_COL) return _baseM->get_ptr() + this->size()*_idx;
|
||||
if (_clone_type == CLONE_ROW) return _baseM->get_ptr() + this->size();
|
||||
if (_clone_type == CLONE_DIAG) return _baseM->get_ptr();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// general resize function, can handle parents that are matrices or vectors
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void CloneVector<T>::_resize(INDEX nRows, INDEX nCols, bool copy, bool zero)
|
||||
{
|
||||
if (_baseV)
|
||||
{
|
||||
if (copy) _baseV->resize(nRows, nCols, copy);
|
||||
else _baseV->reset (nRows, nCols, zero);
|
||||
return;
|
||||
}
|
||||
// parent is a matrix, need to decide what the Vector is cloning
|
||||
switch (_clone_type)
|
||||
{
|
||||
case CLONE_ROW: // now the leading dimension is rows
|
||||
nCols = nCols ? nCols : _baseM->nCols();
|
||||
break;
|
||||
case CLONE_COL: // now the leading dimension is columns
|
||||
nCols = nCols ? nCols : _baseM->nRows();
|
||||
Utility::Swap(nRows, nCols);
|
||||
break;
|
||||
case CLONE_DIAG: // lets just hope you knew what you were doing
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (zero) _baseM->reset(nRows, nCols, zero); // zero overrides copy
|
||||
else _baseM->resize(nRows, nCols, copy);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix and optionally copies what fits
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void CloneVector<T>::resize(INDEX nRows, INDEX nCols, bool copy)
|
||||
{
|
||||
_resize(nRows, nCols, copy, false);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix and optionally zeros it out
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void CloneVector<T>::reset(INDEX nRows, INDEX nCols, bool zero)
|
||||
{
|
||||
_resize(nRows, nCols, false, zero);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix and copies data
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void CloneVector<T>::copy(const T * ptr, INDEX nRows, INDEX nCols)
|
||||
{
|
||||
_resize(nRows, nCols, false, false);
|
||||
memcpy(this->get_ptr(), ptr, this->size()*sizeof(T));
|
||||
}
|
||||
#endif
|
|
@ -1,317 +0,0 @@
|
|||
#ifndef DENSEMATRIX_H
|
||||
#define DENSEMATRIX_H
|
||||
|
||||
#include "Matrix.h"
|
||||
|
||||
template <typename T>
|
||||
class DenseMatrix : public Matrix<T>
|
||||
{
|
||||
public:
|
||||
DenseMatrix(INDEX rows=0, INDEX cols=0, bool z=1) { _create(rows, cols, z); }
|
||||
DenseMatrix(const DenseMatrix<T>& c) : _data(NULL){ _copy(c); }
|
||||
DenseMatrix(const SparseMatrix<T>& c): _data(NULL){ c.dense_copy(*this);}
|
||||
DenseMatrix(const Matrix<T>& c) : _data(NULL){ _copy(c); }
|
||||
// const SparseMatrix<T> * p = sparse_cast(&c);
|
||||
// (p) ? p->dense_copy(*this) : _copy(c); }
|
||||
~DenseMatrix() { _delete();}
|
||||
|
||||
void reset (INDEX rows, INDEX cols, bool zero=true);
|
||||
void resize(INDEX rows, INDEX cols, bool copy=false);
|
||||
void copy (const T * ptr, INDEX rows, INDEX cols);
|
||||
/** returns transpose(this) * B */
|
||||
DenseMatrix<T> transMat(const DenseMatrix<T>& B) const;
|
||||
/** returns by element multiply A_ij = this_ij * B_ij */
|
||||
DenseMatrix<T> mult_by_element(const DenseMatrix<T>& B) const;
|
||||
|
||||
/** overloaded virtual functions */
|
||||
T& operator()(INDEX i, INDEX j) { MICK(i,j) return DATA(i,j); }
|
||||
T operator()(INDEX i, INDEX j) const { MICK(i,j) return DATA(i,j); }
|
||||
T operator[](INDEX i) const { VICK(i) return _data[i]; }
|
||||
T& operator[](INDEX i) { VICK(i) return _data[i]; }
|
||||
INDEX nRows() const { return _nRows; }
|
||||
INDEX nCols() const { return _nCols; }
|
||||
T * get_ptr() const { return _data; }
|
||||
void write_restart(FILE *f) const;
|
||||
void set_all_elements_to(const T &v);
|
||||
DiagonalMatrix<T> get_diag() const;
|
||||
|
||||
DenseMatrix<T>& operator=(const T &v);
|
||||
DenseMatrix<T>& operator=(const Matrix<T> &c);
|
||||
DenseMatrix<T>& operator=(const DenseMatrix<T> &c);
|
||||
DenseMatrix<T>& operator=(const SparseMatrix<T> &c);
|
||||
|
||||
private:
|
||||
void _delete();
|
||||
void _create(INDEX rows, INDEX cols, bool zero=false);
|
||||
void _copy(const Matrix<T> &c);
|
||||
|
||||
T *_data;
|
||||
INDEX _nRows, _nCols;
|
||||
};
|
||||
|
||||
//! Computes the cofactor matrix of A.
|
||||
template<typename T>
|
||||
DenseMatrix<T> adjugate(const Matrix<T> &A, bool symmetric=false);
|
||||
|
||||
//! Returns a the tensor product of two vectors
|
||||
template<typename T>
|
||||
DenseMatrix<T> tensor_product(const Vector<T> &a, const Vector<T> &b);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Returns an identity matrix, defaults to 3x3.
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> eye(INDEX rows=3, INDEX cols=3)
|
||||
{
|
||||
const double dij[] = {0.0, 1.0};
|
||||
DENS_MAT I(rows, cols, false); // do not need to pre-zero
|
||||
for (INDEX j=0; j<cols; j++)
|
||||
for (INDEX i=0; i<rows; i++)
|
||||
I(i,j) = dij[i==j];
|
||||
return I;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// resizes the matrix and optionally zeros it out (default - zero)
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::reset(INDEX rows, INDEX cols, bool zero)
|
||||
{
|
||||
if (!this->is_size(rows, cols))
|
||||
{
|
||||
_delete();
|
||||
_create(rows, cols);
|
||||
}
|
||||
if (zero) this->zero();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// resizes the matrix and optionally copies over what still fits
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::resize(INDEX rows, INDEX cols, bool copy)
|
||||
{
|
||||
if (this->is_size(rows, cols)) return; // if is correct size, done
|
||||
if (!copy)
|
||||
{
|
||||
_delete();
|
||||
_create(rows, cols);
|
||||
return;
|
||||
}
|
||||
DenseMatrix<T> temp(*this);
|
||||
_delete();
|
||||
_create(rows, cols);
|
||||
FORij MIDX(i,j) = temp.in_range(i,j) ? temp(i,j) : T(0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// resizes the matrix and copies data
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::copy(const T * ptr, INDEX rows, INDEX cols)
|
||||
{
|
||||
resize(rows, cols, false);
|
||||
memcpy(_data, ptr, this->size()*sizeof(T));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// returns transpose(this) * B
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T> DenseMatrix<T>::transMat(const DenseMatrix<T>& B) const
|
||||
{
|
||||
DenseMatrix C;
|
||||
MultAB(*this, B, C, true);
|
||||
return C;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// returns this_ij * B_ij
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T> DenseMatrix<T>::mult_by_element(const DenseMatrix<T>& B) const
|
||||
{
|
||||
DenseMatrix C;
|
||||
C.reset(_nRows,_nCols);
|
||||
FORij C(i,j) = (*this)(i,j)*B(i,j);
|
||||
return C;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// writes the matrix data to a file
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::write_restart(FILE *f) const
|
||||
{
|
||||
fwrite(&_nRows, sizeof(INDEX),1,f);
|
||||
fwrite(&_nCols, sizeof(INDEX),1,f);
|
||||
if (this->size()) fwrite(_data, sizeof(T), this->size(), f);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// sets all elements to a value (optimized)
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void DenseMatrix<T>::set_all_elements_to(const T &v)
|
||||
{
|
||||
FORi _data[i] = v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return a diagonal matrix containing the diagonal entries of this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> DenseMatrix<T>::get_diag() const
|
||||
{
|
||||
DiagonalMatrix<T> D(nRows(), true); // initialized to zero
|
||||
INDEX i;
|
||||
for (i=0; i<nRows(); i++)
|
||||
{
|
||||
D(i,i) = DATA(i,i);
|
||||
}
|
||||
return D;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// clears allocated memory
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::_delete()
|
||||
{
|
||||
_nRows = _nCols = 0;
|
||||
if (_data) delete [] _data;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// allocates memory for an rows by cols DenseMatrix
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::_create(INDEX rows, INDEX cols, bool zero)
|
||||
{
|
||||
_nRows=rows;
|
||||
_nCols=cols;
|
||||
_data = (this->size() ? new T [_nCols*_nRows] : NULL);
|
||||
if (zero) this->zero();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// creates a deep memory copy from a general matrix
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseMatrix<T>::_copy(const Matrix<T> &c)
|
||||
{
|
||||
if (!_data || this->size()!=c.size())
|
||||
{
|
||||
_delete();
|
||||
_create(c.nRows(), c.nCols());
|
||||
}
|
||||
else
|
||||
{
|
||||
_nRows = c.nRows();
|
||||
_nCols = c.nCols();
|
||||
}
|
||||
memcpy(_data, c.get_ptr(), c.size()*sizeof(T));
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// sets all elements to a constant
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T>& DenseMatrix<T>::operator=(const T &v)
|
||||
{
|
||||
this->set_all_elements_to(v);
|
||||
return *this;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// copys c with a deep copy
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T>& DenseMatrix<T>::operator=(const Matrix<T> &c)
|
||||
{
|
||||
_copy(c);
|
||||
return *this;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// copys c with a deep copy
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T>& DenseMatrix<T>::operator=(const DenseMatrix<T> &c)
|
||||
{
|
||||
_copy(c);
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copys c with a deep copy, including zeros
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
DenseMatrix<T>& DenseMatrix<T>::operator=(const SparseMatrix<T> &c)
|
||||
{
|
||||
_delete();
|
||||
_create(c.nRows(), c.nCols(), true);
|
||||
SparseMatrix<T>::compress(c);
|
||||
for (INDEX i=0; i<c.size(); i++)
|
||||
{
|
||||
TRIPLET<T> x = c.get_triplet(i);
|
||||
cout << "x.i: "<< x.i << "\nx.j: "<< x.j << "\nv.j: "<< x.v << std::endl << std::endl;
|
||||
MIDX(x.i, x.j) = x.v;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//* Returns the transpose of the cofactor matrix of A.
|
||||
//* see http://en.wikipedia.org/wiki/Adjugate_matrix
|
||||
//* symmetric flag only affects cases N>3
|
||||
template<typename T>
|
||||
DenseMatrix<T> adjugate(const Matrix<T> &A, bool symmetric)
|
||||
{
|
||||
if (!A.is_square()) gerror("adjugate can only be computed for square matrices.");
|
||||
DenseMatrix<T> C(A.nRows(), A.nRows());
|
||||
switch (A.nRows()) {
|
||||
case 1:
|
||||
gerror("adjugate must be computed for matrixes of size greater than 1");
|
||||
case 2:
|
||||
C(0,0) = A(1,1); C(0,1) =-A(0,1);
|
||||
C(1,0) =-A(1,0); C(1,1) = A(0,0);
|
||||
break;
|
||||
case 3: // 3x3 case was tested vs matlab
|
||||
C(0,0) = A(1,1)*A(2,2)-A(1,2)*A(2,1);
|
||||
C(1,0) =-A(1,0)*A(2,2)+A(1,2)*A(2,0); // i+j is odd (reverse sign)
|
||||
C(2,0) = A(1,0)*A(2,1)-A(1,1)*A(2,0);
|
||||
C(0,1) =-A(0,1)*A(2,2)+A(0,2)*A(2,1); // i+j is odd
|
||||
C(1,1) = A(0,0)*A(2,2)-A(0,2)*A(2,0);
|
||||
C(2,1) =-A(0,0)*A(2,1)+A(0,1)*A(2,0); // i+j is odd
|
||||
C(0,2) = A(0,1)*A(1,2)-A(0,2)*A(1,1);
|
||||
C(1,2) =-A(0,0)*A(1,2)+A(0,2)*A(1,0); // i+j is odd
|
||||
C(2,2) = A(0,0)*A(1,1)-A(0,1)*A(1,0);
|
||||
break;
|
||||
default:
|
||||
// NOTE: - det() is only defined for type double
|
||||
// this feature is neither tested nor optimal - use at your own risk!!!
|
||||
DenseMatrix<T> m(A.nRows()-1, A.nRows()-1);
|
||||
double sign[] = {1.0, -1.0};
|
||||
for (unsigned j=0; j<A.nCols(); j++) {
|
||||
for (unsigned i=0; i<A.nRows(); i++) {
|
||||
for (unsigned mj=0; mj<m.nCols(); mj++) {
|
||||
for (unsigned mi=0; mi<m.nRows(); mi++) {
|
||||
m(mi, mj) = A(mi+(mi>=i), mj+(mj>=j)); // skip row i and col j
|
||||
}
|
||||
}
|
||||
if (!symmetric) C(j,i)=det(m)*sign[(i+j)&1];
|
||||
if (symmetric && i>=j) C(i,j)=C(j,i)=det(m)*sign[(i+j)&1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
// Returns a the tensor product of two vectors
|
||||
template<typename T>
|
||||
DenseMatrix<T> tensor_product(const Vector<T> &a, const Vector<T> &b)
|
||||
{
|
||||
DenseMatrix<T> ab(a.size(), b.size());
|
||||
for (unsigned j=0; j<b.size(); j++)
|
||||
for (unsigned i=0; i<a.size(); i++)
|
||||
ab(i,j) = a(i)*b(j);
|
||||
return ab;
|
||||
}
|
||||
|
||||
//* Returns a DenseMatrix with random values (like matlab rand(m,n)
|
||||
template<typename T>
|
||||
DenseMatrix<T> rand(unsigned rows, unsigned cols, int seed=1234)
|
||||
{
|
||||
srand(seed);
|
||||
const double rand_max_inv = 1.0 / double(RAND_MAX);
|
||||
DenseMatrix<T> R(rows, cols, false);
|
||||
for (unsigned i=0; i<R.size(); i++) R[i]=double(::rand())*rand_max_inv;
|
||||
return R;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
#ifndef DENSEVECTOR_H
|
||||
#define DENSEVECTOR_H
|
||||
|
||||
#include "Vector.h"
|
||||
template<typename T>
|
||||
class DenseVector : public Vector<T>
|
||||
{
|
||||
public:
|
||||
explicit DenseVector(INDEX n=0, bool z=1) { _create(n,z); }
|
||||
DenseVector(const DenseVector<T> &c) : _data(NULL) { _copy(c); }
|
||||
DenseVector(const Vector<T> &c) : _data(NULL) { _copy(c); }
|
||||
virtual ~DenseVector() { _delete(); }
|
||||
|
||||
//* resizes the Vector, ignores nCols, optionally copys what fits
|
||||
void resize(INDEX rows, INDEX cols=1, bool copy=false);
|
||||
//* resizes the Vector, ignores nCols, optionally zeros it out
|
||||
void reset (INDEX rows, INDEX cols=1, bool zero=true);
|
||||
//* resizes the Vector and copies data, ignores nCols
|
||||
void copy(const T * ptr, INDEX rows, INDEX cols=1);
|
||||
|
||||
// overloaded inline virtual functions
|
||||
T operator[](INDEX i) const { VICK(i) return _data[i]; }
|
||||
T& operator[](INDEX i) { VICK(i) return _data[i]; }
|
||||
T operator()(INDEX i, INDEX j=0) const { VICK(i) return _data[i]; }
|
||||
T& operator()(INDEX i, INDEX j=0) { VICK(i) return _data[i]; }
|
||||
void set_all_elements_to(const T &v) { FORi _data[i] = v; }
|
||||
INDEX nRows() const { return _size; }
|
||||
|
||||
T* get_ptr() const { return _data; }
|
||||
|
||||
DenseVector<T>& operator=(const T &v);
|
||||
DenseVector<T>& operator=(const Vector<T> &c);
|
||||
DenseVector<T>& operator=(const DenseVector<T> &c);
|
||||
|
||||
void write_restart(FILE *f) const;
|
||||
|
||||
private:
|
||||
void _delete();
|
||||
void _create(INDEX n, bool zero=0);
|
||||
void _copy(const Vector<T> &c);
|
||||
|
||||
T *_data;
|
||||
INDEX _size;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Template definitions ///////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix and optionally copies over what still fits, ignores cols
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void DenseVector<T>::resize(INDEX rows, INDEX cols, bool copy)
|
||||
{
|
||||
if (_size==rows) return; // if is correct size, done
|
||||
if (!copy)
|
||||
{
|
||||
_delete();
|
||||
_create(rows);
|
||||
return;
|
||||
}
|
||||
DenseVector<T> temp(*this);
|
||||
_delete();
|
||||
_create(rows);
|
||||
FORi _data[i] = i<temp.size() ? temp[i] : T(0.0);
|
||||
return;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* resizes the matrix and optionally zeros it out
|
||||
template <typename T>
|
||||
void DenseVector<T>::reset(INDEX rows, INDEX cols, bool zero)
|
||||
{
|
||||
if (_size!=rows)
|
||||
{
|
||||
_delete();
|
||||
_create(rows);
|
||||
}
|
||||
if (zero) this->zero();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* resizes the matrix and optionally zeros it out
|
||||
template <typename T>
|
||||
void DenseVector<T>::copy(const T * ptr, INDEX rows, INDEX cols)
|
||||
{
|
||||
resize(rows, 1, false);
|
||||
memcpy(_data, ptr, this->size()*sizeof(T));
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* writes the matrix data to a file
|
||||
template <typename T>
|
||||
void DenseVector<T>::write_restart(FILE *f) const
|
||||
{
|
||||
fwrite(&_size, sizeof(INDEX),1,f);
|
||||
if(_size) fwrite(_data, sizeof(T), _size, f);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* clears allocated memory
|
||||
template <typename T>
|
||||
inline void DenseVector<T>::_delete()
|
||||
{
|
||||
if (_data) delete [] _data;
|
||||
_size = 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* allocates memory for an rows by cols DenseMatrix
|
||||
template <typename T>
|
||||
inline void DenseVector<T>::_create(INDEX n, bool zero)
|
||||
{
|
||||
_size=n;
|
||||
_data = _size ? new T [_size] : NULL ;
|
||||
if (zero) this->zero();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* creates a deep memory copy from a general matrix
|
||||
template <typename T>
|
||||
inline void DenseVector<T>::_copy(const Vector<T> &c)
|
||||
{
|
||||
if (!_data || _size!=c.size())
|
||||
{
|
||||
_delete();
|
||||
_create(c.size(), false);
|
||||
}
|
||||
else _size = c.size();
|
||||
memcpy(_data, c.get_ptr(), _size*sizeof(T));
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* assigns v to all values in the vector
|
||||
template <typename T>
|
||||
DenseVector<T>& DenseVector<T>::operator=(const T &v)
|
||||
{
|
||||
FORi VIDX(i) = v;
|
||||
return *this;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* copys c with a deep copy
|
||||
template <typename T>
|
||||
DenseVector<T>& DenseVector<T>::operator=(const Vector<T> &c)
|
||||
{
|
||||
_copy(c);
|
||||
return *this;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* copys c with a deep copy
|
||||
template <typename T>
|
||||
DenseVector<T>& DenseVector<T>::operator=(const DenseVector<T> &c)
|
||||
{
|
||||
_copy(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,462 +0,0 @@
|
|||
#ifndef DIAGONALMATRIX_H
|
||||
#define DIAGONALMATRIX_H
|
||||
|
||||
#include "MatrixDef.h"
|
||||
|
||||
template<typename T>
|
||||
class DiagonalMatrix : public Matrix<T>
|
||||
{
|
||||
public:
|
||||
explicit DiagonalMatrix(INDEX nRows=0, bool zero=0);
|
||||
DiagonalMatrix(const DiagonalMatrix<T>& c);
|
||||
DiagonalMatrix(const Vector<T>& v);
|
||||
virtual ~DiagonalMatrix();
|
||||
|
||||
//* resizes the matrix, ignores nCols, optionally zeros
|
||||
void reset(INDEX rows, INDEX cols=0, bool zero=true);
|
||||
//* resizes the matrix, ignores nCols, optionally copies what fits
|
||||
void resize(INDEX rows, INDEX cols=0, bool copy=false);
|
||||
//* resets based on full copy of vector v
|
||||
void reset(const Vector<T>& v);
|
||||
//* resets based on full copy of a DiagonalMatrix
|
||||
void reset(const DiagonalMatrix<T>& v);
|
||||
//* resizes the matrix, ignores nCols, optionally copies what fits
|
||||
void copy(const T * ptr, INDEX rows, INDEX cols=0);
|
||||
|
||||
//* resets based on a "shallow" copy of a vector
|
||||
void shallowreset(const Vector<T> &v);
|
||||
//* resets based on a "shallow" copy of a DiagonalMatrix
|
||||
void shallowreset(const DiagonalMatrix<T> &c);
|
||||
|
||||
T& operator()(INDEX i, INDEX j);
|
||||
T operator()(INDEX i, INDEX j) const;
|
||||
T& operator[](INDEX i);
|
||||
T operator[](INDEX i) const;
|
||||
INDEX nRows() const;
|
||||
INDEX nCols() const;
|
||||
T* get_ptr() const;
|
||||
void write_restart(FILE *f) const;
|
||||
|
||||
// Dump matrix contents to screen (not defined for all datatypes)
|
||||
string tostring() const { return _data->tostring(); }
|
||||
|
||||
using Matrix<T>::matlab;
|
||||
void matlab(ostream &o, const string &s="D") const;
|
||||
|
||||
// overloaded operators
|
||||
DiagonalMatrix<T>& operator=(const T s);
|
||||
DiagonalMatrix<T>& operator=(const DiagonalMatrix<T> &C);
|
||||
//DiagonalMatrix<T>& operator=(const Vector<T> &C);
|
||||
|
||||
INDEX size() const { return _data->size(); }
|
||||
//* computes the inverse of this matrix
|
||||
DiagonalMatrix<T>& inv_this();
|
||||
//* returns a copy of the inverse of this matrix
|
||||
DiagonalMatrix<T> inv() const;
|
||||
|
||||
protected:
|
||||
void _set_equal(const Matrix<T> &r);
|
||||
DiagonalMatrix& operator=(const Vector<T> &c) {}
|
||||
DiagonalMatrix& operator=(const Matrix<T> &c) {}
|
||||
|
||||
private:
|
||||
void _delete();
|
||||
Vector<T> *_data;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix-DiagonalMatrix multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> operator*(const DiagonalMatrix<T>& A, const DiagonalMatrix<T>& B)
|
||||
{
|
||||
SSCK(A, B, "DiagonalMatrix-DiagonalMatrix multiplication");
|
||||
DiagonalMatrix<T> R(A);
|
||||
for (INDEX i=0; i<R.nRows(); i++) R[i] *= B[i];
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix-matrix multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const DiagonalMatrix<T>& A, const Matrix<T> &B)
|
||||
{
|
||||
GCK(A, B, A.nCols()!=B.nRows(), "DiagonalMatrix-Matrix multiplication");
|
||||
DenseMatrix<T> R(B); // makes a copy of r to return
|
||||
for (INDEX i=0; i<R.nRows(); i++)
|
||||
for (INDEX j=0; j<R.nCols(); j++)
|
||||
R(i,j) *= A[i];
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// matrix-DiagonalMatrix multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const Matrix<T> &B, const DiagonalMatrix<T>& A)
|
||||
{
|
||||
GCK(B, A, B.nCols()!=A.nRows(), "Matrix-DiagonalMatrix multiplication");
|
||||
DenseMatrix<T> R(B); // makes a copy of r to return
|
||||
for (INDEX j=0; j<R.nCols(); j++)
|
||||
for (INDEX i=0; i<R.nRows(); i++)
|
||||
R(i,j) *= A[j];
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix-vector multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const DiagonalMatrix<T>& A, const Vector<T> &b)
|
||||
{
|
||||
GCK(A, b, A.nCols()!=b.size(), "DiagonalMatrix-Vector multiplication");
|
||||
DenseVector<T> r(b); // makes a copy of r to return
|
||||
for (INDEX i=0; i<r.size(); i++)
|
||||
r[i] *= A[i];
|
||||
return r;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// vector-DiagonalMatrix multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const Vector<T> &b, const DiagonalMatrix<T>& A)
|
||||
{
|
||||
GCK(b, A, b.size()!=A.nRows(), "Matrix-DiagonalMatrix multiplication");
|
||||
DenseVector<T> r(b); // makes a copy of r to return
|
||||
for (INDEX i=0; i<r.size(); i++)
|
||||
r[i] *= A[i];
|
||||
return r;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix-SparseMatrix multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T> operator*(const DiagonalMatrix<T> &A, const SparseMatrix<T>& B)
|
||||
{
|
||||
GCK(A, B, A.nCols()!=B.nRows() ,"DiagonalMatrix-SparseMatrix multiplication");
|
||||
SparseMatrix<T> R(B);
|
||||
CloneVector<T> d(A);
|
||||
R.row_scale(d);
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix-scalar multiplication
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> operator*(DiagonalMatrix<T> &A, const T s)
|
||||
{
|
||||
DiagonalMatrix<T> R(A);
|
||||
R *= s;
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Commute with DiagonalMatrix * double
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> operator*(const T s, const DiagonalMatrix<T>& A)
|
||||
{
|
||||
DiagonalMatrix<T> R(A);
|
||||
R *= s;
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix addition
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> operator+(const DiagonalMatrix<T> &A, const DiagonalMatrix<T> &B)
|
||||
{
|
||||
DiagonalMatrix<T> R(A);
|
||||
R+=B;
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// DiagonalMatrix subtraction
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> operator-(const DiagonalMatrix<T> &A, const DiagonalMatrix<T> &B)
|
||||
{
|
||||
DiagonalMatrix<T> R(A);
|
||||
return R-=B;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// template member definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default constructor - optionally zeros the matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>::DiagonalMatrix(INDEX rows, bool zero)
|
||||
: _data(NULL)
|
||||
{
|
||||
reset(rows, zero);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy constructor - makes a full copy
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>::DiagonalMatrix(const DiagonalMatrix<T>& c)
|
||||
: _data(NULL)
|
||||
{
|
||||
reset(c);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy constructor from vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>::DiagonalMatrix(const Vector<T>& v)
|
||||
: _data(NULL)
|
||||
{
|
||||
reset(v);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>::~DiagonalMatrix()
|
||||
{
|
||||
_delete();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// deletes the data stored by this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::_delete()
|
||||
{
|
||||
if (_data) delete _data;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix, ignores nCols, optionally zeros
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::reset(INDEX rows, INDEX cols, bool zero)
|
||||
{
|
||||
_delete();
|
||||
_data = new DenseVector<T>(rows, zero);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix, ignores nCols, optionally copies what fits
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::resize(INDEX rows, INDEX cols, bool copy)
|
||||
{
|
||||
_data->resize(rows, copy);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// changes the diagonal of the matrix to a vector v (makes a copy)
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::reset(const Vector<T>& v)
|
||||
{
|
||||
if (&v == _data) return; // check for self-reset
|
||||
_delete();
|
||||
_data = new DenseVector<T>(v);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copys from another DiagonalMatrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::reset(const DiagonalMatrix<T>& c)
|
||||
{
|
||||
reset(*(c._data));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resizes the matrix and copies data
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::copy(const T * ptr, INDEX rows, INDEX cols)
|
||||
{
|
||||
if (_data) _data->reset(rows, false);
|
||||
else _data = new DenseVector<T>(rows, false);
|
||||
memcpy(_data, ptr, this->size()*sizeof(T));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// shallow reset from another DiagonalMatrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::shallowreset(const DiagonalMatrix<T> &c)
|
||||
{
|
||||
_delete();
|
||||
_data = new CloneVector<T>(*(c._data));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// shallow reset from Vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::shallowreset(const Vector<T> &v)
|
||||
{
|
||||
_delete();
|
||||
_data = new CloneVector<T>(v);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// reference indexing operator - must throw an error if i!=j
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T& DiagonalMatrix<T>::operator()(INDEX i, INDEX j)
|
||||
{
|
||||
GCK(*this,*this,i!=j,"DiagonalMatrix: tried to index off diagonal");
|
||||
return VIDX(i);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// value indexing operator - returns 0 if i!=j
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T DiagonalMatrix<T>::operator()(INDEX i, INDEX j) const
|
||||
{
|
||||
return (i==j) ? (*_data)(i) : (T)0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// flat reference indexing operator
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T& DiagonalMatrix<T>::operator[](INDEX i)
|
||||
{
|
||||
return (*_data)(i);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// flat value indexing operator
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T DiagonalMatrix<T>::operator[](INDEX i) const
|
||||
{
|
||||
return (*_data)(i);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of rows
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX DiagonalMatrix<T>::nRows() const
|
||||
{
|
||||
return _data->size();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of columns (same as nCols())
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX DiagonalMatrix<T>::nCols() const
|
||||
{
|
||||
return _data->size();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns a pointer to the diagonal values, dangerous!
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T* DiagonalMatrix<T>::get_ptr() const
|
||||
{
|
||||
return _data->get_ptr();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// writes the diagonal to a binary data restart file
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::write_restart(FILE *f) const
|
||||
{
|
||||
_data->write_restart(f);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// sets the diagonal to a constant
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>& DiagonalMatrix<T>::operator=(const T v)
|
||||
{
|
||||
this->set_all_elements_to(v);
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assignment operator with another diagonal matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>& DiagonalMatrix<T>::operator=(const DiagonalMatrix<T>& C)
|
||||
{
|
||||
reset(C);
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// writes a matlab command to duplicate this sparse matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::matlab(ostream &o, const string &s) const
|
||||
{
|
||||
_data->matlab(o, s);
|
||||
o << s <<"=diag("<<s<<",0);\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// inverts this matrix, returns a reference
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T>& DiagonalMatrix<T>::inv_this()
|
||||
{
|
||||
for(INDEX i=0; i<nRows(); i++)
|
||||
{
|
||||
if (VIDX(i)!=T(0)) VIDX(i) = 1.0/VIDX(i);
|
||||
else
|
||||
{
|
||||
cout<<"DiagonalMatrix::inv(): ("<<i<<","<<i<<")=0\n";
|
||||
}
|
||||
}
|
||||
// Error check info
|
||||
const double min_max = _data->minabs() / _data->maxabs();
|
||||
if (min_max > 1e-14) return *this;
|
||||
cout << "DiagonalMatrix::inv_this(): Warning: Matrix is badly scaled.";
|
||||
cout << " RCOND = "<<min_max<<"\n";
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the inverse of this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> DiagonalMatrix<T>::inv() const
|
||||
{
|
||||
DiagonalMatrix<T> invA(*this); // Make copy of A to invert
|
||||
|
||||
for(INDEX i=0; i<invA.nRows(); i++)
|
||||
{
|
||||
if (VIDX(i)!=T(0)) invA[i]=1.0/VIDX(i);
|
||||
else
|
||||
{
|
||||
cout<<"DiagonalMatrix::inv(): ("<<i<<","<<i<<")=0\n";
|
||||
}
|
||||
}
|
||||
// Error check info
|
||||
const double min_max = _data->minabs() / _data->maxabs();
|
||||
if (min_max > 1e-14) return invA;
|
||||
cout << "DiagonalMatrix::inv(): Warning: Matrix is badly scaled.";
|
||||
cout << " RCOND = "<<min_max<<"\n";
|
||||
return invA;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// computes a matrix inverse
|
||||
//-----------------------------------------------------------------------------
|
||||
inline DiagonalMatrix<double> inv(const DiagonalMatrix<double>& A)
|
||||
{
|
||||
return A.inv();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// general diagonalmatrix assigment
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void DiagonalMatrix<T>::_set_equal(const Matrix<T> &r)
|
||||
{
|
||||
this->resize(r.nRows(), r.nCols());
|
||||
const Matrix<T> *pr = &r;
|
||||
|
||||
const SparseMatrix<T> *ps = dynamic_cast<const SparseMatrix<T>*> (pr);
|
||||
const DiagonalMatrix<T> *pd = dynamic_cast<const DiagonalMatrix<T>*> (pr);
|
||||
const Vector<T> *pv = dynamic_cast<const Vector<T>*> (pr);
|
||||
|
||||
if (ps) this->reset(ps->get_diag());
|
||||
else if (pd) this->reset(*pd);
|
||||
else if (pv) this->reset(*pv);
|
||||
else
|
||||
{
|
||||
cout <<"Error in general sparse matrix assignment\n";
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// casts a generic matrix pointer into a DiagonalMatrix pointer - null if fail
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const DiagonalMatrix<T> *diag_cast(const Matrix<T> *m)
|
||||
{
|
||||
return dynamic_cast<const DiagonalMatrix<T>*>(m);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,251 +0,0 @@
|
|||
// ATC transfer headers
|
||||
#include "ElasticTimeIntegrator.h"
|
||||
#include "ATC_Transfer.h"
|
||||
#include "TimeFilter.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegrator
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab data from ATC
|
||||
//--------------------------------------------------------
|
||||
ElasticTimeIntegrator::ElasticTimeIntegrator(ATC_Transfer * atcTransfer,
|
||||
TimeIntegrationType timeIntegrationType) :
|
||||
TimeIntegrator(atcTransfer, timeIntegrationType)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// modify
|
||||
// parses inputs and modifies state of the filter
|
||||
//--------------------------------------------------------
|
||||
bool ElasticTimeIntegrator::modify(int narg, char **arg)
|
||||
{
|
||||
// currently no parsing for elastic time integration
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
// sets up all the necessary data
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegrator::initialize()
|
||||
{
|
||||
if (needReset_ || timeFilterManager_->need_reset()) {
|
||||
if (timeIntegrationMethod_)
|
||||
delete timeIntegrationMethod_;
|
||||
|
||||
if (timeFilterManager_->need_reset()) {
|
||||
if (timeFilter_)
|
||||
delete timeFilter_;
|
||||
timeFilter_ = timeFilterManager_->construct(TimeFilterManager::IMPLICIT);
|
||||
}
|
||||
|
||||
if (timeFilterManager_->filter_dynamics()) {
|
||||
timeIntegrationMethod_ = new ElasticTimeIntegratorVerletFiltered(this);
|
||||
}
|
||||
else {
|
||||
timeIntegrationMethod_ = new ElasticTimeIntegratorVerlet(this);
|
||||
}
|
||||
}
|
||||
TimeIntegrator::initialize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticIntegrationMethod
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab data from ATC
|
||||
//--------------------------------------------------------
|
||||
ElasticIntegrationMethod::ElasticIntegrationMethod(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
||||
TimeIntegrationMethod(elasticTimeIntegrator),
|
||||
timeFilter_(timeIntegrator_->get_time_filter()),
|
||||
displacement_(atcTransfer_->get_field(DISPLACEMENT)),
|
||||
velocity_(atcTransfer_->get_field(VELOCITY)),
|
||||
acceleration_(atcTransfer_->get_field_roc(VELOCITY)),
|
||||
nodalAtomicDisplacement_(atcTransfer_->get_atomic_field(DISPLACEMENT)),
|
||||
nodalAtomicVelocity_(atcTransfer_->get_atomic_field(VELOCITY)),
|
||||
velocityRhs_(atcTransfer_->get_field_rhs(VELOCITY)),
|
||||
nodalAtomicForce_(atcTransfer_->get_fe_atomic_field_roc(VELOCITY)),
|
||||
forceFilteringData_(atcTransfer_->get_aux_storage(VELOCITY))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegratorVerlet
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
ElasticTimeIntegratorVerlet::ElasticTimeIntegratorVerlet(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
||||
ElasticIntegrationMethod(elasticTimeIntegrator)
|
||||
{
|
||||
TimeFilterManager * timeFilterManager = (timeIntegrator_->get_atc_transfer())->get_time_filter_manager();
|
||||
if (timeFilterManager->need_reset()) {
|
||||
timeFilter_->initialize(nodalAtomicForce_);
|
||||
}
|
||||
// reset filtering data, if needed
|
||||
if (!(timeFilterManager->end_equilibrate())) {
|
||||
forceFilteringData_.reset(atcTransfer_->get_nNodes(),atcTransfer_->get_nsd());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// mid_initial_integrate1
|
||||
// time integration at the mid-point of Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerlet::mid_initial_integrate1(double dt)
|
||||
{
|
||||
explicit_1(velocity_,acceleration_,.5*dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_initial_integrate1
|
||||
// time integration after Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerlet::post_initial_integrate1(double dt)
|
||||
{
|
||||
// NOTE could use explicit_2 with velocityRhs_ as the 2nd derivative
|
||||
// for improved accuracy, but this would be inconsistent with
|
||||
// the atomic integration scheme
|
||||
explicit_1(displacement_,velocity_,dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_final_integrate1
|
||||
// first time integration computations
|
||||
// before Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerlet::pre_final_integrate1(double dt)
|
||||
{
|
||||
// Compute MD contribution to FEM equation
|
||||
DENS_MAT atomicForces;
|
||||
atcTransfer_->compute_atomic_force(atomicForces,atcTransfer_->get_f());
|
||||
atcTransfer_->restrict_volumetric_quantity(atomicForces,nodalAtomicForce_);
|
||||
timeFilter_->apply_post_step2(forceFilteringData_,nodalAtomicForce_,dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_final_integrate1
|
||||
// second time integration computations
|
||||
// after Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerlet::post_final_integrate1(double dt)
|
||||
{
|
||||
atcTransfer_->apply_inverse_mass_matrix(velocityRhs_,
|
||||
acceleration_,
|
||||
VELOCITY);
|
||||
explicit_1(velocity_,acceleration_,.5*dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_process
|
||||
// post processing of variables before output
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerlet::post_process(double dt)
|
||||
{
|
||||
DENS_MAT atomicQuantity;
|
||||
atcTransfer_->compute_atomic_momentum(atomicQuantity,atcTransfer_->get_v());
|
||||
atcTransfer_->project_md_volumetric_quantity(atomicQuantity,nodalAtomicVelocity_,VELOCITY);
|
||||
|
||||
atcTransfer_->compute_atomic_centerOfMass_displacement(atomicQuantity,atcTransfer_->get_x());
|
||||
atcTransfer_->project_md_volumetric_quantity(atomicQuantity,nodalAtomicDisplacement_,VELOCITY);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegratorVerletFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
ElasticTimeIntegratorVerletFiltered::ElasticTimeIntegratorVerletFiltered(ElasticTimeIntegrator * elasticTimeIntegrator) :
|
||||
ElasticTimeIntegratorVerlet(elasticTimeIntegrator),
|
||||
nodalAtomicAcceleration_(atcTransfer_->get_atomic_field_roc(VELOCITY))
|
||||
{
|
||||
// swap filtered and unfiltered forces
|
||||
if ((timeIntegrator_->get_time_filter_manager())->end_equilibrate()) {
|
||||
DENS_MAT temp(nodalAtomicForce_);
|
||||
nodalAtomicForce_ = forceFilteringData_;
|
||||
forceFilteringData_ = temp;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// mid_initial_integrate1
|
||||
// time integration at the mid-point of Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerletFiltered::mid_initial_integrate1(double dt)
|
||||
{
|
||||
explicit_1(velocity_,acceleration_,.5*dt);
|
||||
explicit_1(nodalAtomicVelocity_,nodalAtomicAcceleration_,.5*dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_initial_integrate1
|
||||
// time integration after Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerletFiltered::post_initial_integrate1(double dt)
|
||||
{
|
||||
// NOTE could use explicit_2 with velocityRhs_ as the 2nd derivative
|
||||
// for improved accuracy, but this would be inconsistent with
|
||||
// the atomic integration scheme
|
||||
explicit_1(displacement_,velocity_,dt);
|
||||
explicit_1(nodalAtomicDisplacement_,nodalAtomicVelocity_,dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_final_integrate1
|
||||
// first time integration computations
|
||||
// before Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerletFiltered::pre_final_integrate1(double dt)
|
||||
{
|
||||
// Compute MD contribution to FEM equation
|
||||
DENS_MAT atomicForces;
|
||||
atcTransfer_->compute_atomic_force(atomicForces,atcTransfer_->get_f());
|
||||
|
||||
// apply time filtering to instantaneous atomic force for FE equation
|
||||
// NOTE would an explicit-implicit time filter be more accurate?
|
||||
atcTransfer_->restrict_volumetric_quantity(atomicForces,forceFilteringData_);
|
||||
timeFilter_->apply_post_step2(nodalAtomicForce_,forceFilteringData_,dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_final_integrate1
|
||||
// second time integration computations
|
||||
// after Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void ElasticTimeIntegratorVerletFiltered::post_final_integrate1(double dt)
|
||||
{
|
||||
DENS_MAT velocityRoc(velocityRhs_.nRows(),velocityRhs_.nCols());
|
||||
atcTransfer_->apply_inverse_mass_matrix(velocityRhs_,
|
||||
acceleration_,
|
||||
VELOCITY);
|
||||
explicit_1(velocity_,acceleration_,.5*dt);
|
||||
|
||||
atcTransfer_->apply_inverse_md_mass_matrix(nodalAtomicForce_,
|
||||
nodalAtomicAcceleration_,
|
||||
VELOCITY);
|
||||
explicit_1(nodalAtomicVelocity_,nodalAtomicAcceleration_,.5*dt);
|
||||
}
|
||||
|
||||
};
|
|
@ -1,209 +0,0 @@
|
|||
/** ElasticTimeIntegrator : a class to implement various elasticity integrators for FE quantities */
|
||||
|
||||
#ifndef ELASTIC_TIME_INTEGRATOR_H
|
||||
#define ELASTIC_TIME_INTEGRATOR_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "TimeIntegrator.h"
|
||||
|
||||
using namespace std;
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class ElasticIntegrationMethod;
|
||||
|
||||
/**
|
||||
* @class ElasticTimeIntegrator
|
||||
* @brief Base class fo various time integrators for elasticity FE quantities
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegrator
|
||||
// Base class for elastic integrators which handles
|
||||
// parsing and stores basic data structures
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ElasticTimeIntegrator : public TimeIntegrator {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ElasticTimeIntegrator(ATC_Transfer * atcTransfer,
|
||||
TimeIntegrationType timeIntegrationType);
|
||||
|
||||
// destructor
|
||||
virtual ~ElasticTimeIntegrator(){};
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ElasticTimeIntegrator();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ElasticIntegrationMethod
|
||||
* @brief Base class fo various time integration methods for elasticity FE quantities
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticIntegrationMethod
|
||||
// Base class for elastic integration methods which
|
||||
// update the FE quantities in time
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ElasticIntegrationMethod : public TimeIntegrationMethod {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ElasticIntegrationMethod(ElasticTimeIntegrator * elasticTimeIntegrator);
|
||||
|
||||
// destructor
|
||||
virtual ~ElasticIntegrationMethod(){};
|
||||
|
||||
protected:
|
||||
|
||||
/** time filtering application object */
|
||||
TimeFilter * timeFilter_;
|
||||
|
||||
/** finite element displacement field */
|
||||
DENS_MAT & displacement_;
|
||||
/** finite element velocity field */
|
||||
DENS_MAT & velocity_;
|
||||
/** finite element acceleration field */
|
||||
DENS_MAT & acceleration_;
|
||||
|
||||
/** atomic nodal displacement field */
|
||||
DENS_MAT & nodalAtomicDisplacement_;
|
||||
/** atomic nodal velocity field */
|
||||
DENS_MAT & nodalAtomicVelocity_;
|
||||
|
||||
/** right-hand side of velocity equation */
|
||||
DENS_MAT & velocityRhs_;
|
||||
|
||||
/** force at nodes from atomic quantities */
|
||||
DENS_MAT & nodalAtomicForce_;
|
||||
|
||||
/** filtered power for computation during equilibration */
|
||||
DENS_MAT & forceFilteringData_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ElasticIntegrationMethod();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ElasticTimeIntegratorVerlet
|
||||
* @brief Verlet integration for FE elastic quantities
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegratorVerlet
|
||||
// Uses the second order Verlet integration to update
|
||||
// the finite element velocity and displacement
|
||||
// fields, i.e. the same integration used for the
|
||||
// atomic velocities and positions.
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ElasticTimeIntegratorVerlet : public ElasticIntegrationMethod {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ElasticTimeIntegratorVerlet(ElasticTimeIntegrator * elasticTimeIntegrator);
|
||||
|
||||
// destructor
|
||||
virtual ~ElasticTimeIntegratorVerlet(){};
|
||||
|
||||
// time step methods, corresponding to ATC_Transfer
|
||||
|
||||
/** first part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate1(double dt);
|
||||
|
||||
/** first part of post_initial_integrate */
|
||||
virtual void post_initial_integrate1(double dt);
|
||||
|
||||
/** first part of pre_final_integrate */
|
||||
virtual void pre_final_integrate1(double dt);
|
||||
|
||||
/** first part of post_final_integrate */
|
||||
virtual void post_final_integrate1(double dt);
|
||||
|
||||
/** post processing step before output */
|
||||
virtual void post_process(double dt);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ElasticTimeIntegratorVerlet();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ElasticTimeIntegratorVerlet
|
||||
* @brief Verlet integration for FE elastic quantities with time filtering
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ElasticTimeIntegratorVerletFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ElasticTimeIntegratorVerletFiltered : public ElasticTimeIntegratorVerlet {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ElasticTimeIntegratorVerletFiltered(ElasticTimeIntegrator * elasticTimeIntegrator);
|
||||
|
||||
// destructor
|
||||
virtual ~ElasticTimeIntegratorVerletFiltered(){};
|
||||
|
||||
// time step methods, corresponding to ATC_Transfer
|
||||
|
||||
/** first part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate1(double dt);
|
||||
|
||||
/** first part of post_initial_integrate */
|
||||
virtual void post_initial_integrate1(double dt);
|
||||
|
||||
/** first part of pre_final_integrate */
|
||||
virtual void pre_final_integrate1(double dt);
|
||||
|
||||
/** first part of post_final_integrate */
|
||||
virtual void post_final_integrate1(double dt);
|
||||
|
||||
/** post processing step before output */
|
||||
virtual void post_process(double dt){};
|
||||
|
||||
protected:
|
||||
|
||||
/** atomic nodal acceleration field */
|
||||
DENS_MAT & nodalAtomicAcceleration_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ElasticTimeIntegratorVerletFiltered();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,66 +0,0 @@
|
|||
#include "ElectronFlux.h"
|
||||
#include "StringManip.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
using namespace ATC_STRING;
|
||||
|
||||
ElectronFluxLinear::ElectronFluxLinear(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronFlux(),
|
||||
electronMobility_(0),
|
||||
electronDiffusivity_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "mobility") {
|
||||
electronMobility_ = value;
|
||||
parameters["electron_mobility"] = electronMobility_;
|
||||
}
|
||||
else if (line[0] == "diffusivity") {
|
||||
electronDiffusivity_ = value;
|
||||
parameters["electron_diffusivity"] = electronDiffusivity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectronFluxThermopower::ElectronFluxThermopower(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronFlux(),
|
||||
electronMobility_(0),
|
||||
seebeckCoef_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "mobility") {
|
||||
electronMobility_ = value;
|
||||
parameters["electron_mobility"] = electronMobility_;
|
||||
}
|
||||
else if (line[0] == "seebeck") {
|
||||
seebeckCoef_ = value;
|
||||
parameters["seebeck_coefficient"] = seebeckCoef_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#ifndef ELECTRON_FLUX_H
|
||||
#define ELECTRON_FLUX_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
namespace ATC {
|
||||
class ElectronFlux
|
||||
{
|
||||
public:
|
||||
ElectronFlux() {};
|
||||
virtual ~ElectronFlux() {};
|
||||
/** computes flux */
|
||||
virtual void electron_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)=0;
|
||||
};
|
||||
//-----------------------------------------------------------------------
|
||||
class ElectronFluxLinear : public ElectronFlux
|
||||
{
|
||||
public:
|
||||
ElectronFluxLinear(fstream &matfile, map<string,double> & parameters);
|
||||
virtual ~ElectronFluxLinear() {};
|
||||
virtual void electron_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)
|
||||
{
|
||||
// J_n = - \mu n grad \phi - D grad n
|
||||
const FIELD & n = (fields.find(ELECTRON_DENSITY))->second;
|
||||
const GRAD_FIELD & dn =(gradFields.find(ELECTRON_DENSITY))->second;
|
||||
const GRAD_FIELD & dphi =(gradFields.find(ELECTRIC_POTENTIAL))->second;
|
||||
// NOTE use electron velocity instead
|
||||
flux.push_back(-electronMobility_*dphi[0]);
|
||||
flux.push_back(-electronMobility_*dphi[1]);
|
||||
flux.push_back(-electronMobility_*dphi[2]);
|
||||
flux[0] *= n; // scale by n to get : -n \mu grad(\phi)
|
||||
flux[1] *= n;
|
||||
flux[2] *= n;
|
||||
flux[0] += -electronDiffusivity_* dn[0];
|
||||
flux[1] += -electronDiffusivity_* dn[1];
|
||||
flux[2] += -electronDiffusivity_* dn[2];
|
||||
};
|
||||
protected:
|
||||
double electronMobility_, electronDiffusivity_;
|
||||
};
|
||||
//-----------------------------------------------------------------------
|
||||
class ElectronFluxThermopower : public ElectronFlux
|
||||
{
|
||||
public:
|
||||
ElectronFluxThermopower(fstream &matfile,map<string,double> & parameters);
|
||||
virtual ~ElectronFluxThermopower() {};
|
||||
virtual void electron_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)
|
||||
{
|
||||
static const double kB_ = 8.617343e-5;// [eV/K]
|
||||
// J_n = - \mu n grad \phi - \mu kB/e T_e grad n
|
||||
// - \mu S n grad T_e - \mu kB/e n grad T_e
|
||||
const FIELD & n = (fields.find(ELECTRON_DENSITY))->second;
|
||||
const GRAD_FIELD & dn =(gradFields.find(ELECTRON_DENSITY))->second;
|
||||
const GRAD_FIELD & dphi =(gradFields.find(ELECTRIC_POTENTIAL))->second;
|
||||
const GRAD_FIELD & dT =(gradFields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux.push_back(-electronMobility_*dphi[0]);
|
||||
flux.push_back(-electronMobility_*dphi[1]);
|
||||
flux.push_back(-electronMobility_*dphi[2]);
|
||||
double coef = -electronMobility_*(seebeckCoef_ + kB_);
|
||||
flux[0] += coef* dT[0];
|
||||
flux[1] += coef* dT[1];
|
||||
flux[2] += coef* dT[2];
|
||||
flux[0] *= n; // scale by n
|
||||
flux[1] *= n;
|
||||
flux[2] *= n;
|
||||
GRAD_FIELD tmp = dn;
|
||||
const FIELD & Te = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
tmp[0] *= Te;
|
||||
tmp[1] *= Te;
|
||||
tmp[2] *= Te;
|
||||
coef = -electronMobility_*kB_; // kB: eV/K/e -> V/K
|
||||
flux[0] += tmp[0];
|
||||
flux[1] += tmp[1];
|
||||
flux[2] += tmp[2];
|
||||
};
|
||||
protected:
|
||||
double electronMobility_, seebeckCoef_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#include "ElectronHeatCapacity.h"
|
||||
#include "StringManip.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
using namespace ATC_STRING;
|
||||
|
||||
ElectronHeatCapacityConstant::ElectronHeatCapacityConstant(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronHeatCapacity(),
|
||||
electronHeatCapacity_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "capacity") {
|
||||
electronHeatCapacity_ = str2dbl(line[1]);
|
||||
parameters["electron_heat_capacity"] = electronHeatCapacity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function:" + line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectronHeatCapacityLinear::ElectronHeatCapacityLinear(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronHeatCapacity(),
|
||||
electronHeatCapacity_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "capacity") {
|
||||
electronHeatCapacity_ = str2dbl(line[1]);
|
||||
parameters["electron_heat_capacity"] = electronHeatCapacity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function: " + line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
#ifndef ELECTRON_HEAT_CAPACITY_H
|
||||
#define ELECTRON_HEAT_CAPACITY_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
namespace ATC {
|
||||
class ElectronHeatCapacity
|
||||
{
|
||||
public:
|
||||
ElectronHeatCapacity() {};
|
||||
virtual ~ElectronHeatCapacity() {};
|
||||
/** computes heat capacity */
|
||||
virtual void electron_heat_capacity(const FIELDS &fields,
|
||||
FIELD &capacity)=0;
|
||||
/** computes thermal energy */
|
||||
virtual void electron_thermal_energy(const FIELDS &fields,
|
||||
FIELD &energy)=0;
|
||||
};
|
||||
//-------------------------------------------------------------------
|
||||
class ElectronHeatCapacityConstant : public ElectronHeatCapacity
|
||||
{
|
||||
public:
|
||||
ElectronHeatCapacityConstant(fstream &matfile,
|
||||
map<string,double> & parameters);
|
||||
virtual ~ElectronHeatCapacityConstant() {};
|
||||
virtual void electron_heat_capacity(const FIELDS &fields,
|
||||
FIELD &capacity)
|
||||
{
|
||||
const FIELD & T = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
capacity.reset(T.nRows(),T.nCols());
|
||||
capacity = electronHeatCapacity_;
|
||||
};
|
||||
virtual void electron_thermal_energy(const FIELDS &fields,
|
||||
FIELD &energy)
|
||||
{
|
||||
const FIELD & T = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
energy = electronHeatCapacity_ * T;
|
||||
};
|
||||
protected:
|
||||
double electronHeatCapacity_;
|
||||
};
|
||||
//-------------------------------------------------------------------
|
||||
class ElectronHeatCapacityLinear : public ElectronHeatCapacity
|
||||
{
|
||||
public:
|
||||
ElectronHeatCapacityLinear(fstream &matfile,
|
||||
map<string,double> & parameters);
|
||||
virtual ~ElectronHeatCapacityLinear() {};
|
||||
virtual void electron_heat_capacity(const FIELDS &fields,
|
||||
FIELD &capacity)
|
||||
{
|
||||
const FIELD & T = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
capacity = electronHeatCapacity_*T;
|
||||
};
|
||||
virtual void electron_thermal_energy(const FIELDS &fields,
|
||||
FIELD &energy)
|
||||
{
|
||||
const FIELD & T = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
energy = 0.5 * electronHeatCapacity_ * T;
|
||||
energy *= T;
|
||||
};
|
||||
protected:
|
||||
double electronHeatCapacity_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#include "ElectronHeatFlux.h"
|
||||
#include "StringManip.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
using namespace ATC_STRING;
|
||||
|
||||
ElectronHeatFluxLinear::ElectronHeatFluxLinear(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronHeatFlux(),
|
||||
conductivity_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "conductivity") {
|
||||
conductivity_ = str2dbl(line[1]);
|
||||
parameters["electron_thermal_conductivity"] = conductivity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectronHeatFluxPowerLaw::ElectronHeatFluxPowerLaw(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronHeatFlux(),
|
||||
conductivity_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "conductivity") {
|
||||
conductivity_ = str2dbl(line[1]);
|
||||
parameters["electron_thermal_conductivity"] = conductivity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectronHeatFluxThermopower::ElectronHeatFluxThermopower(
|
||||
fstream &fileId, map<string,double> & parameters,
|
||||
/*const*/ ElectronFlux * electronFlux)
|
||||
: ElectronHeatFlux(),
|
||||
electronFlux_(electronFlux),
|
||||
conductivity_(0),
|
||||
seebeckCoef_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "conductivity") {
|
||||
conductivity_ = value;
|
||||
parameters["electron_thermal_conductivity"] = conductivity_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
seebeckCoef_ = parameters["seebeck_coefficient"];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
#ifndef ELECTRON_HEAT_FLUX_H
|
||||
#define ELECTRON_HEAT_FLUX_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
#include "ElectronFlux.h"
|
||||
|
||||
namespace ATC {
|
||||
class ElectronHeatFlux
|
||||
{
|
||||
public:
|
||||
ElectronHeatFlux() {};
|
||||
virtual ~ElectronHeatFlux() {};
|
||||
/** computes heat flux */
|
||||
virtual void electron_heat_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)=0;
|
||||
};
|
||||
//-----------------------------------------------------------------------
|
||||
class ElectronHeatFluxLinear : public ElectronHeatFlux
|
||||
{
|
||||
public:
|
||||
ElectronHeatFluxLinear(fstream &matfile,map<string,double> & parameters);
|
||||
virtual ~ElectronHeatFluxLinear() {};
|
||||
virtual void electron_heat_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)
|
||||
{
|
||||
// flux = -ke dTe/dx
|
||||
const GRAD_FIELD& dT = (gradFields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux.push_back(-conductivity_ * dT[0]);
|
||||
flux.push_back(-conductivity_ * dT[1]);
|
||||
flux.push_back(-conductivity_ * dT[2]);
|
||||
};
|
||||
protected:
|
||||
double conductivity_;
|
||||
};
|
||||
//-----------------------------------------------------------------------
|
||||
class ElectronHeatFluxPowerLaw : public ElectronHeatFlux
|
||||
{
|
||||
public:
|
||||
ElectronHeatFluxPowerLaw(fstream &matfile,map<string,double> ¶meters);
|
||||
virtual ~ElectronHeatFluxPowerLaw() {};
|
||||
virtual void electron_heat_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)
|
||||
{
|
||||
// flux = -ke * ( Te / T ) dT;
|
||||
const GRAD_FIELD dT = (gradFields.find(ELECTRON_TEMPERATURE))->second;
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
const FIELD & Te = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux.push_back(dT[0]);
|
||||
flux.push_back(dT[1]);
|
||||
flux.push_back(dT[2]);
|
||||
FIELD k_e;
|
||||
k_e = (-conductivity_* Te) / T;
|
||||
flux[0] *= k_e;
|
||||
flux[1] *= k_e;
|
||||
flux[2] *= k_e;
|
||||
};
|
||||
protected:
|
||||
double conductivity_;
|
||||
};
|
||||
//-----------------------------------------------------------------------
|
||||
class ElectronHeatFluxThermopower : public ElectronHeatFlux
|
||||
{
|
||||
public:
|
||||
ElectronHeatFluxThermopower(fstream &matfile,
|
||||
map<string,double> & parameters,
|
||||
/*const*/ ElectronFlux * electronFlux = NULL);
|
||||
virtual ~ElectronHeatFluxThermopower() {};
|
||||
virtual void electron_heat_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux)
|
||||
{
|
||||
// flux = -ke * ( Te / T ) dT + pi J_e;
|
||||
const GRAD_FIELD dT = (gradFields.find(ELECTRON_TEMPERATURE))->second;
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
const FIELD & Te = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux.push_back(dT[0]);
|
||||
flux.push_back(dT[1]);
|
||||
flux.push_back(dT[2]);
|
||||
FIELD k_e;
|
||||
k_e = (-conductivity_* Te) / T;
|
||||
flux[0] *= k_e;
|
||||
flux[1] *= k_e;
|
||||
flux[2] *= k_e;
|
||||
GRAD_FIELD tmp;
|
||||
electronFlux_->electron_flux(fields, gradFields, tmp);
|
||||
tmp[0] *= Te;
|
||||
tmp[1] *= Te;
|
||||
tmp[2] *= Te;
|
||||
flux[0] += seebeckCoef_*tmp[0];
|
||||
flux[1] += seebeckCoef_*tmp[1];
|
||||
flux[2] += seebeckCoef_*tmp[2];
|
||||
|
||||
};
|
||||
protected:
|
||||
double conductivity_,seebeckCoef_;
|
||||
ElectronFlux * electronFlux_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#include "ElectronPhononExchange.h"
|
||||
#include "StringManip.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
using namespace ATC_STRING;
|
||||
|
||||
ElectronPhononExchangeLinear::ElectronPhononExchangeLinear(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronPhononExchange(),
|
||||
exchangeCoef_(0)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "coefficient") {
|
||||
exchangeCoef_ = str2dbl(line[1]);
|
||||
parameters["electron_phonon_exchange_coefficient"] = exchangeCoef_;
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectronPhononExchangePowerLaw::ElectronPhononExchangePowerLaw(
|
||||
fstream &fileId, map<string,double> & parameters)
|
||||
: ElectronPhononExchange(),
|
||||
exchangeCoef_(0),
|
||||
exponent_(1)
|
||||
{
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") return;
|
||||
else if (line[0] == "coefficient") {
|
||||
exchangeCoef_ = str2dbl(line[1]);
|
||||
parameters["electron_phonon_exchange_coefficient"] = exchangeCoef_;
|
||||
}
|
||||
else if (line[0] == "exponent") {
|
||||
exponent_ = str2int(line[1]);
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#ifndef ELECTRON_PHONON_EXCHANGE_H
|
||||
#define ELECTRON_PHONON_EXCHANGE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
namespace ATC {
|
||||
class ElectronPhononExchange
|
||||
{
|
||||
public:
|
||||
ElectronPhononExchange() {};
|
||||
virtual ~ElectronPhononExchange() {};
|
||||
/** computes heat capacity */
|
||||
virtual void electron_phonon_exchange(const FIELDS &fields,
|
||||
DENS_MAT &flux)=0;
|
||||
};
|
||||
//-------------------------------------------------------------------
|
||||
class ElectronPhononExchangeLinear : public ElectronPhononExchange
|
||||
{
|
||||
public:
|
||||
ElectronPhononExchangeLinear(fstream &matfile,
|
||||
map<string,double> & parameters);
|
||||
virtual ~ElectronPhononExchangeLinear() {};
|
||||
virtual void electron_phonon_exchange(const FIELDS &fields,
|
||||
DENS_MAT &flux)
|
||||
{
|
||||
// flux = g * ( T- Te)
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
const FIELD & Te = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux = Te;
|
||||
flux -= T;
|
||||
flux *= exchangeCoef_;
|
||||
};
|
||||
protected:
|
||||
double exchangeCoef_;
|
||||
};
|
||||
//-------------------------------------------------------------------
|
||||
class ElectronPhononExchangePowerLaw : public ElectronPhononExchange
|
||||
{
|
||||
public:
|
||||
ElectronPhononExchangePowerLaw(fstream &matfile,
|
||||
map<string,double> & parameters);
|
||||
virtual ~ElectronPhononExchangePowerLaw() {};
|
||||
virtual void electron_phonon_exchange(const FIELDS &fields,
|
||||
DENS_MAT &flux)
|
||||
{
|
||||
// flux = g c_e T_e (T_e - T_p)^5 / T_e
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
const FIELD & Te = (fields.find(ELECTRON_TEMPERATURE))->second;
|
||||
flux = Te;
|
||||
flux -= T;
|
||||
flux = flux.pow(exponent_);
|
||||
flux *= exchangeCoef_;
|
||||
};
|
||||
protected:
|
||||
double exchangeCoef_;
|
||||
int exponent_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
// ATC_Transfer Headers
|
||||
#include "ExtrinsicModel.h"
|
||||
#include "ExtrinsicModelTwoTemperature.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "TimeIntegrator.h"
|
||||
#include "ATC_Transfer.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "PrescribedDataManager.h"
|
||||
#include "PhysicsModel.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModelManager
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModelManager::ExtrinsicModelManager(ATC_Transfer * atcTransfer) :
|
||||
atcTransfer_(atcTransfer)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModelManager::~ExtrinsicModelManager()
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
delete *(imodel);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// modify
|
||||
//--------------------------------------------------------
|
||||
bool ExtrinsicModelManager::modify(int narg, char **arg)
|
||||
{
|
||||
FieldName thisField;
|
||||
int thisIndex;
|
||||
int argIndx = 0;
|
||||
|
||||
bool foundMatch = false;
|
||||
|
||||
// loop over models with command
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin();
|
||||
imodel!=extrinsicModels_.end(); imodel++) {
|
||||
foundMatch = (*imodel)->modify(narg,arg);
|
||||
if (foundMatch) break;
|
||||
}
|
||||
|
||||
return foundMatch;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// create_model
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::create_model(ExtrinsicModelType modelType,
|
||||
string matFileName)
|
||||
{
|
||||
string typeName;
|
||||
bool validModel = model_to_string(modelType,typeName);
|
||||
if (!validModel) {
|
||||
throw ATC_Error(0,"Could not create extrinsic model");
|
||||
return;
|
||||
}
|
||||
ExtrinsicModel * myModel;
|
||||
if (modelType==TWO_TEMPERATURE) {
|
||||
cout << "ATC: creating two_temperature extrinsic model \n";
|
||||
myModel = new ExtrinsicModelTwoTemperature
|
||||
(this,modelType,matFileName);
|
||||
}
|
||||
extrinsicModels_.push_back(myModel);
|
||||
|
||||
// add new fields to fields data
|
||||
map<FieldName,int> fieldSizes;
|
||||
myModel->get_num_fields(fieldSizes);
|
||||
atcTransfer_->add_fields(fieldSizes);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::initialize()
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin();
|
||||
imodel!=extrinsicModels_.end(); imodel++) {
|
||||
// initialize models
|
||||
(*imodel)->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// size_vector
|
||||
//--------------------------------------------------------
|
||||
int ExtrinsicModelManager::size_vector(int intrinsicSize)
|
||||
{
|
||||
int extrinsicSize = 0;
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin();
|
||||
imodel!=extrinsicModels_.end(); imodel++) {
|
||||
// query all models for LAMMPS display
|
||||
int currentSize = intrinsicSize + extrinsicSize;
|
||||
extrinsicSize += (*imodel)->size_vector(currentSize);
|
||||
}
|
||||
|
||||
return extrinsicSize;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// compute_vector
|
||||
//--------------------------------------------------------
|
||||
double ExtrinsicModelManager::compute_vector(int n)
|
||||
{
|
||||
double value = 0.;
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin();
|
||||
imodel!=extrinsicModels_.end(); imodel++) {
|
||||
// query all models for LAMMPS display
|
||||
if ((*imodel)->compute_vector(n,value))
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// finish
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::finish()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_init_integrate
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::pre_init_integrate(ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->pre_init_integrate();
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->pre_init_integrate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// mid_init_integrate
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::mid_init_integrate(ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->mid_init_integrate();
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->mid_init_integrate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_init_integrate
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::post_init_integrate(ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->post_init_integrate();
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->post_init_integrate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_final_integrate
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::pre_final_integrate(ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->pre_final_integrate();
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->pre_final_integrate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_final_integrate
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::post_final_integrate(ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->post_final_integrate();
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->post_final_integrate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// set_sources
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::set_sources(FIELDS & fields, FIELDS & sources, ExtrinsicModelType modelType)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
if (modelType == NUM_MODELS) {// execute all the models
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->set_sources(fields,sources);
|
||||
}
|
||||
else { // execute only requested type of model
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
if ((*imodel)->get_model_type() == modelType)
|
||||
(*imodel)->set_sources(fields,sources);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// output
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelManager::output(double dt,OUTPUT_LIST & outputData)
|
||||
{
|
||||
vector<ExtrinsicModel *>::iterator imodel;
|
||||
for(imodel=extrinsicModels_.begin(); imodel!=extrinsicModels_.end(); imodel++)
|
||||
(*imodel)->output(dt,outputData);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModel
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModel::ExtrinsicModel(ExtrinsicModelManager * modelManager,
|
||||
ExtrinsicModelType modelType,
|
||||
string matFileName) :
|
||||
modelManager_(modelManager),
|
||||
modelType_(modelType),
|
||||
atc_(modelManager->get_atc_transfer()),
|
||||
physicsModel_(NULL)
|
||||
{
|
||||
rhsMaskIntrinsic_.reset(NUM_FIELDS,NUM_FLUX);
|
||||
rhsMaskIntrinsic_ = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModel::~ExtrinsicModel()
|
||||
{
|
||||
if (physicsModel_) delete physicsModel_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// get_num_fields
|
||||
// - sets dict of fields
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModel::get_num_fields(map<FieldName,int> & fieldSizes)
|
||||
{
|
||||
physicsModel_->get_num_fields(fieldSizes,atc_->fieldMask_); // NOTE clunky
|
||||
}
|
||||
|
||||
};
|
|
@ -1,228 +0,0 @@
|
|||
#ifndef EXTRINSIC_MODEL
|
||||
#define EXTRINSIC_MODEL
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
using namespace std;
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class ATC_Transfer;
|
||||
class ExtrinsicModel;
|
||||
class PhysicsModel;
|
||||
|
||||
/** enumeration for the model types avaiable */
|
||||
enum ExtrinsicModelType {
|
||||
NO_MODEL=0,
|
||||
TWO_TEMPERATURE,
|
||||
NUM_MODELS
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ExtrinsicModelManager
|
||||
* @brief Handles parsing and parameter storage extrinsic models
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModelManager
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ExtrinsicModelManager {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ExtrinsicModelManager(ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
~ExtrinsicModelManager();
|
||||
|
||||
/** parser/modifier */
|
||||
bool modify(int narg, char **arg);
|
||||
|
||||
/** create_model */
|
||||
void create_model(ExtrinsicModelType modelType, string matFileName);
|
||||
|
||||
/** pre time integration */
|
||||
void initialize();
|
||||
|
||||
/** set up LAMMPS display variables */
|
||||
int size_vector(int intrinsicSize);
|
||||
|
||||
/** get LAMMPS display variables */
|
||||
double compute_vector(int n);
|
||||
|
||||
/** post integration run */
|
||||
// is this called at end of run or simulation
|
||||
void finish();
|
||||
|
||||
// calls during LAMMPS Velocity-Verlet integration
|
||||
/** Predictor phase, executed before Verlet */
|
||||
void pre_init_integrate(ExtrinsicModelType modelType = NUM_MODELS);
|
||||
/** Predictor phase, executed between velocity and position Verlet */
|
||||
void mid_init_integrate(ExtrinsicModelType modelType = NUM_MODELS);
|
||||
/** Predictor phase, executed after Verlet */
|
||||
void post_init_integrate(ExtrinsicModelType modelType = NUM_MODELS);
|
||||
/** Corrector phase, executed before Verlet */
|
||||
void pre_final_integrate(ExtrinsicModelType modelType = NUM_MODELS);
|
||||
/** Corrector phase, executed after Verlet*/
|
||||
void post_final_integrate(ExtrinsicModelType modelType = NUM_MODELS);
|
||||
|
||||
/** get source terms for AtC equations */
|
||||
void set_sources(FIELDS & fields, FIELDS & sources,
|
||||
ExtrinsicModelType modelType = NUM_MODELS);
|
||||
|
||||
/** return output data to main AtC */
|
||||
void output(double dt,OUTPUT_LIST & outputData);
|
||||
|
||||
/** model name enum to string */
|
||||
static bool model_to_string(const ExtrinsicModelType index, string & name)
|
||||
{
|
||||
switch (index) {
|
||||
case NO_MODEL:
|
||||
name = "no_model";
|
||||
break;
|
||||
case TWO_TEMPERATURE:
|
||||
name = "two_temperature";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/** string to model enum */
|
||||
static bool string_to_model(const string & name, ExtrinsicModelType & index)
|
||||
{
|
||||
if (name=="no_model")
|
||||
index = NO_MODEL;
|
||||
else if (name=="two_temperature")
|
||||
index = TWO_TEMPERATURE;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/** access to ATC transfer object */
|
||||
ATC_Transfer * get_atc_transfer() {return atcTransfer_;};
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/** associated ATC_Transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** equation hanlder */
|
||||
vector<ExtrinsicModel *> extrinsicModels_;
|
||||
|
||||
private:
|
||||
ExtrinsicModelManager(); // DO NOT define this, only use constructor above
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ExtrinsicModel
|
||||
* @brief base class for functionality of all extrinsic models
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModel
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ExtrinsicModel {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ExtrinsicModel(ExtrinsicModelManager * modelManager,
|
||||
ExtrinsicModelType modelType,
|
||||
string matFileName);
|
||||
|
||||
// destructor
|
||||
virtual ~ExtrinsicModel();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg) {return false;};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(){};
|
||||
|
||||
/** set up LAMMPS display variables */
|
||||
virtual int size_vector(int externalSize) {return 0;};
|
||||
|
||||
/** get LAMMPS display variables */
|
||||
virtual bool compute_vector(int n, double & value) {return false;};
|
||||
|
||||
/** post integration run */
|
||||
// is this called at end of run or simulation
|
||||
virtual void finish(){};
|
||||
|
||||
/** Predictor phase, executed before Verlet */
|
||||
virtual void pre_init_integrate(){};
|
||||
|
||||
/** Predictor phase, executed between velocity and position Verlet */
|
||||
virtual void mid_init_integrate(){};
|
||||
|
||||
/** Predictor phase, executed after Verlet */
|
||||
virtual void post_init_integrate(){};
|
||||
|
||||
/** Corrector phase, executed before Verlet */
|
||||
virtual void pre_final_integrate(){};
|
||||
|
||||
/** Corrector phase, Verlet second step for velocity */
|
||||
virtual void final_integrate(){};
|
||||
|
||||
/** Corrector phase, executed after Verlet*/
|
||||
virtual void post_final_integrate(){};
|
||||
|
||||
/** Set sources to AtC equation */
|
||||
virtual void set_sources(FIELDS & fields, FIELDS & sources){};
|
||||
|
||||
/** Add model-specific output data */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData){};
|
||||
|
||||
/** get the fields and their sizes */
|
||||
void get_num_fields(map<FieldName,int> & fieldSizes);
|
||||
|
||||
/** return the type of model being used */
|
||||
ExtrinsicModelType get_model_type() {return modelType_;};
|
||||
|
||||
protected:
|
||||
|
||||
ExtrinsicModel(){};
|
||||
|
||||
/** ATC transfer object */
|
||||
ATC_Transfer * atc_;
|
||||
|
||||
/** model manager object */
|
||||
ExtrinsicModelManager * modelManager_;
|
||||
|
||||
/** tag for model type */
|
||||
ExtrinsicModelType modelType_;
|
||||
|
||||
/** list of model fields in this model */
|
||||
std::map<FieldName, int> fieldSizes_;
|
||||
|
||||
/** definition for physics used in this model */
|
||||
PhysicsModel * physicsModel_;
|
||||
|
||||
/** rhs */
|
||||
FIELDS rhs_;
|
||||
|
||||
/** rhs mask for coupling with MD */
|
||||
Array2D<bool> rhsMaskIntrinsic_;
|
||||
|
||||
GRAD_FIELDS fluxes_;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,265 +0,0 @@
|
|||
// ATC_Transfer Headers
|
||||
#include "ExtrinsicModelTwoTemperature.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "FieldEulerIntegrator.h"
|
||||
#include "ATC_Transfer.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "PrescribedDataManager.h"
|
||||
#include "PhysicsModelTwoTemperature.h"
|
||||
#include "ImplicitSolveOperator.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModelTwoTemperature
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModelTwoTemperature::ExtrinsicModelTwoTemperature
|
||||
(ExtrinsicModelManager * modelManager,
|
||||
ExtrinsicModelType modelType,
|
||||
string matFileName) :
|
||||
ExtrinsicModel(modelManager,modelType,matFileName),
|
||||
nsubcycle_(1),
|
||||
electronTimeIntegration_(TimeIntegrator::IMPLICIT),
|
||||
temperatureIntegrator_(NULL),
|
||||
exchangeFlag_(true),
|
||||
baseSize_(0)
|
||||
{
|
||||
physicsModel_ = new PhysicsModelTwoTemperature(matFileName,
|
||||
modelManager->get_atc_transfer());
|
||||
|
||||
// set up correct masks for coupling
|
||||
rhsMaskIntrinsic_.reset(NUM_FIELDS,NUM_FLUX);
|
||||
rhsMaskIntrinsic_ = false;
|
||||
rhsMaskIntrinsic_(TEMPERATURE,SOURCE) = true;
|
||||
atc_->fieldMask_(TEMPERATURE,EXTRINSIC_SOURCE) = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
ExtrinsicModelTwoTemperature::~ExtrinsicModelTwoTemperature()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// modify
|
||||
//--------------------------------------------------------
|
||||
bool ExtrinsicModelTwoTemperature::modify(int narg, char **arg)
|
||||
{
|
||||
bool match = false;
|
||||
int argIndx = 0;
|
||||
|
||||
// energy exchange switch
|
||||
/*! \page man_extrinsic_exchange fix_modify AtC extrinsic exchange
|
||||
\section syntax
|
||||
fix_modify AtC extrinsic exchange <on|off>
|
||||
|
||||
\section examples
|
||||
<TT> fix_modify AtC extrinsic exchange on </TT> \n
|
||||
|
||||
\section description
|
||||
Switches energy exchange between the MD system and electron system on and off
|
||||
|
||||
\section restrictions
|
||||
Only valid for use with two_temperature type of AtC fix.
|
||||
|
||||
\section related
|
||||
see \ref man_fix_atc
|
||||
|
||||
\section default
|
||||
on
|
||||
*/
|
||||
if (strcmp(arg[argIndx],"exchange")==0) {
|
||||
argIndx++;
|
||||
if (strcmp(arg[argIndx],"off")==0) {
|
||||
exchangeFlag_ = false;
|
||||
rhsMaskIntrinsic_(TEMPERATURE,SOURCE) = false;
|
||||
atc_->fieldMask_(ELECTRON_TEMPERATURE,SOURCE) = false;
|
||||
atc_->fieldMask_(TEMPERATURE,EXTRINSIC_SOURCE) = false;
|
||||
}
|
||||
else {
|
||||
exchangeFlag_ = true;
|
||||
rhsMaskIntrinsic_(TEMPERATURE,SOURCE) = true;
|
||||
atc_->fieldMask_(ELECTRON_TEMPERATURE,SOURCE) = true;
|
||||
atc_->fieldMask_(TEMPERATURE,EXTRINSIC_SOURCE) = true;
|
||||
}
|
||||
match = true;
|
||||
} // end "exchange"
|
||||
|
||||
// electron integration type
|
||||
/*! \page man_electron_integration fix_modify AtC extrinsic electron_integration
|
||||
\section syntax
|
||||
fix_modify AtC extrinsic electron_integration <integration_type> <num_subcyle_steps(optional)> \n
|
||||
- integration_type (string) = explicit | implicit | steady \n
|
||||
- num_subcycle_steps (int), optional = number of subcycle steps for the electron time integration
|
||||
|
||||
\section examples
|
||||
<TT> fix_modify AtC extrinsic electron_integration implicit </TT> \n
|
||||
<TT> fix_modify AtC extrinsic electron_integration explicit 100 </TT> \n
|
||||
|
||||
\section description
|
||||
Switches between integration scheme for the electron temperature. The number of subcyling steps used to integrate the electron temperature 1 LAMMPS timestep can be manually adjusted to capture fast electron dynamics.
|
||||
|
||||
\section restrictions
|
||||
For use only with two_temperature type of AtC fix ( see \ref man_fix_atc ) \n
|
||||
\section default
|
||||
implicit\n
|
||||
subcycle_steps = 1
|
||||
*/
|
||||
else if (strcmp(arg[argIndx],"electron_integration")==0) {
|
||||
argIndx++;
|
||||
nsubcycle_ = 1;
|
||||
if (strcmp(arg[argIndx],"explicit")==0) {
|
||||
electronTimeIntegration_ = TimeIntegrator::EXPLICIT;
|
||||
match = true;
|
||||
}
|
||||
else if (strcmp(arg[argIndx],"implicit")==0) {
|
||||
electronTimeIntegration_ = TimeIntegrator::IMPLICIT;
|
||||
match = true;
|
||||
}
|
||||
else if (strcmp(arg[argIndx],"steady")==0) {
|
||||
electronTimeIntegration_ = TimeIntegrator::STEADY;
|
||||
match = true;
|
||||
}
|
||||
if (narg > ++argIndx) nsubcycle_ = atoi(arg[argIndx]);
|
||||
} // end "electron_integration"
|
||||
|
||||
if (!match) {
|
||||
match = ExtrinsicModel::modify(narg, arg);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelTwoTemperature::initialize()
|
||||
{
|
||||
int nNodes = atc_->get_fe_engine()->get_nNodes();
|
||||
rhs_[TEMPERATURE].reset(nNodes,1);
|
||||
rhs_[ELECTRON_TEMPERATURE].reset(nNodes,1);
|
||||
|
||||
// set up electron temperature integrator
|
||||
Array2D <bool> rhsMask(NUM_FIELDS,NUM_FLUX);
|
||||
rhsMask = false;
|
||||
for (int i = 0; i < NUM_FLUX; i++) {
|
||||
rhsMask(ELECTRON_TEMPERATURE,i) = atc_->fieldMask_(ELECTRON_TEMPERATURE,i);
|
||||
}
|
||||
if (temperatureIntegrator_) delete temperatureIntegrator_;
|
||||
if (electronTimeIntegration_ == TimeIntegrator::STEADY) {
|
||||
throw ATC_Error(0,"not implemented");
|
||||
}
|
||||
else if (electronTimeIntegration_ == TimeIntegrator::IMPLICIT) {
|
||||
double alpha = 1; // backwards Euler
|
||||
temperatureIntegrator_ = new FieldImplicitEulerIntegrator(
|
||||
ELECTRON_TEMPERATURE, physicsModel_, atc_->get_fe_engine(), atc_,
|
||||
rhsMask, alpha);
|
||||
}
|
||||
else {
|
||||
temperatureIntegrator_ = new FieldExplicitEulerIntegrator(
|
||||
ELECTRON_TEMPERATURE, physicsModel_, atc_->get_fe_engine(), atc_,
|
||||
rhsMask);
|
||||
}
|
||||
|
||||
// set up mass matrix
|
||||
Array<FieldName> massMask(1);
|
||||
massMask = ELECTRON_TEMPERATURE;
|
||||
(atc_->feEngine_)->compute_lumped_mass_matrix(massMask,atc_->fields_,physicsModel_,atc_->elementToMaterialMap_,atc_->massMats_);
|
||||
atc_->massMatInv_[ELECTRON_TEMPERATURE] = inv(atc_->massMats_[ELECTRON_TEMPERATURE]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre initial integration
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelTwoTemperature::pre_init_integrate()
|
||||
{
|
||||
double dt = atc_->lammpsInterface_->dt();
|
||||
double time = atc_->simTime_;
|
||||
|
||||
// integrate fast electron variable/s
|
||||
// note: atc calls set_sources in pre_final_integrate
|
||||
atc_->set_fixed_nodes();
|
||||
double idt = dt/nsubcycle_;
|
||||
for (int i = 0; i < nsubcycle_ ; ++i) {
|
||||
temperatureIntegrator_->update(idt,time,atc_->fields_,rhs_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// set coupling source terms
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelTwoTemperature::set_sources(FIELDS & fields, FIELDS & sources)
|
||||
{
|
||||
// compute source term with appropriate masking and physics model
|
||||
atc_->evaluate_rhs_integral(rhsMaskIntrinsic_, fields,
|
||||
sources,
|
||||
atc_->FULL_DOMAIN, physicsModel_);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// output
|
||||
//--------------------------------------------------------
|
||||
void ExtrinsicModelTwoTemperature::output(double dt, OUTPUT_LIST & outputData)
|
||||
{
|
||||
// nodal data
|
||||
outputData["dot_electron_temperature"]
|
||||
= & rhs_[ELECTRON_TEMPERATURE];
|
||||
// global data
|
||||
if (atc_->lammpsInterface_->comm_rank() == 0) {
|
||||
double T_mean = atc_->fields_[ELECTRON_TEMPERATURE].col_sum(0)/atc_->nNodes_;
|
||||
atc_->feEngine_->add_global("electron_temperature_mean", T_mean);
|
||||
double T_stddev = atc_->fields_[ELECTRON_TEMPERATURE].col_stdev(0);
|
||||
atc_->feEngine_->add_global("electron_temperature_std_dev", T_stddev);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// size_vector
|
||||
//--------------------------------------------------------
|
||||
int ExtrinsicModelTwoTemperature::size_vector(int intrinsicSize)
|
||||
{
|
||||
baseSize_ = intrinsicSize;
|
||||
return 2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// compute_vector
|
||||
//--------------------------------------------------------
|
||||
bool ExtrinsicModelTwoTemperature::compute_vector(int n, double & value)
|
||||
{
|
||||
// output[1] = total electron energy
|
||||
// output[2] = average electron temperature
|
||||
|
||||
if (n == baseSize_) {
|
||||
Array<FieldName> mask(1);
|
||||
FIELDS energy;
|
||||
mask(0) = ELECTRON_TEMPERATURE;
|
||||
(atc_->feEngine_)->compute_energy(mask,
|
||||
atc_->fields_,
|
||||
physicsModel_,
|
||||
atc_->elementToMaterialMap_,
|
||||
energy);
|
||||
// convert to lammps energy units
|
||||
double mvv2e = (atc_->lammpsInterface_)->mvv2e();
|
||||
double electronEnergy = mvv2e * energy[ELECTRON_TEMPERATURE].col_sum();
|
||||
value = electronEnergy;
|
||||
return true;
|
||||
}
|
||||
else if (n == baseSize_+1) {
|
||||
double electronTemperature = (atc_->fields_[ELECTRON_TEMPERATURE]).col_sum()/(atc_->nNodes_);
|
||||
value = electronTemperature;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
|
@ -1,82 +0,0 @@
|
|||
#ifndef EXTRINSIC_MODEL_TWO_TEMPERATURE
|
||||
#define EXTRINSIC_MODEL_TWO_TEMPERATURE
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
#include "ExtrinsicModel.h"
|
||||
#include "FieldEulerIntegrator.h"
|
||||
|
||||
using namespace std;
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class ATC_Transfer;
|
||||
class PrescribedDataManager;
|
||||
class ExtrinsicModel;
|
||||
class PhysicsModel;
|
||||
|
||||
/**
|
||||
* @class ExtrinsicModelTwoTemperature
|
||||
* @brief add electron temperature physics to phonon physics
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ExtrinsicModelTwoTemperature
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ExtrinsicModelTwoTemperature : public ExtrinsicModel {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
ExtrinsicModelTwoTemperature(ExtrinsicModelManager * modelManager,
|
||||
ExtrinsicModelType modelType,
|
||||
string matFileName);
|
||||
|
||||
// destructor
|
||||
virtual ~ExtrinsicModelTwoTemperature();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
/** set up LAMMPS display variables */
|
||||
virtual int size_vector(int externalSize);
|
||||
|
||||
/** get LAMMPS display variables */
|
||||
virtual bool compute_vector(int n, double & value);
|
||||
|
||||
/** Predictor phase, executed before Verlet */
|
||||
virtual void pre_init_integrate();
|
||||
|
||||
/** Set sources to AtC equation */
|
||||
virtual void set_sources(FIELDS & fields, FIELDS & sources);
|
||||
|
||||
/** Add model-specific output data */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
/** electron time integration flag */
|
||||
TimeIntegrator::TimeIntegrationType electronTimeIntegration_;
|
||||
|
||||
/** electron time integration flag */
|
||||
FieldEulerIntegrator * temperatureIntegrator_;
|
||||
|
||||
/** number of electron time integration subscycles */
|
||||
int nsubcycle_;
|
||||
|
||||
/** flag for turning off exchange during equilibration */
|
||||
bool exchangeFlag_;
|
||||
|
||||
/** offset/size for LAMMPS display output */
|
||||
int baseSize_;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,515 +0,0 @@
|
|||
// ATC header files
|
||||
#include "ATC_Error.h"
|
||||
#include "FE_Element.h"
|
||||
#include "FE_Mesh.h"
|
||||
|
||||
// Other headers
|
||||
#include "math.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// -------------------------------------------------------------
|
||||
// class FE_Element
|
||||
// -------------------------------------------------------------
|
||||
// -------------------------------------------------------------
|
||||
|
||||
FE_Element::FE_Element(FE_Mesh * feMesh,
|
||||
int nSD,
|
||||
int numEltNodes,
|
||||
int numIPs,
|
||||
int numFaces,
|
||||
int numFaceNodes,
|
||||
int numFaceIPs)
|
||||
: feMesh_(feMesh),
|
||||
nSD_(nSD),
|
||||
numEltNodes_(numEltNodes),
|
||||
numIPs_(numIPs),
|
||||
numFaces_(numFaces),
|
||||
numFaceNodes_(numFaceNodes),
|
||||
numFaceIPs_(numFaceIPs),
|
||||
localCoords_(nSD,numEltNodes),
|
||||
ipCoords_(nSD,numIPs),
|
||||
N_(numIPs,numEltNodes),
|
||||
ipWeights_(numIPs),
|
||||
localFaceConn_(numFaces,numFaceNodes),
|
||||
ipFace2DCoords_(nSD-1,numFaceIPs),
|
||||
ipFaceCoords_(numFaces),
|
||||
// localFaceCoords_(nSD-1,numFaceNodes),
|
||||
NFace_(numFaces),
|
||||
ipFaceWeights_(numFaceIPs)
|
||||
{
|
||||
for (int f = 0; f < numFaces; f++) {
|
||||
ipFaceCoords_[f].reset(nSD,numFaceIPs);
|
||||
NFace_[f].reset(numFaceIPs,numEltNodes);
|
||||
}
|
||||
}
|
||||
|
||||
FE_Element::~FE_Element()
|
||||
{
|
||||
// Nothing else to do
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// -------------------------------------------------------------
|
||||
// class FE_ElementHex
|
||||
// -------------------------------------------------------------
|
||||
// -------------------------------------------------------------
|
||||
|
||||
FE_ElementHex::FE_ElementHex(FE_Mesh * feMesh)
|
||||
: FE_Element(feMesh, 3, 8, 8, 6, 4, 4)
|
||||
{
|
||||
|
||||
// Matrix of local nodal coordinates
|
||||
localCoords_(0,0) = -1; localCoords_(1,0) = -1; localCoords_(2,0) = -1;
|
||||
localCoords_(0,1) = +1; localCoords_(1,1) = -1; localCoords_(2,1) = -1;
|
||||
localCoords_(0,2) = +1; localCoords_(1,2) = +1; localCoords_(2,2) = -1;
|
||||
localCoords_(0,3) = -1; localCoords_(1,3) = +1; localCoords_(2,3) = -1;
|
||||
localCoords_(0,4) = -1; localCoords_(1,4) = -1; localCoords_(2,4) = +1;
|
||||
localCoords_(0,5) = +1; localCoords_(1,5) = -1; localCoords_(2,5) = +1;
|
||||
localCoords_(0,6) = +1; localCoords_(1,6) = +1; localCoords_(2,6) = +1;
|
||||
localCoords_(0,7) = -1; localCoords_(1,7) = +1; localCoords_(2,7) = +1;
|
||||
|
||||
|
||||
// 3 --- 2
|
||||
// /| /|
|
||||
// / 0 --/ 1 y
|
||||
// 7 --- 6 / |
|
||||
// | |/ |
|
||||
// 4 --- 5 ---> x
|
||||
// /
|
||||
// /
|
||||
// z
|
||||
|
||||
// Matrix of local face connectivity
|
||||
// -x
|
||||
localFaceConn_(0,0) = 0;
|
||||
localFaceConn_(0,1) = 4;
|
||||
localFaceConn_(0,2) = 7;
|
||||
localFaceConn_(0,3) = 3;
|
||||
|
||||
// +x
|
||||
localFaceConn_(1,0) = 1;
|
||||
localFaceConn_(1,1) = 2;
|
||||
localFaceConn_(1,2) = 6;
|
||||
localFaceConn_(1,3) = 5;
|
||||
|
||||
// -y
|
||||
localFaceConn_(2,0) = 0;
|
||||
localFaceConn_(2,1) = 1;
|
||||
localFaceConn_(2,2) = 5;
|
||||
localFaceConn_(2,3) = 4;
|
||||
|
||||
// +y
|
||||
localFaceConn_(3,0) = 2;
|
||||
localFaceConn_(3,1) = 3;
|
||||
localFaceConn_(3,2) = 7;
|
||||
localFaceConn_(3,3) = 6;
|
||||
|
||||
// -z
|
||||
localFaceConn_(4,0) = 0;
|
||||
localFaceConn_(4,1) = 3;
|
||||
localFaceConn_(4,2) = 2;
|
||||
localFaceConn_(4,3) = 1;
|
||||
|
||||
// +z
|
||||
localFaceConn_(5,0) = 4;
|
||||
localFaceConn_(5,1) = 5;
|
||||
localFaceConn_(5,2) = 6;
|
||||
localFaceConn_(5,3) = 7;
|
||||
|
||||
/*
|
||||
localFaceCoords_(0,0) = -1; localFaceCoords_(1,0) = -1;
|
||||
localFaceCoords_(0,1) = +1; localFaceCoords_(1,1) = -1;
|
||||
localFaceCoords_(0,2) = +1; localFaceCoords_(1,2) = +1;
|
||||
localFaceCoords_(0,3) = -1; localFaceCoords_(1,3) = +1;
|
||||
*/
|
||||
|
||||
set_quadrature(GAUSSIAN_QUADRATURE);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void FE_ElementHex::set_quadrature(int quadrature)
|
||||
{
|
||||
double a = 1./sqrt(3.);
|
||||
if (quadrature == NODAL_QUADRATURE) {
|
||||
a = 1.0;
|
||||
}
|
||||
// Matrix of integration point locations (Gaussian) & follows local conn
|
||||
ipCoords_(0,0) = -a; ipCoords_(1,0) = -a; ipCoords_(2,0) = -a;
|
||||
ipCoords_(0,1) = +a; ipCoords_(1,1) = -a; ipCoords_(2,1) = -a;
|
||||
ipCoords_(0,2) = +a; ipCoords_(1,2) = +a; ipCoords_(2,2) = -a;
|
||||
ipCoords_(0,3) = -a; ipCoords_(1,3) = +a; ipCoords_(2,3) = -a;
|
||||
ipCoords_(0,4) = -a; ipCoords_(1,4) = -a; ipCoords_(2,4) = +a;
|
||||
ipCoords_(0,5) = +a; ipCoords_(1,5) = -a; ipCoords_(2,5) = +a;
|
||||
ipCoords_(0,6) = +a; ipCoords_(1,6) = +a; ipCoords_(2,6) = +a;
|
||||
ipCoords_(0,7) = -a; ipCoords_(1,7) = +a; ipCoords_(2,7) = +a;
|
||||
|
||||
// Compute shape functions at ip's
|
||||
for (int ip = 0; ip < numIPs_; ip++) {
|
||||
double r = ipCoords_(0, ip);
|
||||
double s = ipCoords_(1, ip);
|
||||
double t = ipCoords_(2, ip);
|
||||
for (int iNode = 0; iNode < numEltNodes_; iNode++) {
|
||||
double rI = localCoords_(0, iNode);
|
||||
double sI = localCoords_(1, iNode);
|
||||
double tI = localCoords_(2, iNode);
|
||||
N_(ip, iNode) = 0.125 * (1 + r*rI) * (1 + s*sI) * (1 + t*tI);
|
||||
}
|
||||
}
|
||||
|
||||
// Integration point weights
|
||||
ipWeights_ = 1.0;
|
||||
|
||||
// integration points by face
|
||||
ipFace2DCoords_(0,0)=-a; ipFace2DCoords_(1,0)=-a;
|
||||
ipFace2DCoords_(0,1)= a; ipFace2DCoords_(1,1)=-a;
|
||||
ipFace2DCoords_(0,2)= a; ipFace2DCoords_(1,2)= a;
|
||||
ipFace2DCoords_(0,3)=-a; ipFace2DCoords_(1,3)= a;
|
||||
|
||||
ipFaceCoords_[0](0,0)=-1;ipFaceCoords_[0](1,0)=-a;ipFaceCoords_[0](2,0)=-a;
|
||||
ipFaceCoords_[0](0,1)=-1;ipFaceCoords_[0](1,1)= a;ipFaceCoords_[0](2,1)=-a;
|
||||
ipFaceCoords_[0](0,2)=-1;ipFaceCoords_[0](1,2)= a;ipFaceCoords_[0](2,2)= a;
|
||||
ipFaceCoords_[0](0,3)=-1;ipFaceCoords_[0](1,3)=-a;ipFaceCoords_[0](2,3)= a;
|
||||
|
||||
ipFaceCoords_[1](0,0)= 1;ipFaceCoords_[1](1,0)=-a;ipFaceCoords_[1](2,0)=-a;
|
||||
ipFaceCoords_[1](0,1)= 1;ipFaceCoords_[1](1,1)= a;ipFaceCoords_[1](2,1)=-a;
|
||||
ipFaceCoords_[1](0,2)= 1;ipFaceCoords_[1](1,2)= a;ipFaceCoords_[1](2,2)= a;
|
||||
ipFaceCoords_[1](0,3)= 1;ipFaceCoords_[1](1,3)=-a;ipFaceCoords_[1](2,3)= a;
|
||||
|
||||
ipFaceCoords_[2](0,0)=-a;ipFaceCoords_[2](1,0)=-1;ipFaceCoords_[2](2,0)=-a;
|
||||
ipFaceCoords_[2](0,1)=-a;ipFaceCoords_[2](1,1)=-1;ipFaceCoords_[2](2,1)= a;
|
||||
ipFaceCoords_[2](0,2)= a;ipFaceCoords_[2](1,2)=-1;ipFaceCoords_[2](2,2)= a;
|
||||
ipFaceCoords_[2](0,3)= a;ipFaceCoords_[2](1,3)=-1;ipFaceCoords_[2](2,3)=-a;
|
||||
|
||||
ipFaceCoords_[3](0,0)=-a;ipFaceCoords_[3](1,0)= 1;ipFaceCoords_[3](2,0)=-a;
|
||||
ipFaceCoords_[3](0,1)=-a;ipFaceCoords_[3](1,1)= 1;ipFaceCoords_[3](2,1)= a;
|
||||
ipFaceCoords_[3](0,2)= a;ipFaceCoords_[3](1,2)= 1;ipFaceCoords_[3](2,2)= a;
|
||||
ipFaceCoords_[3](0,3)= a;ipFaceCoords_[3](1,3)= 1;ipFaceCoords_[2](2,3)=-a;
|
||||
|
||||
ipFaceCoords_[4](0,0)=-a;ipFaceCoords_[4](1,0)=-a;ipFaceCoords_[4](2,0)=-1;
|
||||
ipFaceCoords_[4](0,1)= a;ipFaceCoords_[4](1,1)=-a;ipFaceCoords_[4](2,1)=-1;
|
||||
ipFaceCoords_[4](0,2)= a;ipFaceCoords_[4](1,2)= a;ipFaceCoords_[4](2,2)=-1;
|
||||
ipFaceCoords_[4](0,3)=-a;ipFaceCoords_[4](1,3)= a;ipFaceCoords_[4](2,3)=-1;
|
||||
|
||||
ipFaceCoords_[5](0,0)=-a;ipFaceCoords_[5](1,0)=-a;ipFaceCoords_[5](2,0)= 1;
|
||||
ipFaceCoords_[5](0,1)= a;ipFaceCoords_[5](1,1)=-a;ipFaceCoords_[5](2,1)= 1;
|
||||
ipFaceCoords_[5](0,2)= a;ipFaceCoords_[5](1,2)= a;ipFaceCoords_[5](2,2)= 1;
|
||||
ipFaceCoords_[5](0,3)=-a;ipFaceCoords_[5](1,3)= a;ipFaceCoords_[5](2,3)= 1;
|
||||
|
||||
// Compute shape functions at ip's
|
||||
for (int f = 0; f < numFaces_; f++) {
|
||||
for (int ip = 0; ip < numFaceIPs_; ip++) {
|
||||
double r = ipFaceCoords_[f](0, ip);
|
||||
double s = ipFaceCoords_[f](1, ip);
|
||||
double t = ipFaceCoords_[f](2, ip);
|
||||
for (int iNode = 0; iNode < numEltNodes_; iNode++) {
|
||||
double rI = localCoords_(0, iNode);
|
||||
double sI = localCoords_(1, iNode);
|
||||
double tI = localCoords_(2, iNode);
|
||||
NFace_[f](ip, iNode) = 0.125 * (1 + r*rI) * (1 + s*sI) * (1 + t*tI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// integration points
|
||||
ipFaceWeights_ = 1.0;
|
||||
}
|
||||
|
||||
FE_ElementHex::~FE_ElementHex()
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// shape_function
|
||||
// -------------------------------------------------------------
|
||||
void FE_ElementHex::shape_function(const int eltID,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
DIAG_MAT &weights)
|
||||
{
|
||||
// Get element node coordinates from mesh
|
||||
DENS_MAT xCoords;
|
||||
feMesh_->element_coordinates(eltID, xCoords);
|
||||
|
||||
// Transpose xCoords
|
||||
DENS_MAT xCoordsT(transpose(xCoords));
|
||||
|
||||
// Shape functions are simply the canonical element values
|
||||
N = N_;
|
||||
|
||||
// Set sizes of matrices and vectors
|
||||
if ((int)dN.size() != nSD_) dN.resize(nSD_);
|
||||
for (int isd = 0; isd < nSD_; isd++) dN[isd].resize(numIPs_, numEltNodes_);
|
||||
weights.resize(numIPs_,numIPs_);
|
||||
|
||||
// Create some temporary matrices:
|
||||
|
||||
// Shape function deriv.'s w.r.t. element coords
|
||||
DENS_MAT dNdr(nSD_, numEltNodes_, false);
|
||||
|
||||
// Jacobian matrix: [dx/dr dy/ds dz/dt | dx/ds ... ]
|
||||
DENS_MAT dxdr, drdx, dNdx;
|
||||
|
||||
// Loop over integration points
|
||||
for (int ip = 0; ip < numIPs_; ip++) {
|
||||
const double &r = ipCoords_(0,ip);
|
||||
const double &s = ipCoords_(1,ip);
|
||||
const double &t = ipCoords_(2,ip);
|
||||
|
||||
// Fill dNdr
|
||||
for (int inode = 0; inode < numEltNodes_; inode++) {
|
||||
const double &rI = localCoords_(0,inode);
|
||||
const double &sI = localCoords_(1,inode);
|
||||
const double &tI = localCoords_(2,inode);
|
||||
dNdr(0,inode) = 0.125 * rI * (1 + s*sI) * (1 + t*tI);
|
||||
dNdr(1,inode) = 0.125 * sI * (1 + r*rI) * (1 + t*tI);
|
||||
dNdr(2,inode) = 0.125 * tI * (1 + r*rI) * (1 + s*sI);
|
||||
}
|
||||
|
||||
// Compute dx/dxi matrix
|
||||
dxdr = dNdr * xCoordsT;
|
||||
drdx = inv(dxdr);
|
||||
|
||||
// Compute dNdx and fill dN matrix
|
||||
dNdx = drdx*dNdr;
|
||||
for (int isd = 0; isd < nSD_; isd++)
|
||||
for (int inode = 0; inode < numEltNodes_; inode++)
|
||||
dN[isd](ip,inode) = dNdx(isd,inode);
|
||||
|
||||
// Compute jacobian determinant of dxdr at this ip
|
||||
double J = dxdr(0,0) * ( dxdr(1,1)*dxdr(2,2) - dxdr(2,1)*dxdr(1,2) )
|
||||
- dxdr(0,1) * ( dxdr(1,0)*dxdr(2,2) - dxdr(1,2)*dxdr(2,0) )
|
||||
+ dxdr(0,2) * ( dxdr(1,0)*dxdr(2,1) - dxdr(1,1)*dxdr(2,0) );
|
||||
|
||||
// Compute ip weight
|
||||
weights(ip,ip) = ipWeights_(ip)*J;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void FE_ElementHex::shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N)
|
||||
{
|
||||
N.resize(numEltNodes_);
|
||||
for (int inode = 0; inode < numEltNodes_; ++inode)
|
||||
{
|
||||
double shp = 0.125;
|
||||
for (int i = 0; i < nSD_; ++i) shp *= (1 + xi(i)*localCoords_(i, inode));
|
||||
N(inode) = shp;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void FE_ElementHex::shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N,
|
||||
DENS_MAT &dNdx)
|
||||
{
|
||||
N.resize(numEltNodes_);
|
||||
|
||||
// Get element node coordinates from mesh
|
||||
DENS_MAT xCoords;
|
||||
feMesh_->element_coordinates(eltID, xCoords);
|
||||
DENS_MAT xCoordsT = transpose(xCoords);
|
||||
DENS_MAT dNdr(3,8,false), dxdr(3,3,false), drdx;
|
||||
double r = xi(0);
|
||||
double s = xi(1);
|
||||
double t = xi(2);
|
||||
for (int inode = 0; inode < numEltNodes_; ++inode)
|
||||
{
|
||||
double rI = localCoords_(0,inode);
|
||||
double sI = localCoords_(1,inode);
|
||||
double tI = localCoords_(2,inode);
|
||||
|
||||
// Shape function
|
||||
N(inode) = 0.125 * (1.0 + r*rI) * (1.0 + s*sI) * (1.0 + t*tI);
|
||||
|
||||
// Shape function derivative wrt (r,s,t)
|
||||
dNdr(0,inode) = 0.125 * rI * (1.0 + s*sI) * (1.0 + t*tI);
|
||||
dNdr(1,inode) = 0.125 * sI * (1.0 + r*rI) * (1.0 + t*tI);
|
||||
dNdr(2,inode) = 0.125 * tI * (1.0 + r*rI) * (1.0 + s*sI);
|
||||
}
|
||||
|
||||
// Derivatives wrt (x,y,z)
|
||||
dxdr = dNdr * xCoordsT;
|
||||
drdx = inv(dxdr);
|
||||
dNdx = drdx*dNdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void FE_ElementHex::face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
vector<DENS_MAT> &Nn,
|
||||
DIAG_MAT &weights)
|
||||
{
|
||||
int eltID = face.first;
|
||||
int local_faceID = face.second;
|
||||
// const double * face_normal = face.normal();
|
||||
// double * normal = face_normal;
|
||||
DENS_VEC normal(nSD_);
|
||||
|
||||
// Get element node coordinates from mesh
|
||||
DENS_MAT xCoords;
|
||||
feMesh_->element_coordinates(eltID, xCoords);
|
||||
|
||||
// Transpose xCoords
|
||||
DENS_MAT xCoordsT = transpose(xCoords);
|
||||
|
||||
// Shape functions are simply the canonical element values
|
||||
N.reset(numFaceIPs_, numEltNodes_);
|
||||
N = NFace_[local_faceID];
|
||||
|
||||
// Set sizes of matrices and vectors
|
||||
if ((int)dN.size() != nSD_) dN.resize(nSD_);
|
||||
for (int isd = 0; isd < nSD_; isd++) dN[isd].reset(numFaceIPs_, numEltNodes_);
|
||||
weights.reset(numFaceIPs_,numFaceIPs_);
|
||||
|
||||
// Create some temporary matrices:
|
||||
|
||||
// Shape function deriv.'s w.r.t. element coords
|
||||
DENS_MAT dNdr(nSD_, numEltNodes_);
|
||||
|
||||
// Jacobian matrix: [dx/dr dy/ds dz/dt | dx/ds ... ]
|
||||
DENS_MAT dxdr, drdx, dNdx;
|
||||
|
||||
// Loop over integration points
|
||||
for (int ip = 0; ip < numFaceIPs_; ip++) {
|
||||
double r = ipFaceCoords_[local_faceID](0,ip);
|
||||
double s = ipFaceCoords_[local_faceID](1,ip);
|
||||
double t = ipFaceCoords_[local_faceID](2,ip);
|
||||
|
||||
// Fill dNdr
|
||||
for (int inode = 0; inode < numEltNodes_; inode++) {
|
||||
double rI = localCoords_(0,inode);
|
||||
double sI = localCoords_(1,inode);
|
||||
double tI = localCoords_(2,inode);
|
||||
dNdr(0,inode) = 0.125 * rI * (1 + s*sI) * (1 + t*tI);
|
||||
dNdr(1,inode) = 0.125 * sI * (1 + r*rI) * (1 + t*tI);
|
||||
dNdr(2,inode) = 0.125 * tI * (1 + r*rI) * (1 + s*sI);
|
||||
}
|
||||
|
||||
// Compute dx/dxi matrix
|
||||
dxdr = dNdr * xCoordsT;
|
||||
drdx = inv(dxdr);
|
||||
|
||||
// Compute 2d jacobian determinant of dxdr at this ip
|
||||
double J = face_normal(face, ip, normal);
|
||||
|
||||
// Compute dNdx and fill dN matrix
|
||||
dNdx = drdx*dNdr;
|
||||
for (int isd = 0; isd < nSD_; isd++) {
|
||||
for (int inode = 0; inode < numEltNodes_; inode++) {
|
||||
dN[isd](ip,inode) = dNdx(isd,inode);
|
||||
Nn[isd](ip,inode) = N(ip,inode)*normal(isd);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute ip weight
|
||||
weights(ip,ip) = ipFaceWeights_(ip)*J;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
void FE_ElementHex::face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
DENS_MAT &n,
|
||||
DIAG_MAT &weights)
|
||||
{
|
||||
int eltID = face.first;
|
||||
int local_faceID = face.second;
|
||||
// const double * face_normal = face.normal();
|
||||
// double * normal = face_normal;
|
||||
DENS_VEC normal(nSD_);
|
||||
|
||||
// Get element node coordinates from mesh
|
||||
DENS_MAT xCoords;
|
||||
feMesh_->element_coordinates(eltID, xCoords);
|
||||
|
||||
// Transpose xCoords
|
||||
DENS_MAT xCoordsT = transpose(xCoords);
|
||||
|
||||
// Shape functions are simply the canonical element values
|
||||
N.reset(numFaceIPs_, numEltNodes_);
|
||||
N = NFace_[local_faceID];
|
||||
|
||||
weights.reset(numFaceIPs_,numFaceIPs_);
|
||||
|
||||
// Create some temporary matrices:
|
||||
|
||||
// Shape function deriv.'s w.r.t. element coords
|
||||
DENS_MAT dNdr(nSD_, numEltNodes_);
|
||||
|
||||
// Jacobian matrix: [dx/dr dy/ds dz/dt | dx/ds ... ]
|
||||
DENS_MAT dxdr, drdx, dNdx;
|
||||
|
||||
// Loop over integration points
|
||||
for (int ip = 0; ip < numFaceIPs_; ip++) {
|
||||
double r = ipFaceCoords_[local_faceID](0,ip);
|
||||
double s = ipFaceCoords_[local_faceID](1,ip);
|
||||
double t = ipFaceCoords_[local_faceID](2,ip);
|
||||
|
||||
// Compute 2d jacobian determinant of dxdr at this ip
|
||||
double J = face_normal(face, ip, normal);
|
||||
|
||||
// Copy normal at integration point
|
||||
for (int isd = 0; isd < nSD_; isd++) {
|
||||
n(isd,ip) = normal(isd);
|
||||
}
|
||||
|
||||
// Compute ip weight
|
||||
weights(ip,ip) = ipFaceWeights_(ip)*J;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// face_normal
|
||||
// -------------------------------------------------------------
|
||||
double FE_ElementHex::face_normal(const PAIR & face,
|
||||
int ip,
|
||||
DENS_VEC &normal)
|
||||
{
|
||||
// Get element node coordinates from mesh
|
||||
DENS_MAT xCoords;
|
||||
feMesh_->face_coordinates(face, xCoords);
|
||||
|
||||
// Transpose xCoords
|
||||
DENS_MAT xCoordsT = transpose(xCoords);
|
||||
|
||||
double r = ipFace2DCoords_(0,ip);
|
||||
double s = ipFace2DCoords_(1,ip);
|
||||
DENS_MAT dNdr(nSD_-1, numFaceNodes_);
|
||||
for (int inode = 0; inode < numFaceNodes_; inode++) {
|
||||
double rI = localCoords_(0,inode); // NOTE a little dangerous
|
||||
double sI = localCoords_(1,inode);
|
||||
dNdr(0,inode) = 0.25 * rI * (1 + s*sI);
|
||||
dNdr(1,inode) = 0.25 * sI * (1 + r*rI);
|
||||
}
|
||||
DENS_MAT dxdr(2,3);
|
||||
|
||||
// Compute dx/dxi matrix
|
||||
dxdr = dNdr * xCoordsT;
|
||||
normal(0) = dxdr(0,1)*dxdr(1,2) - dxdr(0,2)*dxdr(1,1) ;
|
||||
normal(1) = dxdr(0,2)*dxdr(1,0) - dxdr(0,0)*dxdr(1,2) ;
|
||||
normal(2) = dxdr(0,0)*dxdr(1,1) - dxdr(0,1)*dxdr(1,0) ;
|
||||
|
||||
double J = sqrt(normal(0)*normal(0)+normal(1)*normal(1)+normal(2)*normal(2));
|
||||
// double inv_J = normal_sense(face)/J;
|
||||
double inv_J = 1.0/J;
|
||||
normal(0) *= inv_J;
|
||||
normal(1) *= inv_J;
|
||||
normal(2) *= inv_J;
|
||||
return J;
|
||||
}
|
||||
|
||||
|
||||
}; // namespace ATC_Transfer
|
|
@ -1,204 +0,0 @@
|
|||
#ifndef FE_ELEMENT_H
|
||||
#define FE_ELEMENT_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "MatrixLibrary.h"
|
||||
#include "Array2D.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// Forward declarations
|
||||
class FE_Mesh;
|
||||
|
||||
/**
|
||||
* @class FE_Element
|
||||
* @brief Base class for a finite element holding info for canonical element
|
||||
*/
|
||||
|
||||
class FE_Element {
|
||||
|
||||
public:
|
||||
FE_Element(FE_Mesh *feMesh,
|
||||
int nSD,
|
||||
int numEltNodes,
|
||||
int numIPs,
|
||||
int numFaces,
|
||||
int numFaceNodes,
|
||||
int numFaceIPs);
|
||||
virtual ~FE_Element();
|
||||
|
||||
/** get number of element nodes */
|
||||
int num_elt_nodes() { return numEltNodes_; }
|
||||
|
||||
/** get number of integration points */
|
||||
int num_ips() { return numIPs_; }
|
||||
|
||||
/** get number of faces */
|
||||
int num_faces() { return numFaces_; }
|
||||
|
||||
/** get number of face nodes */
|
||||
int num_face_nodes() { return numFaceNodes_; }
|
||||
|
||||
/** get number of integration points */
|
||||
int num_face_ips() { return numFaceIPs_; }
|
||||
|
||||
/** cannonical face numbering */
|
||||
const Array2D<int> & local_face_conn(void) const {return localFaceConn_ ;}
|
||||
|
||||
/**
|
||||
* compute shape functions at all ip's:
|
||||
* indexed: N(ip,node)
|
||||
* dN[nsd](ip,node)
|
||||
* weights(ip)
|
||||
*/
|
||||
virtual void shape_function(const int eltID,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
DIAG_MAT &weights)=0;
|
||||
|
||||
/**
|
||||
* compute shape functions at a single point, given the local coordinates
|
||||
* indexed: N(node)
|
||||
* dN[nsd](node)
|
||||
*/
|
||||
virtual void shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N) = 0;
|
||||
|
||||
virtual void shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N,
|
||||
DENS_MAT &dN) = 0;
|
||||
|
||||
/**
|
||||
* compute shape functions at all face ip's:
|
||||
* indexed: N(ip,node)
|
||||
* dN[nsd](ip,node)
|
||||
* Nn[nsd](ip,node)
|
||||
* weights(ip)
|
||||
*/
|
||||
virtual void face_shape_function(const PAIR &face,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
vector<DENS_MAT> &Nn,
|
||||
DIAG_MAT &weights) = 0;
|
||||
|
||||
virtual void face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
DENS_MAT &n,
|
||||
DIAG_MAT &weights) = 0;
|
||||
|
||||
virtual double face_normal(const PAIR & face,
|
||||
const int ip,
|
||||
DENS_VEC &normal) = 0;
|
||||
|
||||
enum FE_ElementQuadrature { GAUSSIAN_QUADRATURE, NODAL_QUADRATURE};
|
||||
virtual void set_quadrature(int quadrature_type) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
// Mesh
|
||||
FE_Mesh * feMesh_;
|
||||
|
||||
// Number of spatial dimensions
|
||||
int nSD_;
|
||||
|
||||
// Number of element nodes
|
||||
int numEltNodes_;
|
||||
|
||||
// Number of integration points
|
||||
int numIPs_;
|
||||
|
||||
// Number of faces
|
||||
int numFaces_;
|
||||
|
||||
// Number of face nodes
|
||||
int numFaceNodes_;
|
||||
|
||||
// Number of face integration points
|
||||
int numFaceIPs_;
|
||||
|
||||
// local coords of nodes: localCoords_(isd, ip)
|
||||
DENS_MAT localCoords_;
|
||||
|
||||
// quadrature scheme: localCoords_(isd, ip)
|
||||
DENS_MAT ipCoords_; // local coordinates
|
||||
|
||||
// matrix of shape functions at ip's: N_(ip, node)
|
||||
DENS_MAT N_;
|
||||
|
||||
// integration point weights: ipWeights_(ip)
|
||||
DENS_VEC ipWeights_; // local coordinates
|
||||
|
||||
// local face numbering
|
||||
Array2D<int> localFaceConn_;
|
||||
|
||||
// quadrature scheme: localCoords_(isd, ip)
|
||||
vector<DENS_MAT> ipFaceCoords_;
|
||||
DENS_MAT ipFace2DCoords_;
|
||||
|
||||
// matrix of shape functions at ip's: N_(ip, node)
|
||||
vector<DENS_MAT> NFace_;
|
||||
|
||||
// integration point weights: ipWeights_(ip)
|
||||
DENS_VEC ipFaceWeights_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @class FE_ElementHex
|
||||
* @author Greg Wagner
|
||||
* @brief 3D, linear 8-node hex element with 2x2x2 quadrature
|
||||
*/
|
||||
class FE_ElementHex : public FE_Element {
|
||||
|
||||
public:
|
||||
FE_ElementHex(FE_Mesh * feMesh);
|
||||
// Dump state info to disk for later restart
|
||||
void write_restart(FILE *);
|
||||
~FE_ElementHex();
|
||||
|
||||
protected:
|
||||
virtual void shape_function(const int eltID,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
DiagonalMatrix<double> &weights);
|
||||
|
||||
/**
|
||||
* compute shape functions at a single point, given the local coordinates
|
||||
* indexed: N(node)
|
||||
* dN[nsd](node)
|
||||
*/
|
||||
virtual void shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N);
|
||||
|
||||
virtual void shape_function(const int eltID,
|
||||
const VECTOR &xi,
|
||||
DENS_VEC &N,
|
||||
DENS_MAT &dN);
|
||||
|
||||
virtual void face_shape_function(const PAIR &face,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
vector<DENS_MAT> &Nn,
|
||||
DiagonalMatrix<double> &weights);
|
||||
|
||||
virtual void face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
DENS_MAT &n,
|
||||
DIAG_MAT &weights);
|
||||
|
||||
virtual double face_normal(const PAIR &face, const int ip, DENS_VEC &normal);
|
||||
|
||||
virtual void set_quadrature(int quadrature_type);
|
||||
};
|
||||
|
||||
}; // namespace ATC_Transfer
|
||||
|
||||
#endif // FE_ELEMENT_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,348 +0,0 @@
|
|||
/** fe_engine :
|
||||
* computes and assembles mass matrix, rhs vectors
|
||||
* initial conditions handled in atc_transfer
|
||||
*/
|
||||
|
||||
/** field structure:
|
||||
a field is a dense matrix of numPoints X number of DOF in the field
|
||||
a gradient is a std::vector of fields of length numSpatialDimensions
|
||||
a set of fields is a map of fieldName->field of length numFields
|
||||
a set of gradients is a map of fieldName->gradient of length numFields
|
||||
Note: shape functions follow similar conventions with a shape function being
|
||||
a field of numPoints X numNodes
|
||||
and a shape function gradient being a std::vector of shape functions
|
||||
of length numSpatialDimensions, although this is modified in calls when
|
||||
numPoints = 1
|
||||
Note: the convention between shape function format and field format allows
|
||||
for shape functions to matmat nodal fields, creating matrices of
|
||||
numPoints X numElementsInField for evaluating data at atomic/quadarture points
|
||||
*/
|
||||
|
||||
/** current internal limitations:
|
||||
* 3 spatial dimensions
|
||||
* 8 node bricks
|
||||
* structured mesh
|
||||
* no stiffness matrix
|
||||
(i.e. no implicit integration or special treatment of linear problems)
|
||||
* lumped mass
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** terminology:
|
||||
density rate = flux
|
||||
= Grad.FLUX(f,D_x f)
|
||||
+ SOURCE(f,D_x f) + PRESCRIBED_SOURCE(x,t)
|
||||
+ EXTRINSIC_SOURCE(f,D_x f,f_e,D_x f_e)
|
||||
*/
|
||||
|
||||
#ifndef FE_ENGINE_H
|
||||
#define FE_ENGINE_H
|
||||
|
||||
// Other headers
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "Array.h"
|
||||
#include "Array2D.h"
|
||||
#include "FE_Mesh.h"
|
||||
#include "PhysicsModel.h"
|
||||
#include "OutputManager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// Forward declarations
|
||||
class ATC_Transfer;
|
||||
class FE_Element;
|
||||
class XT_Function;
|
||||
|
||||
class FE_Engine{
|
||||
public:
|
||||
/** constructor/s */
|
||||
FE_Engine(ATC_Transfer * atcTransfer);
|
||||
|
||||
/** destructor */
|
||||
~FE_Engine();
|
||||
|
||||
/** initialize */
|
||||
void initialize();
|
||||
|
||||
/** parser/modifier */
|
||||
bool modify(int narg, char **arg);
|
||||
|
||||
/** finish up */
|
||||
void finish();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name output */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** these assume the caller is handling the parallel collection */
|
||||
void initialize_output(int rank,
|
||||
string outputPrefix, OutputType otype = ENSIGHT);
|
||||
|
||||
/** write geometry */
|
||||
void write_geometry(void);
|
||||
|
||||
/** write data: data is arrayed over _unique_ nodes
|
||||
& then mapped by the engine */
|
||||
void write_data(double time, FIELDS &soln, OUTPUT_LIST *data=NULL);
|
||||
void write_data(double time, OUTPUT_LIST *data);
|
||||
void write_restart_file(string fileName, OUTPUT_LIST *data)
|
||||
{outputManager_.write_restart_file(fileName,data);};
|
||||
void read_restart_file(string fileName, OUTPUT_LIST *data)
|
||||
{outputManager_.read_restart_file(fileName,data);};
|
||||
|
||||
void delete_elements(const set<int> & elementList);
|
||||
|
||||
void add_global(string name, double value)
|
||||
{outputManager_.add_global(name,value);}
|
||||
void reset_globals() {outputManager_.reset_globals();}
|
||||
|
||||
/** pass through to access output manager */
|
||||
OutputManager* output_manager() {return &outputManager_;}
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name assembled matrices and vectors */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** compute a dimensionless stiffness matrix */
|
||||
void compute_stiffness_matrix(SPAR_MAT &matrix) const;
|
||||
|
||||
/** compute a dimensionless mass matrix */
|
||||
void compute_mass_matrix(SPAR_MAT &mass_matrix) const;
|
||||
/** computes a dimensionless mass matrix for the given-quadrature */
|
||||
void compute_mass_matrix(const DIAG_MAT &weights,
|
||||
const SPAR_MAT &N,
|
||||
SPAR_MAT &mass_matrix) const;
|
||||
/** compute a single dimensionless mass matrix */
|
||||
void compute_lumped_mass_matrix(DIAG_MAT &lumped_mass_matrix) const;
|
||||
|
||||
/** compute lumped mass matrix = diag (\int \rho N_I dV) */
|
||||
void compute_lumped_mass_matrix(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
map<FieldName, DIAG_MAT> &mass_matrix,
|
||||
const Array<bool> *element_mask=NULL) const;
|
||||
/** compute dimensional lumped mass matrix using given quadrature */
|
||||
void compute_lumped_mass_matrix(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<set<int> > & pointMaterialGroups,
|
||||
const DIAG_MAT &weights,
|
||||
const SPAR_MAT &N,
|
||||
map<FieldName, DIAG_MAT> &mass_matrix) const;
|
||||
|
||||
/** compute an approximation to a finite difference gradient from mesh */
|
||||
void compute_gradient_matrix(GRAD_SHPFCN &grad_matrix) const;
|
||||
|
||||
|
||||
/** compute energy */
|
||||
void compute_energy(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
FIELDS &energy,
|
||||
const Array<bool> *element_mask=NULL) const;
|
||||
|
||||
|
||||
/** compute residual or RHS of the dynamic weak eqn */
|
||||
void compute_rhs_vector(const Array2D<bool> &rhs_mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
FIELDS &rhs,
|
||||
const Array<bool> *element_mask=NULL) const;
|
||||
|
||||
/** compute RHS for given quadrature */
|
||||
void compute_rhs_vector(const Array2D<bool> &rhs_mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<set<int> > & pointMaterialGroups,
|
||||
const DIAG_MAT &weights,
|
||||
const SPAR_MAT &N,
|
||||
const GRAD_SHPFCN &dN,
|
||||
FIELDS &rhs) const;
|
||||
|
||||
/** compute flux in domain i.e. N^T B_integrand */
|
||||
void compute_flux(const Array2D<bool> & rhs_mask,
|
||||
const FIELDS &fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
GRAD_FIELDS &flux,
|
||||
const Array<bool> *element_mask=NULL) const;
|
||||
|
||||
/** compute the flux on the MD/FE boundary */
|
||||
void compute_boundary_flux(
|
||||
const Array2D<bool> & rhs_mask,
|
||||
const FIELDS & fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
const set<PAIR> & faceSet,
|
||||
FIELDS & rhs) const;
|
||||
|
||||
/** compute the flux on using an L2 interpolation of the flux */
|
||||
void compute_boundary_flux(
|
||||
const Array2D<bool> & rhs_mask,
|
||||
const FIELDS & fields,
|
||||
const PhysicsModel * physicsModel,
|
||||
const Array<int> & elementMaterials,
|
||||
const Array<set<int> > & pointMaterialGroups,
|
||||
const DIAG_MAT & weights,
|
||||
const SPAR_MAT & N,
|
||||
const GRAD_SHPFCN & dN,
|
||||
const DIAG_MAT & flux_mask,
|
||||
FIELDS & rhs ) const;
|
||||
|
||||
/** compute prescribed flux given an array of functions of x & t */
|
||||
void add_fluxes(const Array<bool> &fieldMask,
|
||||
const double time,
|
||||
const SURFACE_SOURCE & sourceFunctions,
|
||||
FIELDS &nodalSources) const;
|
||||
|
||||
/** compute nodal vector of volume based sources */
|
||||
void add_sources(const Array<bool> &fieldMask,
|
||||
const double time,
|
||||
const VOLUME_SOURCE &sourceFunctions,
|
||||
FIELDS &nodalSources) const;
|
||||
|
||||
/** compute surface flux of a nodal field */
|
||||
void field_surface_flux(const DENS_MAT & field,
|
||||
const set<PAIR> &faceSet,
|
||||
DENS_MAT & values,
|
||||
const bool contour = false,
|
||||
const int axis = 2) const;
|
||||
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name shape functions */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** evaluate shape function at a list of points in R^3 */
|
||||
void evaluate_shape_functions(const MATRIX &coords,
|
||||
SPAR_MAT &N,
|
||||
Array<int> & pointToEltMap) const;
|
||||
|
||||
/** evaluate shape function & derivatives at a list of points in R^3 */
|
||||
void evaluate_shape_functions( const MATRIX &coords,
|
||||
SPAR_MAT &N,
|
||||
GRAD_SHPFCN &dN,
|
||||
Array<int> & pointToEltMap) const;
|
||||
|
||||
/** evaluate all shape function & derivatives at a specific R^3 location */
|
||||
void evaluate_shape_functions(const VECTOR & x,
|
||||
Array<int>& node_index,
|
||||
DENS_VEC& shp,
|
||||
DENS_MAT& dshp,
|
||||
int & eltID) const;
|
||||
|
||||
/** pass through */
|
||||
void shape_functions(const VECTOR &x,
|
||||
DENS_VEC& shp,
|
||||
int & eltID,
|
||||
Array<int>& node_list) const
|
||||
{ feMesh_->shape_functions(x,shp,eltID,node_list); }
|
||||
|
||||
void shape_functions(const VECTOR &x,
|
||||
DENS_VEC& shp,
|
||||
int & eltID,
|
||||
Array<int>& node_list,
|
||||
const Array<bool>& periodicity) const
|
||||
{ feMesh_->shape_functions(x,shp,eltID,node_list, periodicity); }
|
||||
/*@}*/
|
||||
|
||||
//----------------------------------------------------------------
|
||||
/** \name accessors */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
/** even though these are pass-throughs there is a necessary translation */
|
||||
/** return number of unique nodes */
|
||||
int get_nNodes() const { return feMesh_->get_nNodesUnique(); };
|
||||
|
||||
/** return number of total nodes */
|
||||
int get_nNodesTotal() const { return feMesh_->get_nNodes(); };
|
||||
|
||||
/** return number of elements */
|
||||
int get_nElements() const { return feMesh_->get_nElements(); };
|
||||
|
||||
/** return element connectivity */
|
||||
void element_connectivity(const int eltID, Array<int> & nodes) const
|
||||
{ feMesh_->element_connectivity_unique(eltID, nodes); }
|
||||
|
||||
/** return face connectivity */
|
||||
void face_connectivity(const PAIR &faceID, Array<int> &nodes) const
|
||||
{ feMesh_->face_connectivity_unique(faceID, nodes); }
|
||||
|
||||
/** in lieu of pass-throughs const accessors ... */
|
||||
// return const ptr to mesh
|
||||
const FE_Mesh* get_feMesh() const { return feMesh_;}
|
||||
|
||||
// return number of spatial dimensions
|
||||
int get_nsd() const { return feMesh_->get_nSpatialDimensions(); }
|
||||
|
||||
// return if the FE mesh has been created
|
||||
int fe_mesh_exist() const { return feMesh_!=NULL; }
|
||||
|
||||
// get nodal coordinates for a given element
|
||||
void element_coordinates(const int eltIdx, DENS_MAT &coords)
|
||||
{ feMesh_->element_coordinates(eltIdx,coords); }
|
||||
|
||||
// access list of elements to be deleted
|
||||
set<int> & null_elements(void) { return nullElements_; }
|
||||
/*@}*/
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------
|
||||
/** mesh setup commands (called from modify) */
|
||||
//----------------------------------------------------------------
|
||||
/*@{*/
|
||||
|
||||
/** initialized flag */
|
||||
bool initialized_;
|
||||
|
||||
/** create a uniform, structured mesh */
|
||||
void create_mesh(int nx, int ny, int nz, char * regionName,
|
||||
int xperiodic, int yperiodic, int zperiodic);
|
||||
/*@}*/
|
||||
|
||||
/** ATC transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** finite element mesh */
|
||||
FE_Mesh * feMesh_;
|
||||
|
||||
/** data that can be used for a subset of original mesh */
|
||||
set<int> nullElements_;
|
||||
bool amendedMeshData_;
|
||||
const Array2D<int> * connectivity_;
|
||||
const Array<int> * nodeMap_;
|
||||
const DENS_MAT * coordinates_;
|
||||
|
||||
/** workspace */
|
||||
int nNodesPerElement_;
|
||||
int nIPsPerElement_;
|
||||
int nIPsPerFace_;
|
||||
int nSD_;
|
||||
int nElems_;
|
||||
|
||||
/** output object */
|
||||
OutputManager outputManager_;
|
||||
|
||||
/** base name for output files */
|
||||
string outputPrefix_;
|
||||
|
||||
/** output frequency (NOTE will move to "Transfer") */
|
||||
int outputFrequency_;
|
||||
|
||||
/** list of output timesteps */
|
||||
vector<double> outputTimes_;
|
||||
};
|
||||
}; // end namespace ATC
|
||||
|
||||
#endif
|
1315
lib/atc/FE_Mesh.cpp
1315
lib/atc/FE_Mesh.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,387 +0,0 @@
|
|||
#ifndef FE_MESH_H
|
||||
#define FE_MESH_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "Array.h"
|
||||
#include "Array2D.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
// Other headers
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
// Forward declarations
|
||||
class FE_Element;
|
||||
|
||||
/**
|
||||
* @class FE_Mesh
|
||||
* @brief Base class for a finite element mesh
|
||||
*/
|
||||
class FE_Mesh {
|
||||
|
||||
public:
|
||||
|
||||
/** constructor */
|
||||
FE_Mesh();
|
||||
|
||||
/** destructor */
|
||||
virtual ~FE_Mesh();
|
||||
|
||||
/** parser/modifier */
|
||||
bool modify(int narg, char **arg);
|
||||
|
||||
/** evaluate shape function at real coordinates */
|
||||
void shape_functions(const VECTOR &x,
|
||||
DENS_VEC& shp,
|
||||
int & eltID,
|
||||
Array<int>& node_list) const;
|
||||
|
||||
/** evaluate shape function at real coordinates */
|
||||
void shape_functions(const VECTOR &x,
|
||||
DENS_VEC& shp,
|
||||
int & eltID,
|
||||
Array<int>& node_list,
|
||||
const Array<bool>& periodicity) const;
|
||||
|
||||
/** evaluate shape function at real coordinates */
|
||||
void shape_functions(const VECTOR &x,
|
||||
DENS_VEC & shp,
|
||||
DENS_MAT & dshp,
|
||||
int & eltID,
|
||||
Array<int>& node_list) const;
|
||||
|
||||
/** evaluate shape functions for all ip's on an element */
|
||||
// N is numIPsInElement X numNodesInElement
|
||||
void shape_function(const int eltID,
|
||||
DENS_MAT &N,
|
||||
DIAG_MAT &weights) const;
|
||||
|
||||
/** evaluate shape functions for all ip's on an element */
|
||||
// N is numIPsInElement X numNodesInElement
|
||||
void shape_function(const int eltID,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
DIAG_MAT &weights) const;
|
||||
|
||||
/** evaluate shape functions for all ip's on an face*/
|
||||
// N is numIPsInFace X numNodesInElement
|
||||
void face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
vector<DENS_MAT> &dN,
|
||||
vector<DENS_MAT> &Nn,
|
||||
DIAG_MAT &weights) const;
|
||||
|
||||
void face_shape_function(const PAIR & face,
|
||||
DENS_MAT &N,
|
||||
DENS_MAT &n,
|
||||
DIAG_MAT &weights) const;
|
||||
|
||||
/** return connectivity (global ID numbers) for element eltID */
|
||||
void element_connectivity_global(const int eltID,
|
||||
Array<int> & nodes) const;
|
||||
|
||||
void element_connectivity_unique(const int eltID,
|
||||
Array<int> & nodes) const;
|
||||
|
||||
void face_connectivity(const pair<int,int> & faceID,
|
||||
Array<int> & nodes) const
|
||||
{ int nNodesPerFace = get_nNodesPerFace();
|
||||
nodes.reset(nNodesPerFace);
|
||||
int eltID = faceID.first;
|
||||
int localFace = faceID.second;
|
||||
const Array2D<int> & localFaceConn = local_face_connectivity();
|
||||
for(int i = 0; i < nNodesPerFace; ++i) {
|
||||
nodes(i) = connectivity_(localFaceConn(localFace,i),eltID);
|
||||
}
|
||||
}
|
||||
void face_connectivity_unique(const pair<int,int> & faceID,
|
||||
Array<int> & nodes) const
|
||||
{ int nNodesPerFace = get_nNodesPerFace();
|
||||
nodes.reset(nNodesPerFace);
|
||||
int eltID = faceID.first;
|
||||
int localFace = faceID.second;
|
||||
const Array2D<int> & localFaceConn = local_face_connectivity();
|
||||
for(int i = 0; i < nNodesPerFace; ++i) {
|
||||
nodes(i) = connectivityUnique_(localFaceConn(localFace,i),eltID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* return spatial coordinates for element nodes on eltID,
|
||||
* indexed xCoords(isd,inode)
|
||||
*/
|
||||
void element_coordinates(const int eltID,
|
||||
DENS_MAT & xCoords) const;
|
||||
|
||||
void face_coordinates(const pair <int,int> face,
|
||||
DENS_MAT & xCoords) const;
|
||||
|
||||
|
||||
/** access to the nodal coordinate values */
|
||||
const DENS_MAT & nodal_coordinates(void) {return nodalCoords_ ;}
|
||||
|
||||
/** access to nodal coordinates of a unique node */
|
||||
DENS_VEC nodal_coordinates(const int nodeID) const;
|
||||
|
||||
/** access to nodal coordinates of a node */
|
||||
DENS_VEC global_coordinates(const int nodeID) const;
|
||||
|
||||
/** access to the element connectivity values */
|
||||
const Array2D<int> & connectivity(void) {return connectivity_ ;}
|
||||
|
||||
/** map spatial location to element */
|
||||
virtual int map_to_element(const DENS_VEC & x) const = 0;
|
||||
|
||||
/** map spatial location to element and local coordinates */
|
||||
virtual int map_to_element(const DENS_VEC & x,
|
||||
DENS_VEC & xi) const = 0;
|
||||
|
||||
/** map spatial location to element and local coordinates */
|
||||
virtual int map_to_element(const DENS_VEC & x,
|
||||
DENS_VEC & xi,
|
||||
const Array<bool>& periodicity) const = 0;
|
||||
|
||||
/** map global node numbering to unique node numbering */
|
||||
int map_global_to_unique(const int global_id) const {return globalToUniqueMap_(global_id);}
|
||||
inline const int* global_to_unique_map_pointer(void) {return globalToUniqueMap_.get_data();}
|
||||
inline const Array<int>& global_to_unique_map(void) {return globalToUniqueMap_;}
|
||||
|
||||
/** map unique node numbering a global node numbering */
|
||||
int map_unique_to_global(const int unique_id)
|
||||
{return uniqueToGlobalMap_(unique_id);}
|
||||
inline const int* unique_to_global_map(void) {return uniqueToGlobalMap_.get_data();}
|
||||
|
||||
/** query whether a nodeset with the given name exists */
|
||||
bool query_nodeset(const string & name) const;
|
||||
|
||||
/** get node set (unique ID's) from the string name assigned to the set */
|
||||
const set<int> & get_nodeset(const string & name) const;
|
||||
|
||||
/** create node set with tag "name" from nodes in given spatial range */
|
||||
void create_nodeset(const string & name,
|
||||
double xmin, double xmax,
|
||||
double ymin, double ymax,
|
||||
double zmin, double zmax);
|
||||
|
||||
/** get element set from the string name assigned to the set */
|
||||
const set<int> & get_elementset(const string & name) const;
|
||||
|
||||
/** create element set with tag "name" from nodes in given spatial range */
|
||||
void create_elementset(const string & name,
|
||||
double xmin, double xmax,
|
||||
double ymin, double ymax,
|
||||
double zmin, double zmax);
|
||||
|
||||
/** get the minimal element set from a nodeset by name */
|
||||
void nodeset_to_minimal_elementset
|
||||
(const string & name, set<int> & elemSet) const;
|
||||
/** get the maximal element set from a nodeset by name */
|
||||
void nodeset_to_maximal_elementset
|
||||
(const string & name, set<int> & elemSet) const;
|
||||
/** get complement of element set by name */
|
||||
void elementset_complement(const string & name, set<int> & elemSet) const;
|
||||
void elementset_complement(const set<int> & elemSet, set<int> & elemSetComplement) const;
|
||||
/** get the node set from an element set by name */
|
||||
void elementset_to_minimal_nodeset
|
||||
(const string & name, set<int> & nodeSet) const;
|
||||
void elementset_to_nodeset(const string & name, set<int> & nodeSet) const;
|
||||
void elementset_to_nodeset(const set<int> & elemSet, set<int> & nodeSet) const;
|
||||
/** convert faceset to nodeset in _unique_node numbering */
|
||||
void faceset_to_nodeset(const string &name, set<int> &nodeSet) const;
|
||||
void faceset_to_nodeset_global(const string &name, set<int> &nodeSet) const;
|
||||
|
||||
/** get face set from the string name assigned to the set */
|
||||
const set< pair <int,int> > & get_faceset(const string & name) const;
|
||||
|
||||
/** create face set with tag "name" from faces aligned with box */
|
||||
void create_faceset(const string & name,
|
||||
double xmin, double xmax,
|
||||
double ymin, double ymax,
|
||||
double zmin, double zmax,
|
||||
bool outward);
|
||||
void create_faceset(const string & name, double x, int idir, int isgn);
|
||||
|
||||
/** return number of spatial dimensions */
|
||||
int get_nSpatialDimensions() const { return nSD_; };
|
||||
|
||||
/** return total number of nodes */
|
||||
int get_nNodes() const { return nNodes_; };
|
||||
|
||||
/** return number of unique nodes */
|
||||
int get_nNodesUnique() const { return nNodesUnique_; };
|
||||
|
||||
/** return number of elements */
|
||||
int get_nElements() const { return nElts_; };
|
||||
|
||||
/** return number of integration points per element */
|
||||
int get_nIPsPerElement() const;
|
||||
|
||||
/** return number of nodes per element */
|
||||
int get_nNodesPerElement() const;
|
||||
|
||||
/** return number of faces per element */
|
||||
int get_nFacesPerElement() const;
|
||||
|
||||
/** return number of nodes per face */
|
||||
int get_nNodesPerFace() const;
|
||||
|
||||
/** return number of integration points per face */
|
||||
int get_nIPsPerFace() const;
|
||||
|
||||
/** return scale in x */
|
||||
double get_xscale() const {return xscale_;}
|
||||
|
||||
/** return scale in y */
|
||||
double get_yscale() const {return yscale_;}
|
||||
|
||||
/** return scale in z */
|
||||
double get_zscale() const {return zscale_;}
|
||||
|
||||
/** local face connectivity */
|
||||
const Array2D<int> & local_face_connectivity() const;
|
||||
|
||||
/** element size in each direction */
|
||||
virtual void element_size(const int ielem,
|
||||
double hx, double hy, double hz) = 0;
|
||||
|
||||
/** element size in each direction */
|
||||
virtual double min_element_size(void) const = 0;
|
||||
|
||||
/** set quadrature on element : a pass-through */
|
||||
void set_quadrature(int type);
|
||||
|
||||
/** output mesh subsets */
|
||||
void output(string prefix) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** number of spatial dimensions */
|
||||
int nSD_;
|
||||
|
||||
/** number of elements */
|
||||
int nElts_;
|
||||
|
||||
/** number of nodes */
|
||||
int nNodes_;
|
||||
int nNodesUnique_;
|
||||
|
||||
/** periodicity flags */
|
||||
int periodicFlag_[3];
|
||||
|
||||
/** element type for this mesh */
|
||||
FE_Element *feElement_;
|
||||
|
||||
/** Nodal coordinates: nodalCoords_(nsd, numnode) */
|
||||
DENS_MAT nodalCoords_;
|
||||
|
||||
/** Element connectivity: connectivity_(neltnode, nelt) */
|
||||
Array2D<int> connectivity_;
|
||||
Array2D<int> connectivityUnique_;
|
||||
|
||||
/** map of global to unique node ID's */
|
||||
Array<int> globalToUniqueMap_;
|
||||
|
||||
/** map of unique to global node ID's */
|
||||
Array<int> uniqueToGlobalMap_;
|
||||
|
||||
/** map of string names to node sets */
|
||||
NODE_SET_MAP nodeSetMap_;
|
||||
|
||||
/** maximal nodeset */
|
||||
set<int> nodeSetAll_;
|
||||
|
||||
/** map of string names to node sets */
|
||||
FACE_SET_MAP faceSetMap_;
|
||||
|
||||
/** map of string names to element sets */
|
||||
ELEMENT_SET_MAP elementSetMap_;
|
||||
|
||||
/** maximal elementset */
|
||||
set<int> elementSetAll_;
|
||||
|
||||
/** length scaling used by lammps */
|
||||
double xscale_, yscale_, zscale_;
|
||||
|
||||
/** scratch memory for setting face connectivities */
|
||||
Array<int> connScratch_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class FE_Uniform3DMesh
|
||||
* @brief Derived class for a uniform mesh, a structured mesh with
|
||||
* fixed element sizes in x, y, and z directions
|
||||
*/
|
||||
|
||||
class FE_Uniform3DMesh : public FE_Mesh {
|
||||
|
||||
public:
|
||||
|
||||
/** constructor */
|
||||
FE_Uniform3DMesh(const int nx,
|
||||
const int ny,
|
||||
const int nz,
|
||||
double xmin, double xmax,
|
||||
double ymin, double ymax,
|
||||
double zmin, double zmax,
|
||||
double xscale,
|
||||
double yscale,
|
||||
double zscale,
|
||||
int xperiodic,
|
||||
int yperiodic,
|
||||
int zperiodic);
|
||||
|
||||
/** destructor */
|
||||
~FE_Uniform3DMesh();
|
||||
|
||||
virtual void element_size(const int ielem,
|
||||
double hx, double hy, double hz)
|
||||
{ hx = Lx_[0]/nx_[0]; hy = Lx_[1]/nx_[1]; hz = Lx_[2]/nx_[2]; }
|
||||
|
||||
virtual double min_element_size(void) const
|
||||
{return min(Lx_[0]/nx_[0], min(Lx_[1]/nx_[1], Lx_[2]/nx_[2])); }
|
||||
|
||||
/** map spatial location to element */
|
||||
virtual int map_to_element(const DENS_VEC & x) const;
|
||||
|
||||
/** map spatial location to element and local coordinates */
|
||||
virtual int map_to_element(const DENS_VEC & x,
|
||||
DENS_VEC & xi) const;
|
||||
|
||||
/** map spatial location to element and local coordinates */
|
||||
virtual int map_to_element(const DENS_VEC & x,
|
||||
DENS_VEC & xi,
|
||||
const Array<bool> & periodicity) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Number of elements in each spatial direction
|
||||
int nx_[3];
|
||||
|
||||
// Bounds of region on which mesh is defined
|
||||
double borders_[2][3];
|
||||
|
||||
// Region size in each direction
|
||||
double Lx_[3];
|
||||
|
||||
// Element size in each direction
|
||||
double dx_[3];
|
||||
|
||||
/** create global-to-unique node mapping */
|
||||
void setup_periodicity();
|
||||
|
||||
};
|
||||
|
||||
}; // namespace ATC_Transfer
|
||||
|
||||
#endif // FE_MESH_H
|
|
@ -1,101 +0,0 @@
|
|||
// Header file for this class
|
||||
#include "FieldEulerIntegrator.h"
|
||||
|
||||
// Other ATC includes
|
||||
#include "ATC_Transfer.h"
|
||||
#include "FE_Engine.h"
|
||||
#include "PhysicsModel.h"
|
||||
#include "GMRES.h"
|
||||
#include "ImplicitSolveOperator.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// ====================================================================
|
||||
// FieldEulerIntegrator
|
||||
// ====================================================================
|
||||
FieldEulerIntegrator::FieldEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask // copy
|
||||
)
|
||||
: atc_(atcTransfer),
|
||||
feEngine_(feEngine),
|
||||
physicsModel_(physicsModel),
|
||||
fieldName_(fieldName),
|
||||
rhsMask_(rhsMask)
|
||||
{
|
||||
nNodes_ = feEngine->get_nNodes();
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// FieldImplicitIntegrator
|
||||
// ====================================================================
|
||||
FieldExplicitEulerIntegrator::FieldExplicitEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask // copy
|
||||
) : FieldEulerIntegrator(fieldName,physicsModel,feEngine,atcTransfer,rhsMask)
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// update
|
||||
// --------------------------------------------------------------------
|
||||
void FieldExplicitEulerIntegrator::update(const double dt, double time,
|
||||
FIELDS & fields, FIELDS & rhs)
|
||||
{ // NOTE time is not used
|
||||
atc_->compute_rhs_vector(rhsMask_, fields, rhs,
|
||||
atc_->FULL_DOMAIN, physicsModel_);
|
||||
atc_->apply_inverse_mass_matrix(rhs[fieldName_],fieldName_);
|
||||
fields[fieldName_] += dt*rhs[fieldName_];
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// FieldImplicitEulerIntegrator
|
||||
// ====================================================================
|
||||
FieldImplicitEulerIntegrator::FieldImplicitEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask, // copy
|
||||
const double alpha
|
||||
) : FieldEulerIntegrator(fieldName,physicsModel,feEngine,atcTransfer,rhsMask),
|
||||
alpha_(alpha),
|
||||
dT_(1.0e-6),
|
||||
maxRestarts_(50),
|
||||
maxIterations_(200),
|
||||
tol_(1.0e-8)
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// update
|
||||
// --------------------------------------------------------------------
|
||||
void FieldImplicitEulerIntegrator::update(const double dt, double time,
|
||||
FIELDS & fields, FIELDS & rhs)
|
||||
{ // solver handles bcs
|
||||
FieldImplicitSolveOperator solver(atc_, feEngine_, // NOTE make persistent
|
||||
fields, fieldName_, rhsMask_, physicsModel_,
|
||||
time, dt, alpha_);
|
||||
DiagonalMatrix<double> preconditioner = solver.get_preconditioner(fields);
|
||||
DENS_VEC myRhs = solver.get_rhs();
|
||||
DENS_VEC dT(nNodes_); dT = dT_;
|
||||
DENS_MAT H(maxRestarts_+1, maxRestarts_);
|
||||
double tol = tol_; // tol returns the residual
|
||||
int iterations = maxIterations_; // iterations returns number of iterations
|
||||
int restarts = maxRestarts_;
|
||||
int convergence = GMRES(solver,
|
||||
dT, myRhs, preconditioner, H, restarts, iterations, tol);
|
||||
if (convergence != 0) {
|
||||
throw ATC_Error(0,field_to_string(fieldName_) + " evolution did not converge");
|
||||
}
|
||||
fields[fieldName_] += dT;
|
||||
rhs[fieldName_] = myRhs;
|
||||
}
|
||||
|
||||
} // namespace ATC
|
|
@ -1,138 +0,0 @@
|
|||
#ifndef FIELD_EULER_INTEGRATOR_H
|
||||
#define FIELD_EULER_INTEGRATOR_H
|
||||
|
||||
// ATC includes
|
||||
#include "Array2D.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "PhysicsModel.h"
|
||||
#include "TimeIntegrator.h"
|
||||
#include "ImplicitSolveOperator.h"
|
||||
|
||||
// other includes
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// Forward class declarations
|
||||
class ATC_Transfer;
|
||||
class FE_Engine;
|
||||
|
||||
/**
|
||||
* @class FieldEulerIntegrator
|
||||
* @brief method for integrating fast fields
|
||||
*/
|
||||
//class FieldEulerIntegrator : public TimeIntegrator { // NOTE need to construct
|
||||
class FieldEulerIntegrator {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
FieldEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask // copy
|
||||
);
|
||||
|
||||
|
||||
/** Destructor */
|
||||
virtual ~FieldEulerIntegrator() {};
|
||||
|
||||
/** update */
|
||||
virtual void update(const double dt, const double time,
|
||||
FIELDS & fields, FIELDS & rhs) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** Pointer to ATC_Tranfer */
|
||||
ATC_Transfer * atc_;
|
||||
|
||||
/** Pointer to FE_Engine */
|
||||
/*const*/ FE_Engine * feEngine_;
|
||||
|
||||
/** Pointer to PhysicsModel */
|
||||
const PhysicsModel * physicsModel_;
|
||||
|
||||
/** field name */
|
||||
FieldName fieldName_;
|
||||
|
||||
/** rhs mask */
|
||||
Array2D <bool> rhsMask_;
|
||||
|
||||
/** number of nodes */
|
||||
int nNodes_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class FieldExplicitEulerIntegrator
|
||||
* @brief explicit Euler method for integrating fast electron fields
|
||||
*/
|
||||
class FieldExplicitEulerIntegrator : public FieldEulerIntegrator {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
FieldExplicitEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask // copy
|
||||
);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~FieldExplicitEulerIntegrator() {};
|
||||
|
||||
/** update */
|
||||
void update(const double dt, const double time,
|
||||
FIELDS & fields, FIELDS & rhs);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class FieldImplicitEulerIntegrator
|
||||
* @brief explicit Euler method for integrating fast electron fields
|
||||
*/
|
||||
class FieldImplicitEulerIntegrator : public FieldEulerIntegrator {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
FieldImplicitEulerIntegrator(
|
||||
const FieldName fieldName,
|
||||
const PhysicsModel * physicsModel,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
/*const*/ ATC_Transfer * atcTransfer,
|
||||
const Array2D< bool > & rhsMask, // copy
|
||||
const double alpha = 0.5 // default to trap/midpt
|
||||
);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~FieldImplicitEulerIntegrator() {};
|
||||
|
||||
/** update */
|
||||
void update(const double dt, const double time,
|
||||
FIELDS & fields, FIELDS & rhs);
|
||||
|
||||
protected:
|
||||
/** euler update factor */
|
||||
double alpha_;
|
||||
|
||||
/** perturbation */
|
||||
double dT_;
|
||||
|
||||
/** max number of restarts = size of basis */
|
||||
int maxRestarts_;
|
||||
|
||||
/** max number of iterations */
|
||||
int maxIterations_;
|
||||
|
||||
/** convergence tolerance */
|
||||
double tol_;
|
||||
};
|
||||
|
||||
} // namespace ATC
|
||||
|
||||
#endif
|
150
lib/atc/GMRES.h
150
lib/atc/GMRES.h
|
@ -1,150 +0,0 @@
|
|||
//*****************************************************************
|
||||
// Iterative template routine -- GMRES
|
||||
//
|
||||
// GMRES solves the unsymmetric linear system Ax = b using the
|
||||
// Generalized Minimum Residual method
|
||||
//
|
||||
// GMRES follows the algorithm described on p. 20 of the
|
||||
// SIAM Templates book.
|
||||
//
|
||||
// The return value indicates convergence within max_iter (input)
|
||||
// iterations (0), or no convergence within max_iter iterations (1).
|
||||
//
|
||||
// Upon successful return, output arguments have the following values:
|
||||
//
|
||||
// x -- approximate solution to Ax = b
|
||||
// max_iter -- the number of iterations performed before the
|
||||
// tolerance was reached
|
||||
// tol -- the residual after the final iteration
|
||||
//
|
||||
//*****************************************************************
|
||||
|
||||
|
||||
template < class Matrix, class Vector >
|
||||
void
|
||||
Update(Vector &x, int k, Matrix &h, Vector &s, Vector v[])
|
||||
{
|
||||
Vector y(s);
|
||||
|
||||
// Backsolve:
|
||||
for (int i = k; i >= 0; i--) {
|
||||
y(i) /= h(i,i);
|
||||
for (int j = i - 1; j >= 0; j--)
|
||||
y(j) -= h(j,i) * y(i);
|
||||
}
|
||||
|
||||
for (int j = 0; j <= k; j++)
|
||||
x += v[j] * y(j);
|
||||
}
|
||||
|
||||
|
||||
template < class Real >
|
||||
Real
|
||||
abs(Real x)
|
||||
{
|
||||
return (x > 0 ? x : -x);
|
||||
}
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
template<class Real>
|
||||
void GeneratePlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
|
||||
{
|
||||
if (dy == 0.0) {
|
||||
cs = 1.0;
|
||||
sn = 0.0;
|
||||
} else if (abs(dy) > abs(dx)) {
|
||||
Real temp = dx / dy;
|
||||
sn = 1.0 / sqrt( 1.0 + temp*temp );
|
||||
cs = temp * sn;
|
||||
} else {
|
||||
Real temp = dy / dx;
|
||||
cs = 1.0 / sqrt( 1.0 + temp*temp );
|
||||
sn = temp * cs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Real>
|
||||
void ApplyPlaneRotation(Real &dx, Real &dy, Real &cs, Real &sn)
|
||||
{
|
||||
Real temp = cs * dx + sn * dy;
|
||||
dy = -sn * dx + cs * dy;
|
||||
dx = temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template < class Operator, class Vector, class Preconditioner,
|
||||
class Matrix, class Real >
|
||||
int
|
||||
GMRES(const Operator &A, Vector &x, const Vector &b,
|
||||
const Preconditioner &M, Matrix &H, int &m, int &max_iter,
|
||||
Real &tol)
|
||||
{
|
||||
Real resid;
|
||||
int i, j = 1, k;
|
||||
Vector s(m+1), cs(m+1), sn(m+1), w;
|
||||
|
||||
Vector p = inv(M)*b;
|
||||
Real normb = p.norm();
|
||||
Vector r = inv(M) * (b - A * x);
|
||||
Real beta = r.norm();
|
||||
|
||||
if (normb == 0.0)
|
||||
normb = 1;
|
||||
|
||||
if ((resid = r.norm() / normb) <= tol) {
|
||||
tol = resid;
|
||||
max_iter = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vector *v = new Vector[m+1];
|
||||
|
||||
while (j <= max_iter) {
|
||||
v[0] = r * (1.0 / beta); // ??? r / beta
|
||||
s = 0.0;
|
||||
s(0) = beta;
|
||||
|
||||
for (i = 0; i < m && j <= max_iter; i++, j++) {
|
||||
w = inv(M) * (A * v[i]);
|
||||
for (k = 0; k <= i; k++) {
|
||||
H(k, i) = w.dot(v[k]);
|
||||
w -= H(k, i) * v[k];
|
||||
}
|
||||
H(i+1, i) = w.norm();
|
||||
v[i+1] = w * (1.0 / H(i+1, i)); // ??? w / H(i+1, i)
|
||||
|
||||
for (k = 0; k < i; k++)
|
||||
ApplyPlaneRotation(H(k,i), H(k+1,i), cs(k), sn(k));
|
||||
|
||||
GeneratePlaneRotation(H(i,i), H(i+1,i), cs(i), sn(i));
|
||||
ApplyPlaneRotation(H(i,i), H(i+1,i), cs(i), sn(i));
|
||||
ApplyPlaneRotation(s(i), s(i+1), cs(i), sn(i));
|
||||
|
||||
if ((resid = abs(s(i+1)) / normb) < tol) {
|
||||
Update(x, i, H, s, v);
|
||||
tol = resid;
|
||||
max_iter = j;
|
||||
delete [] v;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Update(x, m - 1, H, s, v);
|
||||
r = inv(M) * (b - A * x);
|
||||
beta = r.norm();
|
||||
if ((resid = beta / normb) < tol) {
|
||||
tol = resid;
|
||||
max_iter = j;
|
||||
delete [] v;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
tol = resid;
|
||||
delete [] v;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
// Header file for this class
|
||||
#include "ImplicitSolveOperator.h"
|
||||
|
||||
// Other ATC includes
|
||||
#include "ATC_Transfer.h"
|
||||
#include "FE_Engine.h"
|
||||
#include "PhysicsModel.h"
|
||||
#include "PrescribedDataManager.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// ImplicitSolveOperator
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
ImplicitSolveOperator::
|
||||
ImplicitSolveOperator(ATC_Transfer * atcTransfer,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
const PhysicsModel * physicsModel)
|
||||
: atcTransfer_(atcTransfer),
|
||||
feEngine_(feEngine),
|
||||
physicsModel_(physicsModel)
|
||||
{
|
||||
// Nothing else to do here
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
// FieldImplicitSolveOperator
|
||||
// --------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------
|
||||
FieldImplicitSolveOperator::
|
||||
FieldImplicitSolveOperator(ATC_Transfer * atcTransfer,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
FIELDS & fields,
|
||||
const FieldName fieldName,
|
||||
const Array2D< bool > & rhsMask,
|
||||
const PhysicsModel * physicsModel,
|
||||
double simTime,
|
||||
double dt,
|
||||
double alpha)
|
||||
: ImplicitSolveOperator(atcTransfer, feEngine, physicsModel),
|
||||
fields_(fields), // ref to fields
|
||||
fieldName_(fieldName),
|
||||
simTime_(simTime),
|
||||
dt_(dt),
|
||||
alpha_(alpha),
|
||||
epsilon0_(1.0e-8)
|
||||
{
|
||||
// find field associated with ODE
|
||||
rhsMask_.reset(NUM_FIELDS,NUM_FLUX);
|
||||
rhsMask_ = false;
|
||||
for (int i = 0; i < rhsMask.nCols(); i++) {
|
||||
rhsMask_(fieldName_,i) = rhsMask(fieldName_,i);
|
||||
}
|
||||
massMask_.reset(1);
|
||||
massMask_(0) = fieldName_;
|
||||
|
||||
// Save off current field
|
||||
TnVect_ = column(fields_[fieldName_],0); // NOTE assuming 1 dof ?
|
||||
|
||||
// Allocate vectors for fields and rhs
|
||||
int nNodes = atcTransfer_->get_nNodes();
|
||||
// copy fields
|
||||
fieldsNp1_ = fields_;
|
||||
// size rhs
|
||||
int dof = fields_[fieldName_].nCols();
|
||||
RnMap_ [fieldName_].reset(nNodes,dof);
|
||||
RnpMap_[fieldName_].reset(nNodes,dof);
|
||||
|
||||
// Compute the RHS vector R(T^n)
|
||||
// Set BCs on Rn, multiply by inverse mass and then extract its vector
|
||||
atcTransfer_->compute_rhs_vector(rhsMask_, fields_, RnMap_,
|
||||
atcTransfer_->FULL_DOMAIN, physicsModel_);
|
||||
DENS_MAT & Rn = RnMap_[fieldName_];
|
||||
atcTransfer_->get_prescribed_data_manager()
|
||||
->set_fixed_dfield(simTime_, fieldName_, Rn);
|
||||
atcTransfer_->apply_inverse_mass_matrix(Rn,fieldName_);
|
||||
RnVect_ = column(Rn,0);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// operator *(Vector)
|
||||
// --------------------------------------------------------------------
|
||||
DENS_VEC
|
||||
FieldImplicitSolveOperator::operator * (DENS_VEC x) const
|
||||
{
|
||||
// This method uses a matrix-free approach to approximate the
|
||||
// multiplication by matrix A in the matrix equation Ax=b, where the
|
||||
// matrix equation results from an implicit treatment of the
|
||||
// fast field solve for the Two Temperature Model. In
|
||||
// brief, if the ODE for the fast field can be written:
|
||||
//
|
||||
// dT/dt = R(T)
|
||||
//
|
||||
// A generalized discretization can be written:
|
||||
//
|
||||
// 1/dt * (T^n+1 - T^n) = alpha * R(T^n+1) + (1-alpha) * R(T^n)
|
||||
//
|
||||
// Taylor expanding the R(T^n+1) term and rearranging gives the
|
||||
// equation to be solved for dT at each timestep:
|
||||
//
|
||||
// [1 - dt * alpha * dR/dT] * dT = dt * R(T^n)
|
||||
//
|
||||
// The operator defined in this method computes the left-hand side,
|
||||
// given a vector dT. It uses a finite difference, matrix-free
|
||||
// approximation of dR/dT * dT, giving:
|
||||
//
|
||||
// [1 - dt * alpha * dR/dT] * dT = dt * R(T^n)
|
||||
// ~= dT - dt*alpha/epsilon * ( R(T^n + epsilon*dT) - R(T^n) )
|
||||
//
|
||||
|
||||
|
||||
// Compute epsilon
|
||||
double epsilon = (x.norm() > 0.0) ? epsilon0_ * TnVect_.norm()/x.norm() : epsilon0_;
|
||||
|
||||
// Compute incremented vector = T + epsilon*dT
|
||||
fieldsNp1_[fieldName_] = TnVect_ + epsilon * x;
|
||||
|
||||
// Evaluate R(b)
|
||||
atcTransfer_->compute_rhs_vector(rhsMask_, fieldsNp1_, RnpMap_,
|
||||
atcTransfer_->FULL_DOMAIN, physicsModel_);
|
||||
DENS_MAT & Rnp = RnpMap_[fieldName_];
|
||||
atcTransfer_->get_prescribed_data_manager()
|
||||
->set_fixed_dfield(simTime_, fieldName_, Rnp);
|
||||
atcTransfer_->apply_inverse_mass_matrix(Rnp,fieldName_);
|
||||
RnpVect_ = column(Rnp,0);
|
||||
|
||||
// Compute full left hand side and return it
|
||||
DENS_VEC Ax = x - dt_ * alpha_ / epsilon * (RnpVect_ - RnVect_);
|
||||
return Ax;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// get_rhs
|
||||
// --------------------------------------------------------------------
|
||||
DENS_VEC
|
||||
FieldImplicitSolveOperator::get_rhs()
|
||||
{
|
||||
// Return dt * R(T^n)
|
||||
return dt_ * RnVect_;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// get_preconditioner
|
||||
// --------------------------------------------------------------------
|
||||
DIAG_MAT
|
||||
FieldImplicitSolveOperator::get_preconditioner(FIELDS & fields)
|
||||
{
|
||||
// Just create and return identity matrix
|
||||
int nNodes = atcTransfer_->get_nNodes();
|
||||
DENS_VEC ones(nNodes);
|
||||
ones = 1.0;
|
||||
DIAG_MAT identity(ones);
|
||||
return identity;
|
||||
}
|
||||
|
||||
} // namespace ATC
|
|
@ -1,129 +0,0 @@
|
|||
#ifndef IMPLICIT_SOLVE_OPERATOR_H
|
||||
#define IMPLICIT_SOLVE_OPERATOR_H
|
||||
|
||||
// ATC includes
|
||||
#include "Array2D.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "PhysicsModel.h"
|
||||
|
||||
// other includes
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
// Forward class declarations
|
||||
class ATC_Transfer;
|
||||
class FE_Engine;
|
||||
|
||||
/**
|
||||
* @class ImplicitSolveOperator
|
||||
* @brief Helper class to compute matrix-free product for use with IML++ solvers
|
||||
*/
|
||||
class ImplicitSolveOperator {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
ImplicitSolveOperator(ATC_Transfer * atcTransfer,
|
||||
/*const*/ FE_Engine * feEngine,
|
||||
const PhysicsModel * physicsModel);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~ImplicitSolveOperator() {};
|
||||
|
||||
/** pure virtual operator to compute Ax, for equation Ax=b */
|
||||
virtual DENS_VEC operator * (DENS_VEC x) const = 0;
|
||||
|
||||
/** pure virtual method to return the rhs vector b */
|
||||
virtual DENS_VEC get_rhs() = 0;
|
||||
|
||||
/** pure virtual method to return preconditioner */
|
||||
virtual DiagonalMatrix<double> get_preconditioner(FIELDS & fields) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** Pointer to ATC_Tranfer */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** Pointer to FE_Engine */
|
||||
/*const*/ FE_Engine * feEngine_;
|
||||
|
||||
/** Pointer to PhysicsModel */
|
||||
const PhysicsModel * physicsModel_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class FieldImplicitSolveOperator
|
||||
* @brief Class to perform A*x operation for electron temperature solution
|
||||
*/
|
||||
class FieldImplicitSolveOperator : public ImplicitSolveOperator {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
FieldImplicitSolveOperator(ATC_Transfer * atc_Transfer,
|
||||
/*const*/ FE_Engine * fe_Engine,
|
||||
FIELDS & fields,
|
||||
const FieldName electronField,
|
||||
const Array2D< bool > & rhsMask,
|
||||
const PhysicsModel * physicsModel,
|
||||
double simTime,
|
||||
double dt,
|
||||
double alpha);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~FieldImplicitSolveOperator() {};
|
||||
|
||||
/** operator to compute A*x for the electron temperature equation */
|
||||
virtual DENS_VEC operator * (DENS_VEC x) const;
|
||||
|
||||
/** method to return the rhs vector b */
|
||||
virtual DENS_VEC get_rhs();
|
||||
|
||||
/** method to return preconditioner (identity matrix) */
|
||||
virtual DIAG_MAT get_preconditioner(FIELDS & fields);
|
||||
|
||||
protected:
|
||||
// field name of ODE to solve
|
||||
FieldName fieldName_;
|
||||
|
||||
// Reference to current fields (passed in constructor)
|
||||
FIELDS & fields_;
|
||||
|
||||
// Local fields
|
||||
mutable FIELDS fieldsNp1_;
|
||||
|
||||
// Vector to hold current temperature
|
||||
DENS_VEC TnVect_;
|
||||
|
||||
// Old and new RHS maps (not including inverse mass)
|
||||
FIELDS RnMap_;
|
||||
mutable FIELDS RnpMap_;
|
||||
|
||||
// Matrices/vectors to hold electron temperature components of RHS
|
||||
// vectors (including inverse mass)
|
||||
DENS_VEC RnVect_;
|
||||
mutable DENS_VEC RnpVect_;
|
||||
|
||||
Array2D<bool> rhsMask_;
|
||||
Array<FieldName> massMask_;
|
||||
|
||||
// simulation time
|
||||
double simTime_;
|
||||
|
||||
// timestep
|
||||
double dt_;
|
||||
|
||||
// implicit/explicit parameter (0 -> explicit, else implicit)
|
||||
double alpha_;
|
||||
|
||||
// small parameter to compute increment
|
||||
double epsilon0_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ATC
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,488 +0,0 @@
|
|||
#ifndef KINETOSTAT_H
|
||||
#define KINETOSTAT_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "AtomicRegulator.h"
|
||||
|
||||
// other headers
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
/**
|
||||
* @class Kinetostat
|
||||
* @brief Manager class for atom-continuum control of momentum and position
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class Kinetostat
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class Kinetostat : public AtomicRegulator {
|
||||
|
||||
public:
|
||||
|
||||
/** kinetostat types */
|
||||
enum KinetostatType {
|
||||
NONE=0,
|
||||
GLC_DISPLACEMENT,
|
||||
GLC_VELOCITY,
|
||||
FORCE
|
||||
};
|
||||
|
||||
enum KinetostatCouplingType {
|
||||
UNCOUPLED=0,
|
||||
FLUX,
|
||||
FIXED
|
||||
};
|
||||
|
||||
// constructor
|
||||
Kinetostat(ATC_Transfer *atcTransfer);
|
||||
|
||||
// destructor
|
||||
~Kinetostat(){};
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
// data access, intended for method objects
|
||||
/** reset the nodal force to a prescribed value */
|
||||
void reset_lambda_force(DENS_MAT & target);
|
||||
/** return the nodal force induced by lambda */
|
||||
DENS_MAT & get_nodal_atomic_lambda_force() { return nodalAtomicLambdaForce_;}
|
||||
/** return value of filtered lambda */
|
||||
DENS_MAT & get_lambda_force_filtered() { return lambdaForceFiltered_;}
|
||||
/** access to kinetostat type */
|
||||
KinetostatType get_kinetostat_type() const
|
||||
{ return kinetostatType_;};
|
||||
KinetostatCouplingType get_coupling_mode() const
|
||||
{ return couplingMode_;};
|
||||
|
||||
protected:
|
||||
|
||||
/** kinetostat type flag */
|
||||
KinetostatType kinetostatType_;
|
||||
/** kinetostat copuling type flag */
|
||||
KinetostatCouplingType couplingMode_;
|
||||
|
||||
// kinetostat data
|
||||
/** lambda force applied to atoms */
|
||||
DENS_MAT nodalAtomicLambdaForce_;
|
||||
/** filtered lambda force */
|
||||
DENS_MAT lambdaForceFiltered_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
Kinetostat();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class GlcKinetostat
|
||||
* @brief Base class for implementation of kinetostat algorithms based on Gaussian least constraints (GLC)
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class GlcKinetostat
|
||||
// base class for all thermostats of general form of a
|
||||
// Gaussian least constraint (GLC)
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class GlcKinetostat : public RegulatorShapeFunction {
|
||||
|
||||
public:
|
||||
|
||||
GlcKinetostat(Kinetostat *kinetostat);
|
||||
|
||||
~GlcKinetostat(){};
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** apply forces to atoms */
|
||||
virtual void apply_to_atoms(double ** atomicQuantity,
|
||||
const DENS_MAT & lambdaAtom,
|
||||
double dt=0.);
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights);
|
||||
/** apply any required corrections for localized kinetostats */
|
||||
virtual void apply_localization_correction(const DENS_MAT & source,
|
||||
DENS_MAT & nodalField,
|
||||
double weight = 1.){};
|
||||
|
||||
// member data
|
||||
/** pointer to thermostat object for data */
|
||||
Kinetostat * kinetostat_;
|
||||
/** pointer to a time filtering object */
|
||||
TimeFilter * timeFilter_;
|
||||
/** stress induced by lambda */
|
||||
DENS_MAT & nodalAtomicLambdaForce_;
|
||||
/** filtered lambda force */
|
||||
DENS_MAT & lambdaForceFiltered_;
|
||||
/** atomic force induced by lambda */
|
||||
DENS_MAT & lambdaForce_;
|
||||
/** MD mass matrix */
|
||||
MATRIX & mdMassMatrix_;
|
||||
/** mass of ATC internal atoms on this processor */
|
||||
DENS_VEC atomicMass_;
|
||||
/** reference to ATC map from global nodes to overlap nodes */
|
||||
Array<int> & nodeToOverlapMap_;
|
||||
/** nodeset corresponding to Hoover coupling */
|
||||
set<pair<int,int> > hooverNodes_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
GlcKinetostat();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class DisplacementGlc
|
||||
* @brief Enforces GLC on atomic position based on FE displacement
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class DisplacementGlc
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class DisplacementGlc : public GlcKinetostat {
|
||||
|
||||
public:
|
||||
|
||||
DisplacementGlc(Kinetostat * kinetostat);
|
||||
|
||||
~DisplacementGlc(){};
|
||||
|
||||
/** applies kinetostat to atoms */
|
||||
virtual void apply_post_predictor(double dt);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights);
|
||||
/** does initial filtering operations before main computation */
|
||||
virtual void apply_pre_filtering(double dt);
|
||||
/** compute force induced by lambda */
|
||||
virtual void compute_lambda_force(DENS_MAT & lambdaForce, DENS_MAT & lambdaAtom, double dt);
|
||||
/** sets up and solves kinetostat equations */
|
||||
virtual void compute_kinetostat(double dt);
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** computes the nodal FE force applied by the kinetostat */
|
||||
virtual void compute_nodal_lambda_force(double dt);
|
||||
/** apply any required corrections for localized kinetostats */
|
||||
virtual void apply_localization_correction(const DENS_MAT & source,
|
||||
DENS_MAT & nodalField,
|
||||
double weight = 1.);
|
||||
|
||||
// data
|
||||
/** clone of FE displacement field */
|
||||
DENS_MAT & nodalDisplacements_;
|
||||
/** pointer to lammps atomic positions */
|
||||
double ** x_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
DisplacementGlc();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class DisplacementGlcFiltered
|
||||
* @brief Enforces GLC on time filtered atomic position based on FE displacement
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class DisplacementGlcFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class DisplacementGlcFiltered : public DisplacementGlc {
|
||||
|
||||
public:
|
||||
|
||||
DisplacementGlcFiltered(Kinetostat * kinetostat);
|
||||
|
||||
~DisplacementGlcFiltered(){};
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** does initial filtering operations before main computation */
|
||||
virtual void apply_pre_filtering(double dt);
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** computes the nodal FE force applied by the kinetostat */
|
||||
virtual void compute_nodal_lambda_force(double dt);
|
||||
|
||||
// data
|
||||
/** clone of FE nodal atomic displacement field */
|
||||
DENS_MAT & nodalAtomicDisplacements_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
DisplacementGlcFiltered();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class VelocityGlc
|
||||
* @brief Enforces GLC on atomic velocity based on FE velocity
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class VelocityGlc
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class VelocityGlc : public GlcKinetostat {
|
||||
|
||||
public:
|
||||
|
||||
VelocityGlc(Kinetostat * kinetostat);
|
||||
|
||||
~VelocityGlc(){};
|
||||
|
||||
/** applies kinetostat to atoms */
|
||||
virtual void apply_mid_predictor(double dt);
|
||||
|
||||
/** applies kinetostat to atoms */
|
||||
virtual void apply_post_corrector(double dt);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights);
|
||||
/** compute force induced by lambda */
|
||||
virtual void compute_lambda_force(DENS_MAT & lambdaForce, DENS_MAT & lambdaAtom, double dt);
|
||||
/** does initial filtering operations before main computation */
|
||||
virtual void apply_pre_filtering(double dt);
|
||||
/** sets up and solves kinetostat equations */
|
||||
virtual void compute_kinetostat(double dt);
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** computes the nodal FE force applied by the kinetostat */
|
||||
virtual void compute_nodal_lambda_force(double dt);
|
||||
/** apply any required corrections for localized kinetostats */
|
||||
virtual void apply_localization_correction(const DENS_MAT & source,
|
||||
DENS_MAT & nodalField,
|
||||
double weight = 1.);
|
||||
|
||||
// data
|
||||
/** clone of FE velocity field */
|
||||
DENS_MAT & nodalVelocities_;
|
||||
/** pointer to lammps atomic velocities */
|
||||
double ** v_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
VelocityGlc();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class VelocityGlcFiltered
|
||||
* @brief Enforces GLC on time filtered atomic velocity based on FE velocity
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class VelocityGlcFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class VelocityGlcFiltered : public VelocityGlc {
|
||||
|
||||
public:
|
||||
|
||||
VelocityGlcFiltered(Kinetostat * kinetostat);
|
||||
|
||||
~VelocityGlcFiltered(){};
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** does initial filtering operations before main computation */
|
||||
virtual void apply_pre_filtering(double dt);
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** computes the nodal FE force applied by the kinetostat */
|
||||
virtual void compute_nodal_lambda_force(double dt);
|
||||
|
||||
// data
|
||||
/** clone of FE nodal atomic velocity field */
|
||||
DENS_MAT & nodalAtomicVelocities_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
VelocityGlcFiltered();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class StressFlux
|
||||
* @brief Enforces GLC on atomic forces based on FE stresses or accelerations
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class StressFlux
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class StressFlux : public GlcKinetostat {
|
||||
|
||||
public:
|
||||
|
||||
StressFlux(Kinetostat * kinetostat);
|
||||
|
||||
~StressFlux();
|
||||
|
||||
/** applies kinetostat to atoms in the mid-predictor phase */
|
||||
virtual void apply_mid_predictor(double dt);
|
||||
|
||||
/** applies kinetostat to atoms in the pre-corrector phase */
|
||||
virtual void apply_pre_corrector(double dt);
|
||||
|
||||
/** applies kinetostat to atoms in the post-corrector phase */
|
||||
virtual void apply_post_corrector(double dt);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
/** sets filtered ghost force to prescribed value */
|
||||
void reset_filtered_ghost_force(DENS_MAT & targetForce);
|
||||
/** returns reference to filtered ghost force */
|
||||
DENS_MAT & get_filtered_ghost_force() {return nodalGhostForceFiltered_;};
|
||||
|
||||
protected:
|
||||
|
||||
// data
|
||||
/** nodal force */
|
||||
DENS_MAT & nodalForce_;
|
||||
/** nodal force due to atoms */
|
||||
DENS_MAT & nodalAtomicForce_;
|
||||
/** nodal ghost force */
|
||||
DENS_MAT nodalGhostForce_;
|
||||
/** filtered ghost force */
|
||||
DENS_MAT nodalGhostForceFiltered_;
|
||||
/** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */
|
||||
DENS_MAT & momentumSource_;
|
||||
/** pointer to lammps atomic velocities */
|
||||
double ** v_;
|
||||
/** pointer to lammps atomic forces */
|
||||
double ** f_;
|
||||
#if false
|
||||
/** initial lammps atomic forces */
|
||||
double ** f0_;
|
||||
#endif
|
||||
|
||||
// methods
|
||||
/** compute force induced by lambda */
|
||||
virtual void compute_lambda_force(DENS_MAT & lambdaForce);
|
||||
/** does initial filtering operations before main computation */
|
||||
virtual void apply_pre_filtering(double dt);
|
||||
/** sets up and solves kinetostat equations */
|
||||
virtual void compute_kinetostat(double dt);
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** computes the nodal FE force applied by the kinetostat */
|
||||
virtual void compute_nodal_lambda_force(double dt);
|
||||
/** apply forces to atoms */
|
||||
virtual void apply_to_atoms(double ** atomicVelocity,
|
||||
const DENS_MAT & lambdaForce,
|
||||
double dt);
|
||||
/** adds in finite element rhs contributions */
|
||||
virtual void add_to_rhs(FIELDS & rhs);
|
||||
/** computes restricted force on ghost atoms */
|
||||
void compute_ghost_force(DENS_MAT & nodalGhostForce);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
StressFlux();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class StressFluxFiltered
|
||||
* @brief Enforces GLC on time filtered atomic forces based on FE stresses or accelerations
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class StressFluxFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class StressFluxFiltered : public StressFlux {
|
||||
|
||||
public:
|
||||
|
||||
StressFluxFiltered(Kinetostat * kinetostat);
|
||||
|
||||
~StressFluxFiltered(){};
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
// data
|
||||
DENS_MAT & nodalAtomicVelocity_;
|
||||
|
||||
// methods
|
||||
/** sets up appropriate rhs for kinetostat equations */
|
||||
virtual void set_kinetostat_rhs(DENS_MAT & rhs, double dt);
|
||||
/** adds in finite element rhs contributions */
|
||||
virtual void add_to_rhs(FIELDS & rhs);
|
||||
/** apply forces to atoms */
|
||||
virtual void apply_to_atoms(double ** atomicVelocity,
|
||||
const DENS_MAT & lambdaForce,
|
||||
double dt);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
StressFluxFiltered();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,671 +0,0 @@
|
|||
// Header file for this class
|
||||
#include "LammpsInterface.h"
|
||||
|
||||
// LAMMPS includes
|
||||
#include "lammps.h"
|
||||
#include "lmptype.h"
|
||||
#include "atom.h" // x, v, f
|
||||
#include "domain.h" // for basing locations on regions
|
||||
#include "region.h" // region bounding box and style
|
||||
#include "force.h" // boltzman constant
|
||||
#include "group.h" // atom masks
|
||||
#include "memory.h" // grow atom information
|
||||
#include "compute.h" // computes
|
||||
#include "modify.h" //
|
||||
#include "neighbor.h" // neighbors
|
||||
#include "neigh_list.h" // neighbor list
|
||||
#include "update.h" // timestepping information
|
||||
#include "pair.h" // pair potentials
|
||||
#include "lattice.h" // lattice parameters
|
||||
#include "comm.h" //
|
||||
|
||||
// ATC includes
|
||||
#include "ATC_Error.h"
|
||||
#include "MatrixLibrary.h"
|
||||
|
||||
// Other include files
|
||||
#include "mpi.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
|
||||
LammpsInterface * LammpsInterface::myInstance_ = NULL;
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// instance()
|
||||
// -----------------------------------------------------------------
|
||||
LammpsInterface * LammpsInterface::instance()
|
||||
{
|
||||
if (myInstance_ == NULL) {
|
||||
myInstance_ = new LammpsInterface();
|
||||
}
|
||||
return myInstance_;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// constructor
|
||||
// -----------------------------------------------------------------
|
||||
LammpsInterface::LammpsInterface()
|
||||
: lammps_(NULL),
|
||||
atomPE_(NULL),
|
||||
commRank_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// general interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
MPI_Comm LammpsInterface::world() { return lammps_->world; }
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// atom interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
int LammpsInterface::nlocal() { return lammps_->atom->nlocal; }
|
||||
|
||||
int LammpsInterface::nghost() { return lammps_->atom->nghost; }
|
||||
|
||||
double LammpsInterface::natoms() { return lammps_->atom->natoms; }
|
||||
|
||||
int LammpsInterface::nmax() { return lammps_->atom->nmax; }
|
||||
|
||||
int LammpsInterface::ntypes() { return lammps_->atom->ntypes; }
|
||||
|
||||
double ** LammpsInterface::xatom() { return lammps_->atom->x; }
|
||||
|
||||
const double ** LammpsInterface::xatom() const { return (const double**)(lammps_->atom->x); }
|
||||
|
||||
double ** LammpsInterface::vatom() { return lammps_->atom->v; }
|
||||
|
||||
double ** LammpsInterface::fatom() { return lammps_->atom->f; }
|
||||
|
||||
int * LammpsInterface::atom_mask() { return lammps_->atom->mask; }
|
||||
|
||||
int * LammpsInterface::atom_type() { return lammps_->atom->type; }
|
||||
|
||||
int * LammpsInterface::atom_tag() { return lammps_->atom->tag; }
|
||||
|
||||
double * LammpsInterface::atom_mass() { return lammps_->atom->mass; }
|
||||
|
||||
double LammpsInterface::atom_mass(int iType) { return lammps_->atom->mass[iType]; }
|
||||
|
||||
double * LammpsInterface::atom_rmass() { return lammps_->atom->rmass; }
|
||||
|
||||
double * LammpsInterface::atom_charge() { return lammps_->atom->q; }
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// domain interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
int LammpsInterface::dimension() { return lammps_->domain->dimension; }
|
||||
|
||||
int LammpsInterface::nregion() { return lammps_->domain->nregion; }
|
||||
|
||||
void LammpsInterface::get_box_bounds(double & boxxlo, double & boxxhi,
|
||||
double & boxylo, double & boxyhi,
|
||||
double & boxzlo, double &boxzhi)
|
||||
{
|
||||
if (lammps_->domain->triclinic == 0) {
|
||||
boxxlo = lammps_->domain->boxlo[0];
|
||||
boxxhi = lammps_->domain->boxhi[0];
|
||||
boxylo = lammps_->domain->boxlo[1];
|
||||
boxyhi = lammps_->domain->boxhi[1];
|
||||
boxzlo = lammps_->domain->boxlo[2];
|
||||
boxzhi = lammps_->domain->boxhi[2];
|
||||
}
|
||||
else {
|
||||
boxxlo = lammps_->domain->boxlo_bound[0];
|
||||
boxxhi = lammps_->domain->boxhi_bound[0];
|
||||
boxylo = lammps_->domain->boxlo_bound[1];
|
||||
boxyhi = lammps_->domain->boxhi_bound[1];
|
||||
boxzlo = lammps_->domain->boxlo_bound[2];
|
||||
boxzhi = lammps_->domain->boxhi_bound[2];
|
||||
}
|
||||
}
|
||||
|
||||
int LammpsInterface::xperiodic() { return lammps_->domain->xperiodic; }
|
||||
|
||||
int LammpsInterface::yperiodic() { return lammps_->domain->yperiodic; }
|
||||
|
||||
int LammpsInterface::zperiodic() { return lammps_->domain->zperiodic; }
|
||||
|
||||
int LammpsInterface::nperiodic()
|
||||
{
|
||||
int nprd = 0;
|
||||
if ( lammps_->domain->xperiodic > 0 ) { nprd++ ; }
|
||||
if ( lammps_->domain->yperiodic > 0 ) { nprd++ ; }
|
||||
if ( lammps_->domain->zperiodic > 0 ) { nprd++ ; }
|
||||
return nprd;
|
||||
}
|
||||
|
||||
double LammpsInterface::domain_xprd() { return lammps_->domain->xprd; }
|
||||
|
||||
double LammpsInterface::domain_yprd() { return lammps_->domain->yprd; }
|
||||
|
||||
double LammpsInterface::domain_zprd() { return lammps_->domain->zprd; }
|
||||
|
||||
double LammpsInterface::domain_xy() { return lammps_->domain->xy; }
|
||||
|
||||
double LammpsInterface::domain_xz() { return lammps_->domain->xz; }
|
||||
|
||||
double LammpsInterface::domain_yz() { return lammps_->domain->yz; }
|
||||
|
||||
int LammpsInterface::domain_triclinic() { return lammps_->domain->triclinic; }
|
||||
|
||||
void LammpsInterface::get_box_periodicity(int & xperiodic,
|
||||
int & yperiodic,
|
||||
int & zperiodic)
|
||||
{
|
||||
xperiodic = lammps_->domain->xperiodic;
|
||||
yperiodic = lammps_->domain->yperiodic;
|
||||
zperiodic = lammps_->domain->zperiodic;
|
||||
}
|
||||
|
||||
int LammpsInterface::get_region_id(const char * regionName) {
|
||||
int nregion = this->nregion();
|
||||
for (int iregion = 0; iregion < nregion; iregion++) {
|
||||
if (strcmp(regionName, region_name(iregion)) == 0) {
|
||||
return iregion;
|
||||
}
|
||||
}
|
||||
throw ATC_Error(0,"Region has not been defined");
|
||||
return -1;
|
||||
}
|
||||
// -----------------------------------------------------------------
|
||||
// update interface methods
|
||||
// -----------------------------------------------------------------
|
||||
LammpsInterface::UnitsType LammpsInterface::units_style(void)
|
||||
{
|
||||
if (strcmp(lammps_->update->unit_style,"lj") == 0) return LJ;
|
||||
else if (strcmp(lammps_->update->unit_style,"real") == 0) return REAL;
|
||||
else if (strcmp(lammps_->update->unit_style,"metal") == 0) return METAL;
|
||||
else return UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// lattice interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
double LammpsInterface::xlattice() { return lammps_->domain->lattice->xlattice; }
|
||||
|
||||
double LammpsInterface::ylattice() { return lammps_->domain->lattice->ylattice; }
|
||||
|
||||
double LammpsInterface::zlattice() { return lammps_->domain->lattice->zlattice; }
|
||||
|
||||
LammpsInterface::LatticeType LammpsInterface::lattice_style()
|
||||
{
|
||||
if (lammps_->domain->lattice)
|
||||
return (LammpsInterface::LatticeType)lammps_->domain->lattice->style;
|
||||
else
|
||||
throw ATC_Error(0,"Lattice has not been defined");
|
||||
}
|
||||
|
||||
//* retuns the number of basis vectors
|
||||
int LammpsInterface::get_n_basis()
|
||||
{
|
||||
return lammps_->domain->lattice->nbasis;
|
||||
}
|
||||
|
||||
//* returns the basis vectors, transformed to the box coords
|
||||
void LammpsInterface::get_basis(double **basis)
|
||||
{
|
||||
LAMMPS_NS::Lattice *lattice = lammps_->domain->lattice;
|
||||
int i,j;
|
||||
double origin[3] = {0.0, 0.0, 0.0};
|
||||
lattice->lattice2box(origin[0], origin[1], origin[2]);
|
||||
for (i=0; i<get_n_basis(); i++)
|
||||
{
|
||||
memcpy(basis[i],lattice->basis[i],3*sizeof(double));
|
||||
lattice->lattice2box(basis[i][0], basis[i][1], basis[i][2]);
|
||||
for (j=0; j<3; j++) basis[i][j] -= origin[j];
|
||||
}
|
||||
}
|
||||
|
||||
//* gets the unit cell vectors
|
||||
void LammpsInterface::get_unit_cell(double *a1, double *a2, double *a3)
|
||||
{
|
||||
int i, j;
|
||||
double *a[3] = {a1,a2,a3};
|
||||
double origin[3] = {0.0,0.0,0.0};
|
||||
LAMMPS_NS::Lattice *lattice = lammps_->domain->lattice;
|
||||
// transform origin
|
||||
lattice->lattice2box(origin[0], origin[1], origin[2]);
|
||||
|
||||
// copy reference lattice vectors
|
||||
memcpy(a[0], lattice->a1, 3*sizeof(double));
|
||||
memcpy(a[1], lattice->a2, 3*sizeof(double));
|
||||
memcpy(a[2], lattice->a3, 3*sizeof(double));
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
lattice->lattice2box(a[i][0], a[i][1], a[i][2]);
|
||||
for (j=0; j<3; j++) a[i][j] -= origin[j];
|
||||
}
|
||||
}
|
||||
|
||||
//* gets number of atoms in a unit cell
|
||||
int LammpsInterface::num_atoms_per_cell(void)
|
||||
{
|
||||
int naCell = 0;
|
||||
LatticeType type = lattice_style();
|
||||
if (type == LammpsInterface::SC) naCell = 1;
|
||||
else if (type == LammpsInterface::BCC) naCell = 2;
|
||||
else if (type == LammpsInterface::FCC) naCell = 4;
|
||||
else if (type == LammpsInterface::DIAMOND) naCell = 8;
|
||||
else if (comm_rank()==0) {
|
||||
//{throw ATC_Error(0,"lattice style not currently supported by ATC");}
|
||||
cout << "ATC WARNING: Cannot get number of atoms per cell from lattice\n";
|
||||
naCell = 1; //HACK to enable us to keep going since this is only used to compute volume per atom
|
||||
// ATC modes with a user specified atomic volume or using only volumetric quantities are fine
|
||||
}
|
||||
return naCell;
|
||||
}
|
||||
|
||||
//* gets tributary volume for an atom
|
||||
double LammpsInterface::volume_per_atom(void)
|
||||
{
|
||||
double naCell = num_atoms_per_cell();
|
||||
double volPerAtom =
|
||||
xlattice() * ylattice() * zlattice() / naCell;
|
||||
return volPerAtom;
|
||||
}
|
||||
|
||||
//* gets lattice basis
|
||||
void LammpsInterface::get_lattice(MATRIX &N, MATRIX &B)
|
||||
{
|
||||
int nbasis = get_n_basis();
|
||||
double **basis = new double*[nbasis];
|
||||
N.reset(3,3);
|
||||
B.reset(3,nbasis);
|
||||
for (int i=0; i<nbasis; i++) basis[i] = column(B,i).get_ptr();
|
||||
get_basis(basis);
|
||||
get_unit_cell(column(N,0).get_ptr(),
|
||||
column(N,1).get_ptr(),
|
||||
column(N,2).get_ptr());
|
||||
delete [] basis;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// force interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
double LammpsInterface::boltz() { return lammps_->force->boltz; }
|
||||
|
||||
double LammpsInterface::mvv2e() { return lammps_->force->mvv2e; }
|
||||
|
||||
double LammpsInterface::ftm2v() { return lammps_->force->ftm2v; }
|
||||
|
||||
double LammpsInterface::nktv2p() { return lammps_->force->nktv2p; }
|
||||
|
||||
double LammpsInterface::qqr2e() { return lammps_->force->qqr2e; }
|
||||
|
||||
double LammpsInterface::qe2f() { return lammps_->force->qe2f; }
|
||||
|
||||
double LammpsInterface::dielectric() { return lammps_->force->dielectric; }
|
||||
|
||||
double LammpsInterface::qqrd2e() { return lammps_->force->qqrd2e; }
|
||||
|
||||
double LammpsInterface::pair_force(int i, int j, double rsq,
|
||||
double & fmag_over_rmag)
|
||||
{
|
||||
int itype = (lammps_->atom->type)[i];
|
||||
int jtype = (lammps_->atom->type)[j];
|
||||
// return value is the energy
|
||||
if (rsq < (lammps_->force->pair->cutsq)[itype][jtype]) {
|
||||
return lammps_->force->pair->single(i,j,itype,jtype,
|
||||
rsq,1.0,1.0,fmag_over_rmag);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double LammpsInterface::pair_cutoff()
|
||||
{
|
||||
return lammps_->force->pair->cutforce;
|
||||
}
|
||||
|
||||
int LammpsInterface::single_enable()
|
||||
{
|
||||
return lammps_->force->pair->single_enable;
|
||||
}
|
||||
|
||||
//* Boltzmann's constant in M,L,T,t units
|
||||
double LammpsInterface::kBoltzmann() {
|
||||
return (lammps_->force->boltz)/(lammps_->force->mvv2e);
|
||||
}
|
||||
|
||||
//* Dulong-Petit heat capacity
|
||||
double LammpsInterface::heat_capacity() {
|
||||
double rhoCp = dimension()*kBoltzmann()/volume_per_atom();
|
||||
return rhoCp;
|
||||
}
|
||||
|
||||
//* reference mass density
|
||||
double LammpsInterface::mass_density()
|
||||
{
|
||||
const int ntypes = lammps_->atom->ntypes;
|
||||
const int *mass_setflag = lammps_->atom->mass_setflag;
|
||||
const int *type = lammps_->atom->type;
|
||||
const double *mass = lammps_->atom->mass;
|
||||
const double *rmass = lammps_->atom->rmass;
|
||||
// NOTE currently assumes all atoms have same mass and volume
|
||||
// in the future, mass and volume will be different but density should be
|
||||
// an atom indepedent quantity
|
||||
if (mass) {
|
||||
if (type) return mass[type[0]]/volume_per_atom();
|
||||
// no type array - just use first type that has a set mass
|
||||
for (int i=1; i<=ntypes; i++) {
|
||||
if (mass_setflag[i]) return mass[i]/volume_per_atom();
|
||||
}
|
||||
// NOTE: no masses specified in input file should we warn the user of this?
|
||||
return 0.0;
|
||||
}
|
||||
// NOTE is this valid - lammps likes to not use 0 index
|
||||
if (rmass) return rmass[0]/volume_per_atom();
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// group interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
int LammpsInterface::ngroup() { return lammps_->group->ngroup; }
|
||||
|
||||
int LammpsInterface::group_bit(int iGroup) { return lammps_->group->bitmask[iGroup]; }
|
||||
|
||||
int LammpsInterface::find_group(const char * c) { return lammps_->group->find(c); }
|
||||
|
||||
int LammpsInterface::group_inverse_mask(int iGroup)
|
||||
{
|
||||
return lammps_->group->inversemask[iGroup];
|
||||
}
|
||||
|
||||
char * LammpsInterface::group_name(int iGroup)
|
||||
{
|
||||
return lammps_->group->names[iGroup];
|
||||
}
|
||||
|
||||
void LammpsInterface::group_bounds(int iGroup, double * b)
|
||||
{
|
||||
lammps_->group->bounds(iGroup, b);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// memory interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
double * LammpsInterface::create_1d_double_array(int nlo, int nhi, const char *name) {
|
||||
double *array;
|
||||
return lammps_->memory->create1d_offset(array, nlo, nhi, name);
|
||||
}
|
||||
|
||||
void LammpsInterface::destroy_1d_double_array(double * d, int i) {
|
||||
lammps_->memory->destroy1d_offset(d, i);
|
||||
}
|
||||
|
||||
double ** LammpsInterface::create_2d_double_array(int n1, int n2, const char *name) {
|
||||
double **array;
|
||||
return lammps_->memory->create(array, n1, n2, name);
|
||||
}
|
||||
|
||||
void LammpsInterface::destroy_2d_double_array(double **d) {
|
||||
lammps_->memory->destroy(d);
|
||||
}
|
||||
|
||||
double **LammpsInterface::grow_2d_double_array(double **array,
|
||||
int n1,
|
||||
int n2,
|
||||
const char *name)
|
||||
{
|
||||
return lammps_->memory->grow(array, n1, n2, name);
|
||||
}
|
||||
|
||||
int ** LammpsInterface::create_2d_int_array(int n1, int n2, const char *name) {
|
||||
int **array;
|
||||
return lammps_->memory->create(array, n1, n2, name);
|
||||
}
|
||||
|
||||
void LammpsInterface::destroy_2d_int_array(int **i) {
|
||||
lammps_->memory->destroy(i);
|
||||
}
|
||||
|
||||
int ** LammpsInterface::grow_2d_int_array(int **array, int n1, int n2, const char *name) {
|
||||
return lammps_->memory->grow(array, n1, n2, name);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// update interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
double LammpsInterface::dt() { return lammps_->update->dt; }
|
||||
|
||||
int LammpsInterface::ntimestep() { return lammps_->update->ntimestep; }
|
||||
|
||||
int LammpsInterface::nsteps() { return lammps_->update->nsteps; }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// neighbor list interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
void LammpsInterface::init_list(int id, LAMMPS_NS::NeighList *ptr) { list_ = ptr; }
|
||||
|
||||
int LammpsInterface::neighbor_list_inum() { return list_->inum; }
|
||||
|
||||
int * LammpsInterface::neighbor_list_numneigh() { return list_->numneigh; }
|
||||
|
||||
int * LammpsInterface::neighbor_list_ilist() { return list_->ilist; }
|
||||
|
||||
int ** LammpsInterface::neighbor_list_firstneigh() { return list_->firstneigh; }
|
||||
|
||||
int LammpsInterface::neighbor_ago() { return lammps_->neighbor->ago; }
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// region interface methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
char * LammpsInterface::region_name(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->id;
|
||||
}
|
||||
|
||||
char * LammpsInterface::region_style(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->style;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_xlo(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_xlo;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_xhi(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_xhi;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_ylo(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_ylo;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_yhi(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_yhi;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_zlo(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_zlo;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_zhi(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->extent_zhi;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_xscale(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->xscale;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_yscale(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->yscale;
|
||||
}
|
||||
|
||||
double LammpsInterface::region_zscale(int iRegion)
|
||||
{
|
||||
return lammps_->domain->regions[iRegion]->zscale;
|
||||
}
|
||||
|
||||
int LammpsInterface::region_match(int iRegion, double x, double y, double z) {
|
||||
return lammps_->domain->regions[iRegion]->match(x,y,z);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// compute methods
|
||||
// -----------------------------------------------------------------
|
||||
int LammpsInterface::find_compute(const char* tag)
|
||||
{
|
||||
// a clunky way to safely get rid of the const
|
||||
int n = strlen(tag) + 1;
|
||||
char* tag_copy = new char[n];
|
||||
strcpy(tag_copy,tag);
|
||||
|
||||
int icompute = lammps_->modify->find_compute(tag_copy);
|
||||
if (icompute < 0) {
|
||||
string msg("Could not find compute ");
|
||||
msg += tag;
|
||||
throw ATC_Error(0,msg);
|
||||
}
|
||||
return icompute;
|
||||
}
|
||||
|
||||
LAMMPS_NS::Compute* LammpsInterface::get_compute(const char* tag)
|
||||
{
|
||||
int icompute = find_compute(tag);
|
||||
LAMMPS_NS::Compute* cmpt = lammps_->modify->compute[icompute];
|
||||
return cmpt;
|
||||
}
|
||||
|
||||
double** LammpsInterface::compute_vector_data(const char* tag)
|
||||
{
|
||||
LAMMPS_NS::Compute* cmpt = get_compute(tag);
|
||||
if (!(cmpt->invoked_flag & INVOKED_PERATOM)) {
|
||||
cmpt->compute_peratom();
|
||||
cmpt->invoked_flag |= INVOKED_PERATOM;
|
||||
}
|
||||
return cmpt->array_atom;
|
||||
}
|
||||
|
||||
double* LammpsInterface::compute_scalar_data(const char* tag)
|
||||
{
|
||||
LAMMPS_NS::Compute* cmpt = get_compute(tag);
|
||||
if (!(cmpt->invoked_flag & INVOKED_PERATOM)) {
|
||||
cmpt->compute_peratom();
|
||||
cmpt->invoked_flag |= INVOKED_PERATOM;
|
||||
}
|
||||
return cmpt->vector_atom;
|
||||
}
|
||||
|
||||
int LammpsInterface::compute_ncols(const char* tag)
|
||||
{
|
||||
int icompute = find_compute(tag);
|
||||
int ncols = lammps_->modify->compute[icompute]->size_peratom_cols;
|
||||
if (ncols == 0) ncols = 1; // oddity of lammps, used as flag for scalar
|
||||
return ncols;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// compute pe/atom interface methods
|
||||
// -----------------------------------------------------------------
|
||||
int LammpsInterface::atomPE_create(void)
|
||||
{
|
||||
//char * list[3] = {"atcPE","all","pe/atom"};
|
||||
char * list[4] = {"atcPE","all","pe/atom","pair"};
|
||||
int icompute = lammps_->modify->find_compute(list[0]);
|
||||
if (icompute < 0) {
|
||||
lammps_->modify->add_compute(3,list);
|
||||
icompute = lammps_->modify->find_compute(list[0]);
|
||||
}
|
||||
if (! atomPE_ ) {
|
||||
atomPE_ = lammps_->modify->compute[icompute];
|
||||
}
|
||||
return icompute;
|
||||
}
|
||||
|
||||
void LammpsInterface::atomPE_init(void)
|
||||
{
|
||||
if (atomPE_) {
|
||||
atomPE_->init();
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0,"no atomPE compute");
|
||||
}
|
||||
}
|
||||
|
||||
void LammpsInterface::atomPE_addstep(LAMMPS_NS::bigint step)
|
||||
{
|
||||
atomPE_->addstep(step);
|
||||
}
|
||||
|
||||
double * LammpsInterface::atomPE_compute(void)
|
||||
{
|
||||
if (atomPE_) {
|
||||
atomPE_->compute_peratom();
|
||||
return atomPE_->vector_atom;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void LammpsInterface::unwrap_coordinates(int iatom, double* xatom)
|
||||
{
|
||||
double **x = lammps_->atom->x;
|
||||
int *mask = lammps_->atom->mask;
|
||||
int *image = lammps_->atom->image;
|
||||
int nlocal = lammps_->atom->nlocal;
|
||||
|
||||
double *h = lammps_->domain->h;
|
||||
double xprd = lammps_->domain->xprd;
|
||||
double yprd = lammps_->domain->yprd;
|
||||
double zprd = lammps_->domain->zprd;
|
||||
int xbox,ybox,zbox;
|
||||
|
||||
// for triclinic, need to unwrap current atom coord via h matrix
|
||||
// NOTE: Using current box dimensions.
|
||||
if (lammps_->domain->triclinic == 0) {
|
||||
xbox = (image[iatom] & 1023) - 512;
|
||||
ybox = (image[iatom] >> 10 & 1023) - 512;
|
||||
zbox = (image[iatom] >> 20) - 512;
|
||||
xatom[0] = x[iatom][0] + xbox*xprd;
|
||||
xatom[1] = x[iatom][1] + ybox*yprd;
|
||||
xatom[2] = x[iatom][2] + zbox*zprd;
|
||||
} else {
|
||||
xbox = (image[iatom] & 1023) - 512;
|
||||
ybox = (image[iatom] >> 10 & 1023) - 512;
|
||||
zbox = (image[iatom] >> 20) - 512;
|
||||
xatom[0] = x[iatom][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
|
||||
xatom[1] = x[iatom][1] + h[1]*ybox + h[3]*zbox;
|
||||
xatom[2] = x[iatom][2] + h[2]*zbox;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// other methods
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/** Return lammps pointer -- only as a last resort! */
|
||||
LAMMPS_NS::LAMMPS * LammpsInterface::get_lammps_ptr() { return lammps_; }
|
||||
|
||||
}
|
|
@ -1,295 +0,0 @@
|
|||
#ifndef LAMMPS_INTERFACE_H
|
||||
#define LAMMPS_INTERFACE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include "mpi.h"
|
||||
#include "../../src/lammps.h"
|
||||
#include "../../src/lmptype.h"
|
||||
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
// Forward class declarations for LAMMPS_NS namespace
|
||||
namespace LAMMPS_NS {
|
||||
class LAMMPS;
|
||||
class NeighList;
|
||||
class Compute;
|
||||
}
|
||||
|
||||
namespace ATC {
|
||||
|
||||
/**
|
||||
* @class LammpsInterface
|
||||
* @brief Singleton class that handles all interfacing with the lammps code
|
||||
*/
|
||||
|
||||
class LammpsInterface {
|
||||
|
||||
public:
|
||||
|
||||
// Enumeration for lattice type. this MUST match the enum in src/lattice.cpp
|
||||
enum LatticeType {
|
||||
NONE=0,
|
||||
SC,
|
||||
BCC,
|
||||
FCC,
|
||||
HCP,
|
||||
DIAMOND,
|
||||
SQ,
|
||||
SQ2,
|
||||
HEX,
|
||||
CUSTOM
|
||||
};
|
||||
|
||||
// Enumeration for units type. this is internal to ATC
|
||||
enum UnitsType {
|
||||
UNKNOWN=0,
|
||||
LJ,
|
||||
REAL,
|
||||
METAL
|
||||
};
|
||||
|
||||
/** Static instance of this class */
|
||||
static LammpsInterface * instance();
|
||||
|
||||
/** Set lammps pointer */
|
||||
void set_lammps(LAMMPS_NS::LAMMPS * lammps)
|
||||
{
|
||||
lammps_ = lammps;
|
||||
MPI_Comm_rank(lammps_->world, & commRank_);
|
||||
}
|
||||
|
||||
/** \name Methods that interface with Lammps base class */
|
||||
/*@{*/
|
||||
MPI_Comm world();
|
||||
|
||||
void allsum(double * send_buf, double * rec_buf, int count = 1)
|
||||
{
|
||||
MPI_Allreduce(send_buf, rec_buf, count, MPI_DOUBLE, MPI_SUM,
|
||||
lammps_->world);
|
||||
MPI_Barrier(lammps_->world);
|
||||
}
|
||||
|
||||
void int_allsum(int * send_buf, int * rec_buf, int count = 1)
|
||||
{
|
||||
MPI_Allreduce(send_buf, rec_buf, count, MPI_INT, MPI_SUM,
|
||||
lammps_->world);
|
||||
MPI_Barrier(lammps_->world);
|
||||
}
|
||||
|
||||
void allmax(double * send_buf, double * rec_buf, int count = 1)
|
||||
{
|
||||
MPI_Allreduce(send_buf, rec_buf, count, MPI_DOUBLE, MPI_MAX,
|
||||
lammps_->world);
|
||||
MPI_Barrier(lammps_->world);
|
||||
}
|
||||
|
||||
void int_allmax(int * send_buf, int * rec_buf, int count = 1)
|
||||
{
|
||||
MPI_Allreduce(send_buf, rec_buf, count, MPI_INT, MPI_MAX,
|
||||
lammps_->world);
|
||||
MPI_Barrier(lammps_->world);
|
||||
}
|
||||
|
||||
void logical_or(int * send_buf, int * rec_buf, int count = 1)
|
||||
{
|
||||
MPI_Allreduce(send_buf, rec_buf, count, MPI_INT, MPI_LOR,
|
||||
lammps_->world);
|
||||
MPI_Barrier(lammps_->world);
|
||||
}
|
||||
|
||||
int comm_rank(void) { return commRank_;}
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Atom class */
|
||||
/*@{*/
|
||||
int nlocal();
|
||||
int nghost();
|
||||
int nmax();
|
||||
double natoms();
|
||||
double ** xatom();
|
||||
int ntypes();
|
||||
const double ** xatom() const;
|
||||
double ** vatom();
|
||||
double ** fatom();
|
||||
int * atom_mask();
|
||||
int * atom_type();
|
||||
int * atom_tag();
|
||||
double * atom_mass();
|
||||
double atom_mass(int iType);
|
||||
double * atom_rmass();
|
||||
double * atom_charge();
|
||||
void unwrap_coordinates(int iatom, double* xatom);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Domain class */
|
||||
/*@{*/
|
||||
int dimension();
|
||||
int nregion();
|
||||
void get_box_bounds(double & boxxlo, double & boxxhi,
|
||||
double & boxylo, double & boxyhi,
|
||||
double & boxzlo, double &boxzhi);
|
||||
int xperiodic();
|
||||
int yperiodic();
|
||||
int zperiodic();
|
||||
int nperiodic();
|
||||
void get_box_periodicity(int & xperiodic,
|
||||
int & yperiodic,
|
||||
int & zperiodic);
|
||||
int get_region_id(const char * regionName);
|
||||
double domain_xprd();
|
||||
double domain_yprd();
|
||||
double domain_zprd();
|
||||
double domain_xy();
|
||||
double domain_xz();
|
||||
double domain_yz();
|
||||
int domain_triclinic();
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Update class */
|
||||
UnitsType units_style();
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Lattice class */
|
||||
/*@{*/
|
||||
double xlattice();
|
||||
double ylattice();
|
||||
double zlattice();
|
||||
LatticeType lattice_style();
|
||||
int get_n_basis();
|
||||
void get_basis(double **basis);
|
||||
void get_unit_cell(double *a1, double *a2, double *a3);
|
||||
/** these functions are more than just simple pass throughs */
|
||||
int num_atoms_per_cell(void);
|
||||
double volume_per_atom(void);
|
||||
void get_lattice(MATRIX &N, MATRIX &B);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Force class */
|
||||
/*@{*/
|
||||
double boltz();
|
||||
double mvv2e();
|
||||
double ftm2v();
|
||||
double nktv2p();
|
||||
double qqr2e();
|
||||
double qe2f();
|
||||
double dielectric();
|
||||
double qqrd2e();
|
||||
double pair_force(int i, int j, double rsq, double& fmag_over_rmag);
|
||||
double pair_cutoff();
|
||||
int single_enable();
|
||||
/** these functions are more than just simple pass throughs */
|
||||
/** Boltzmann's constant in M,L,T,t units */
|
||||
double kBoltzmann(void);
|
||||
/** Dulong-Petit heat capacity per volume in M,L,T,t units */
|
||||
double heat_capacity(void);
|
||||
/** mass per volume in reference configuraturation in M,L units */
|
||||
double mass_density(void);
|
||||
/** ratio of permittivity of free space over elemental charge in V, L units */
|
||||
double epsilon0(void) {return 0.00552635; } // [V A]^-1
|
||||
// NOTE this won't work for LJ/SI/CGS units where [L] != A
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Group class */
|
||||
/*@{*/
|
||||
int ngroup();
|
||||
int group_bit(int iGroup);
|
||||
int find_group(const char * c);
|
||||
int group_inverse_mask(int iGroup);
|
||||
char * group_name(int iGroup);
|
||||
void group_bounds(int iGroup, double * b);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Memory class */
|
||||
/*@{*/
|
||||
double * create_1d_double_array(int nlo, int nhi, const char *name);
|
||||
void destroy_1d_double_array(double * d, int i);
|
||||
double ** create_2d_double_array(int n1, int n2, const char *name);
|
||||
void destroy_2d_double_array(double **d);
|
||||
double **grow_2d_double_array(double **array, int n1, int n2, const char *name);
|
||||
int ** create_2d_int_array(int n1, int n2, const char *name);
|
||||
void destroy_2d_int_array(int **i);
|
||||
int ** grow_2d_int_array(int **array, int n1, int n2, const char *name);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Update class */
|
||||
/*@{*/
|
||||
double dt();
|
||||
int ntimestep();
|
||||
int nsteps();
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with neighbor list */
|
||||
/*@{*/
|
||||
void init_list(int id, LAMMPS_NS::NeighList *ptr);
|
||||
int neighbor_list_inum();
|
||||
int * neighbor_list_numneigh();
|
||||
int * neighbor_list_ilist();
|
||||
int ** neighbor_list_firstneigh();
|
||||
int neighbor_ago();
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with Region class */
|
||||
/*@{*/
|
||||
char * region_name(int iRegion);
|
||||
char * region_style(int iRegion);
|
||||
double region_xlo(int iRegion);
|
||||
double region_xhi(int iRegion);
|
||||
double region_ylo(int iRegion);
|
||||
double region_yhi(int iRegion);
|
||||
double region_zlo(int iRegion);
|
||||
double region_zhi(int iRegion);
|
||||
double region_xscale(int iRegion);
|
||||
double region_yscale(int iRegion);
|
||||
double region_zscale(int iRegion);
|
||||
int region_match(int iRegion, double x, double y, double z);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with compute class */
|
||||
enum COMPUTE_INVOKED
|
||||
{DUMMY0,INVOKED_SCALAR,INVOKED_VECTOR,DUMMMY3,INVOKED_PERATOM};
|
||||
int find_compute(const char* tag);
|
||||
LAMMPS_NS::Compute* get_compute(const char* tag);
|
||||
double* compute_scalar_data(const char* tag);
|
||||
double** compute_vector_data(const char* tag);
|
||||
int compute_ncols(const char* tag);
|
||||
/*@}*/
|
||||
|
||||
/** \name Methods that interface with compute pe/atom class */
|
||||
/*@{*/
|
||||
int atomPE_create(void);
|
||||
void atomPE_init(void);
|
||||
void atomPE_addstep(LAMMPS_NS::bigint step);
|
||||
double * atomPE_compute(void);
|
||||
/*@}*/
|
||||
|
||||
/** Return lammps pointer -- only as a last resort! */
|
||||
LAMMPS_NS::LAMMPS * get_lammps_ptr();
|
||||
|
||||
protected:
|
||||
|
||||
LAMMPS_NS::LAMMPS * lammps_;
|
||||
|
||||
/** access to neighbor list */
|
||||
LAMMPS_NS::NeighList *list_;
|
||||
|
||||
/** constructor */
|
||||
LammpsInterface();
|
||||
|
||||
/** comm rank */
|
||||
int commRank_;
|
||||
|
||||
/** compute pe/atom */
|
||||
LAMMPS_NS::Compute * atomPE_;
|
||||
|
||||
private:
|
||||
|
||||
static LammpsInterface * myInstance_;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace ATC
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
# Settings that the LAMMPS build will import when this package library is used
|
||||
|
||||
user-atc_SYSINC =
|
||||
user-atc_SYSLIB = -lblas -llapack
|
||||
user-atc_SYSPATH =
|
|
@ -0,0 +1,29 @@
|
|||
SHELL = /bin/sh
|
||||
# ------ FILES ------
|
||||
SRC = $(wildcard *.cpp)
|
||||
INC = $(wildcard *.h)
|
||||
# ------ DEFINITIONS ------
|
||||
LIB = libatc.a
|
||||
OBJ = $(SRC:.cpp=.o)
|
||||
# ------ SETTINGS ------
|
||||
CC = mpic++
|
||||
CCFLAGS = -O -g -I../../src -fPIC -DMPICH_IGNORE_CXX_SEEK
|
||||
ARCHIVE = ar
|
||||
ARCHFLAG = -rc
|
||||
DEPFLAGS = -M
|
||||
LINK = ${CC}
|
||||
LINKFLAGS = -O
|
||||
# ------ MAKE PROCEDURE ------
|
||||
lib: $(OBJ)
|
||||
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
|
||||
@cp Makefile.lammps.installed Makefile.lammps
|
||||
# ------ COMPILE RULES ------
|
||||
%.o:%.cpp
|
||||
$(CC) $(CCFLAGS) -c $<
|
||||
%.d:%.cpp
|
||||
$(CC) $(CCFLAGS) $(DEPFLAGS) $< > $@
|
||||
# ------ DEPENDENCIES ------
|
||||
DEPENDS = $(OBJ:.o=.d)
|
||||
# ------ CLEAN ------
|
||||
clean:
|
||||
@rm *.o *.d $(LIB)
|
|
@ -1,349 +0,0 @@
|
|||
#include "Material.h"
|
||||
#include "ATC_Transfer.h"
|
||||
#include "LammpsInterface.h"
|
||||
#include "ElectronHeatCapacity.h"
|
||||
#include "ElectronHeatFlux.h"
|
||||
#include "ElectronPhononExchange.h"
|
||||
|
||||
namespace ATC {
|
||||
using namespace ATC_STRING;
|
||||
|
||||
Material::Material()
|
||||
: rhoCp_(0),
|
||||
rho_(0),
|
||||
heatCapacity_(0),
|
||||
massDensity_(0),
|
||||
chargeDensity_(0),
|
||||
electronHeatCapacity_(NULL),
|
||||
heatConductivity_(0),
|
||||
electronHeatFlux_(NULL),
|
||||
stress_(NULL),
|
||||
electronPhononExchange_(NULL),
|
||||
permittivity_(1.),
|
||||
electronEquilibriumDensity_(0),
|
||||
electronRecombinationInvTau_(0),
|
||||
donorConcentration_(0)
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
// Constructor (parser)
|
||||
//--------------------------------------------------------------
|
||||
// Example:
|
||||
// material Cu
|
||||
// heat_capacity constant
|
||||
// capacity 1.0
|
||||
// end
|
||||
// heat_flux linear
|
||||
// conductivity 1.0
|
||||
// end
|
||||
// electron_heat_flux linear
|
||||
// conductivity 1.0
|
||||
// end
|
||||
// electron_heat_capacity linear
|
||||
// capacity 1.0
|
||||
// end
|
||||
// electron_phonon_exchange linear
|
||||
// coefficient 0.1
|
||||
// end
|
||||
// end
|
||||
Material::Material(string & tag, fstream &fileId)
|
||||
: tag_(tag),
|
||||
rhoCp_(0),
|
||||
rho_(0),
|
||||
heatCapacity_(0),
|
||||
massDensity_(0),
|
||||
chargeDensity_(0),
|
||||
electronHeatCapacity_(NULL),
|
||||
heatConductivity_(0),
|
||||
electronHeatFlux_(NULL),
|
||||
stress_(NULL),
|
||||
electronPhononExchange_(NULL),
|
||||
permittivity_(1.),
|
||||
electronEquilibriumDensity_(0),
|
||||
electronRecombinationInvTau_(0),
|
||||
donorConcentration_(0)
|
||||
{
|
||||
linearFlux_.reset(NUM_FIELDS);
|
||||
linearFlux_ = false;
|
||||
linearSource_.reset(NUM_FIELDS);
|
||||
linearSource_ = true;
|
||||
constantDensity_.reset(NUM_FIELDS);
|
||||
constantDensity_ = false;
|
||||
|
||||
// NOTE these next two rely on many assumptions
|
||||
rhoCp_ = ATC::LammpsInterface::instance()->heat_capacity();
|
||||
parameters_["heat_capacity"] = rhoCp_;
|
||||
heatCapacity_ = rhoCp_;
|
||||
registry_.insert("heat_capacity");
|
||||
constantDensity_(TEMPERATURE) = true;
|
||||
|
||||
rho_ = ATC::LammpsInterface::instance()->mass_density();
|
||||
parameters_["mass_density"] = rho_;
|
||||
massDensity_ = rho_;
|
||||
registry_.insert("mass_density");
|
||||
constantDensity_(DISPLACEMENT) = true;
|
||||
constantDensity_(VELOCITY) = true;
|
||||
|
||||
|
||||
vector<string> line;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line.size() == 1) {
|
||||
if (line[0] == "end") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (line[0] == "heat_capacity") { // over-ride default
|
||||
registry_. insert("heat_capacity");
|
||||
registry_. insert("thermal_energy");
|
||||
if (line[1] == "constant") {
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") break;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "capacity") {
|
||||
heatCapacity_ = value;
|
||||
parameters_["heat_capacity"] = heatCapacity_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line[0] == "heat_flux") {
|
||||
registry_. insert("heat_flux");
|
||||
if (line[1] == "linear") {
|
||||
linearFlux_(TEMPERATURE) = true;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") break;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "conductivity") {
|
||||
heatConductivity_ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line[0] == "electron_heat_flux") {
|
||||
registry_. insert("electron_heat_flux");
|
||||
if (line[1] == "linear") {
|
||||
linearFlux_(ELECTRON_TEMPERATURE) = true;
|
||||
electronHeatFlux_ = new ElectronHeatFluxLinear(fileId, parameters_);
|
||||
}
|
||||
else if (line[1] == "power_law") {
|
||||
electronHeatFlux_ = new ElectronHeatFluxPowerLaw(fileId, parameters_);
|
||||
}
|
||||
}
|
||||
else if (line[0] == "electron_heat_capacity") {
|
||||
registry_. insert("electron_heat_capacity");
|
||||
registry_. insert("electron_thermal_energy");
|
||||
if (line[1] == "constant") {
|
||||
constantDensity_(ELECTRON_TEMPERATURE) = true;
|
||||
electronHeatCapacity_ = new ElectronHeatCapacityConstant(fileId,
|
||||
parameters_);
|
||||
}
|
||||
else if (line[1] == "linear") {
|
||||
electronHeatCapacity_ = new ElectronHeatCapacityLinear(fileId,
|
||||
parameters_);
|
||||
}
|
||||
}
|
||||
else if (line[0] == "electron_phonon_exchange") {
|
||||
registry_. insert("electron_phonon_exchange");
|
||||
if (line[1] == "linear") {
|
||||
electronPhononExchange_ = new ElectronPhononExchangeLinear(fileId,
|
||||
parameters_);
|
||||
}
|
||||
else if (line[1] == "power_law") {
|
||||
linearSource_(TEMPERATURE) = false;
|
||||
linearSource_(ELECTRON_TEMPERATURE) = false;
|
||||
electronPhononExchange_ = new ElectronPhononExchangePowerLaw(fileId,
|
||||
parameters_);
|
||||
}
|
||||
}
|
||||
else if (line[0] == "mass_density") { // over-ride default
|
||||
registry_. insert("mass_density");
|
||||
registry_. insert("kinetic_energy");
|
||||
if (line[1] == "constant") {
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") break;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "density") {
|
||||
massDensity_ = value;
|
||||
parameters_["mass_density"] = massDensity_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line[0] == "electron_recombination") {
|
||||
registry_. insert("electron_recombination");
|
||||
if (line[1] == "linear") {
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") break;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "inv_relaxation_time") {
|
||||
electronRecombinationInvTau_ = value;
|
||||
parameters_["inv_relaxation_time"] = electronRecombinationInvTau_;
|
||||
}
|
||||
else if (line[0] == "equilibrium_carrier_density") {
|
||||
electronEquilibriumDensity_ = value;
|
||||
parameters_["equilibrium_carrier_density"]
|
||||
= electronEquilibriumDensity_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line[0] == "charge_density") {
|
||||
registry_. insert("charge_density");
|
||||
if (line[1] == "constant") {
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0) continue;
|
||||
if (line[0] == "end") break;
|
||||
double value = str2dbl(line[1]);
|
||||
if (line[0] == "donor_concentration") {
|
||||
donorConcentration_ = value;
|
||||
parameters_["donor_concentration"] = donorConcentration_;
|
||||
}
|
||||
else if (line[0] == "density") {
|
||||
chargeDensity_ = value;
|
||||
parameters_["charge_density"] = chargeDensity_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw ATC_Error(0, "unrecognized material function: "+line[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void Material::heat_capacity(
|
||||
const FIELDS & fields,
|
||||
FIELD & capacity)
|
||||
{
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
int nNodes = T.nRows();
|
||||
capacity.reset(nNodes,1);
|
||||
capacity = heatCapacity_;
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::thermal_energy(
|
||||
const FIELDS &fields,
|
||||
FIELD &energy)
|
||||
{
|
||||
const FIELD & T = (fields.find(TEMPERATURE))->second;
|
||||
energy = heatCapacity_ * T;
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::electron_heat_capacity(
|
||||
const FIELDS & fields,
|
||||
FIELD & capacity)
|
||||
{
|
||||
electronHeatCapacity_->electron_heat_capacity(fields,capacity);
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::electron_thermal_energy(
|
||||
const FIELDS &fields,
|
||||
FIELD &energy)
|
||||
{
|
||||
electronHeatCapacity_->electron_thermal_energy(fields,energy);
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::mass_density(
|
||||
const FIELDS &fields,
|
||||
FIELD &density)
|
||||
{
|
||||
int nNodes = 0;
|
||||
FIELDS::const_iterator field = fields.find(MASS_DENSITY);
|
||||
if (field != fields.end()) {
|
||||
const FIELD & d = field->second;
|
||||
nNodes = d.nRows();
|
||||
}
|
||||
else {
|
||||
FIELDS::const_iterator field = fields.find(VELOCITY);
|
||||
if (field != fields.end()) {
|
||||
const FIELD & v = field->second;
|
||||
nNodes = v.nRows();
|
||||
}
|
||||
}
|
||||
density.reset(nNodes,1);
|
||||
density = massDensity_;
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::kinetic_energy(
|
||||
const FIELDS &fields,
|
||||
FIELD &energy)
|
||||
{
|
||||
FIELDS::const_iterator field = fields.find(VELOCITY);
|
||||
if (field != fields.end()) {
|
||||
const FIELD & v = field->second;
|
||||
energy = 0.5*massDensity_*v;
|
||||
energy *= v;
|
||||
}
|
||||
else {
|
||||
energy = 0.;
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------
|
||||
void Material::heat_flux(
|
||||
const FIELDS & fields,
|
||||
const GRAD_FIELDS & gradFields,
|
||||
GRAD_FIELD & flux)
|
||||
{
|
||||
const GRAD_FIELD & dT = (gradFields.find(TEMPERATURE))->second;
|
||||
flux.push_back(-heatConductivity_* dT[0]);
|
||||
flux.push_back(-heatConductivity_* dT[1]);
|
||||
flux.push_back(-heatConductivity_* dT[2]);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void Material::electron_heat_flux(
|
||||
const FIELDS & fields,
|
||||
const GRAD_FIELDS & gradFields,
|
||||
GRAD_FIELD & flux)
|
||||
{
|
||||
electronHeatFlux_->electron_heat_flux(fields,gradFields,flux);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void Material::electron_phonon_exchange(
|
||||
const FIELDS & fields,
|
||||
FIELD & flux)
|
||||
{
|
||||
electronPhononExchange_->electron_phonon_exchange(fields,flux);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void Material::electron_recombination(
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
FIELD & flux)
|
||||
{
|
||||
// 1/tau (n - n0)
|
||||
const FIELD & n = (fields.find(ELECTRON_DENSITY))->second;
|
||||
flux = n;
|
||||
flux -= electronEquilibriumDensity_;
|
||||
flux *= -electronRecombinationInvTau_;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void Material::charge_density(
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
FIELD & flux)
|
||||
{
|
||||
// Extrinsic/electron charge density
|
||||
FIELDS::const_iterator field = fields.find(ELECTRON_DENSITY);
|
||||
if (field != fields.end()) {
|
||||
// (n - nD) , where n > 0
|
||||
const FIELD & n = field->second;
|
||||
flux = n;
|
||||
flux -= donorConcentration_;// NOTE uniform
|
||||
flux *= -1.0; // account for negative charge
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
#ifndef MATERIAL_H
|
||||
#define MATERIAL_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "LammpsInterface.h"
|
||||
|
||||
namespace ATC
|
||||
{
|
||||
class ATC_Transfer;
|
||||
class Stress;
|
||||
class ElectronHeatCapacity;
|
||||
class ElectronHeatFlux;
|
||||
class ElectronFlux;
|
||||
class ElectronPhononExchange;
|
||||
|
||||
class Material
|
||||
{
|
||||
public:
|
||||
Material();
|
||||
virtual ~Material() {};
|
||||
/** this constructor parses material file */
|
||||
Material(string & tag, fstream & fileId);
|
||||
|
||||
/** return label */
|
||||
string label(void) {return tag_;}
|
||||
|
||||
/** check material has required interfaces */
|
||||
bool check_registry(const set<string> functionList) const
|
||||
{
|
||||
set<string>::const_iterator itr;
|
||||
for (itr=functionList.begin(); itr!=functionList.end(); itr++) {
|
||||
if (registry_.find(*itr) == registry_.end()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** access to material parameters */
|
||||
bool get_parameter(const string name, double & value) const
|
||||
{
|
||||
map<string,double>::const_iterator iter = parameters_.find(name);
|
||||
if ( iter == parameters_.end()) {
|
||||
value = 0.0;
|
||||
return false;
|
||||
}
|
||||
value = iter->second;
|
||||
return true;
|
||||
}
|
||||
/** true if rhs flux is linear (per field) */
|
||||
bool linear_flux(FieldName name) {
|
||||
return linearFlux_(name);
|
||||
};
|
||||
|
||||
/** true if rhs source is linear (per field) */
|
||||
bool linear_source(FieldName name) {
|
||||
return linearSource_(name);
|
||||
};
|
||||
|
||||
/** true if lhs density is constant (per field) */
|
||||
bool constant_density(FieldName name) {
|
||||
return constantDensity_(name);
|
||||
};
|
||||
|
||||
/** each of these is a field function computed at a set of points */
|
||||
/** if there is only one function it is in the base class
|
||||
** otherwise, a subsidary class is setup */
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** densitities */
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** thermal energy */
|
||||
void thermal_energy(const FIELDS & fields,
|
||||
FIELD & energy);
|
||||
/** heat capacity */
|
||||
void heat_capacity(const FIELDS & fields,
|
||||
FIELD & capacity);
|
||||
/** thermal energy */
|
||||
void electron_thermal_energy(const FIELDS & fields,
|
||||
FIELD & energy);
|
||||
/** electron heat capacity */
|
||||
void electron_heat_capacity(const FIELDS &fields,
|
||||
FIELD &capacity);
|
||||
/** kinetic energy */
|
||||
void kinetic_energy(const FIELDS & fields,
|
||||
FIELD & energy);
|
||||
/** mass density */
|
||||
void mass_density(const FIELDS &fields,
|
||||
FIELD &density);
|
||||
/** elastic energy */
|
||||
void elastic_energy(const FIELDS & fields,
|
||||
const GRAD_FIELDS & gradFields,
|
||||
FIELD & energy);
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** fluxes */
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** heat_flux */
|
||||
void heat_flux(const FIELDS & fields,
|
||||
const GRAD_FIELDS & gradFields,
|
||||
GRAD_FIELD & heatFlux);
|
||||
/** electron conduction flux */
|
||||
void electron_heat_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux);
|
||||
/** stress */
|
||||
void stress(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &stress);
|
||||
/** computes electron flux */
|
||||
void electron_flux(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux);
|
||||
/** computes electric displacement */
|
||||
void electric_displacement(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux);
|
||||
/** computes electric field */
|
||||
void electric_field(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
GRAD_FIELD &flux);
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** sources */
|
||||
/* -----------------------------------------------------------------*/
|
||||
/** electron-phonon exchange flux */
|
||||
void electron_phonon_exchange(const FIELDS &fields,
|
||||
FIELD &flux);
|
||||
/** computes net generation */
|
||||
virtual void electron_recombination(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
FIELD &flux);
|
||||
/** computes drift diffusion charge density */
|
||||
virtual void charge_density(const FIELDS &fields,
|
||||
const GRAD_FIELDS &gradFields,
|
||||
FIELD &flux);
|
||||
|
||||
|
||||
protected:
|
||||
/** material's label */
|
||||
string tag_;
|
||||
/** dictionary of material parameters */
|
||||
map<string,double> parameters_;
|
||||
/** dictionary of instantiated functions */
|
||||
set<string> registry_;
|
||||
/** per eqn flag of constant density */
|
||||
Array<bool> constantDensity_;
|
||||
/** per eqn flag of linearity/nonlinearity */
|
||||
Array<bool> linearFlux_, linearSource_;
|
||||
/** default heat capacity */
|
||||
double rhoCp_;
|
||||
/** default mass density */
|
||||
double rho_;
|
||||
/** heat capacity */
|
||||
double heatCapacity_;
|
||||
/** electron heat capacity */
|
||||
ElectronHeatCapacity * electronHeatCapacity_;
|
||||
/** mass density */
|
||||
double massDensity_;
|
||||
/** charge density */
|
||||
double chargeDensity_;
|
||||
/** thermal conductivity */
|
||||
double heatConductivity_;
|
||||
/** electron heat flux */
|
||||
ElectronHeatFlux * electronHeatFlux_;
|
||||
/** stress */
|
||||
Stress * stress_;
|
||||
/** electron-phonon exchange */
|
||||
ElectronPhononExchange * electronPhononExchange_;
|
||||
/** electron heat flux */
|
||||
ElectronFlux * electronFlux_;
|
||||
/** electric permittivity */
|
||||
double permittivity_;
|
||||
/** equilibrium carrier density */
|
||||
double electronEquilibriumDensity_;
|
||||
/** relaxation time */
|
||||
double electronRecombinationInvTau_;
|
||||
/** uniform donor concentration */
|
||||
double donorConcentration_; // NOTE only for uniform
|
||||
};
|
||||
|
||||
}
|
||||
#endif // Material.h
|
||||
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
#include "DenseMatrix.h"
|
||||
#include "Solver.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//* performs a matrix-matrix multiply with optional transposes BLAS version
|
||||
// C = b*C + a*A*B
|
||||
//-----------------------------------------------------------------------------
|
||||
void MultAB(const MATRIX &A, const MATRIX &B, DENS_MAT &C,
|
||||
const bool At, const bool Bt, double a, double b)
|
||||
{
|
||||
static char t[2] = {'N','T'};
|
||||
char *ta=t+At, *tb=t+Bt;
|
||||
int sA[2] = {A.nRows(), A.nCols()}; // sizes of A
|
||||
int sB[2] = {B.nRows(), B.nCols()}; // sizes of B
|
||||
|
||||
GCK(A, B, sA[!At]!=sB[Bt], "MultAB<double>: matrix-matrix multiply");
|
||||
if (!C.is_size(sA[At],sB[!Bt]))
|
||||
{
|
||||
C.resize(sA[At],sB[!Bt]);
|
||||
if (b != 0.0) C.zero();
|
||||
}
|
||||
// get pointers to the matrix sizes needed by BLAS
|
||||
int *M = sA+At; // # of rows in op[A] (op[A] = A' if At='T' else A)
|
||||
int *N = sB+!Bt; // # of cols in op[B]
|
||||
int *K = sA+!At; // # of cols in op[A] or # of rows in op[B]
|
||||
|
||||
double *pa=A.get_ptr(), *pb=B.get_ptr(), *pc=C.get_ptr();
|
||||
|
||||
#ifdef COL_STORAGE
|
||||
dgemm_(ta, tb, M, N, K, &a, pa, sA, pb, sB, &b, pc, M);
|
||||
#else
|
||||
dgemm_(tb, ta, N, M, K, &a, pb, sB+1, pa, sA+1, &b, pc, N);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the inverse of a double precision matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
DenseMatrix<double> inv(const MATRIX& A)
|
||||
{
|
||||
SQCK(A, "DenseMatrix::inv(), matrix not square"); // check matrix is square
|
||||
DENS_MAT invA(A); // Make copy of A to invert
|
||||
|
||||
// setup for call to BLAS
|
||||
int m, info, lwork=-1;
|
||||
m = invA.nRows();
|
||||
|
||||
int *ipiv = new int[m<<1]; // need 2m storage
|
||||
int *iwork=ipiv+m;
|
||||
|
||||
dgetrf_(&m,&m,invA.get_ptr(),&m,ipiv,&info); // compute LU factorization
|
||||
GCK(A,A,info<0,"DenseMatrix::inv() dgetrf error: Argument had bad value.");
|
||||
GCK(A,A,info>0,"DenseMatrix::inv() dgetrf error: Matrix not invertable.");
|
||||
|
||||
// LU factorization succeeded
|
||||
// Compute 1-norm of original matrix for use with dgecon
|
||||
char norm = '1'; // Use 1-norm
|
||||
double rcond, anorm, *workc = new double[4*m];
|
||||
anorm = dlange_(&norm,&m,&m,A.get_ptr(),&m,workc);
|
||||
|
||||
// Condition number estimation (warn if bad)
|
||||
dgecon_(&norm,&m,invA.get_ptr(),&m,&anorm,&rcond,workc,iwork,&info);
|
||||
GCK(A,A,info<0, "DenseMatrix::inv(): dgecon error: Argument had bad value.");
|
||||
GCK(A,A,rcond<1e-14,"DenseMatrix::inv(): Matrix nearly singular, RCOND<e-14");
|
||||
|
||||
// Now determine optimal work size for computation of matrix inverse
|
||||
double work_dummy[2] = {0.0,0.0};
|
||||
dgetri_(&m, invA.get_ptr(), &m, ipiv, work_dummy, &lwork, &info);
|
||||
GCK(A,A,info<0,"DenseMatrix::inv() dgetri error: Argument had bad value.");
|
||||
GCK(A,A,info>0,"DenseMatrix::inv() dgetri error: Matrix not invertable.");
|
||||
|
||||
// Work size query succeded
|
||||
lwork = (int)work_dummy[0];
|
||||
double *work = new double[lwork]; // Allocate vector of appropriate size
|
||||
|
||||
// Compute and store matrix inverse
|
||||
dgetri_(&m,invA.get_ptr(),&m,ipiv,work,&lwork,&info);
|
||||
GCK(A,A,info<0,"DenseMatrix::inv() dgetri error: Argument had bad value.");
|
||||
GCK(A,A,info>0,"DenseMatrix::inv() dgetri error: Matrix not invertable.");
|
||||
|
||||
// Clean-up
|
||||
delete [] ipiv;
|
||||
delete [] workc;
|
||||
delete [] work;
|
||||
return invA;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* computes the determinant of a square matrix by LU decomposition (if n>3)
|
||||
//-----------------------------------------------------------------------------
|
||||
double det(const MATRIX& A)
|
||||
{
|
||||
static const double sign[2] = {1.0, -1.0};
|
||||
SQCK(A, "Matrix::det(), matrix not square"); // check matrix is square
|
||||
int m = A.nRows();
|
||||
switch (m) // explicit determinant for small matrix sizes
|
||||
{
|
||||
case 1: return A(0,0);
|
||||
case 2: return A(0,0)*A(1,1)-A(0,1)*A(1,0);
|
||||
case 3:
|
||||
return A(0,0)*(A(1,1)*A(2,2)-A(1,2)*A(2,1))
|
||||
+ A(0,1)*(A(1,2)*A(2,0)-A(1,0)*A(2,2))
|
||||
+ A(0,2)*(A(1,0)*A(2,1)-A(1,1)*A(2,0));
|
||||
default: break;
|
||||
}
|
||||
// First compute LU factorization
|
||||
int info, *ipiv = new int[m];
|
||||
double det = 1.0;
|
||||
DENS_MAT PLUA(A);
|
||||
dgetrf_(&m,&m,PLUA.get_ptr(),&m,ipiv,&info);
|
||||
|
||||
GCK(A,A,info>0,"Matrix::det() dgetrf error: Bad argument value.");
|
||||
if (!info) // matrix is non-singular
|
||||
{
|
||||
// Compute det(A) = det(P)*det(L)*det(U) = +/-1 * det(U)
|
||||
int i, OddNumPivots;
|
||||
|
||||
det = PLUA(0,0);
|
||||
OddNumPivots = ipiv[0]!=(1);
|
||||
for(i=1; i<m; i++)
|
||||
{
|
||||
det *= PLUA(i,i);
|
||||
OddNumPivots += (ipiv[i]!=(i+1)); // # pivots even/odd
|
||||
}
|
||||
det *= sign[OddNumPivots&1];
|
||||
}
|
||||
delete [] ipiv; // Clean-up
|
||||
return det;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the maximum eigenvalue of a matrix.
|
||||
//-----------------------------------------------------------------------------
|
||||
double max_eigenvalue(const Matrix<double>& A)
|
||||
{
|
||||
GCK(A,A,!is_size(3,3), "max_eigenvalue only implimented for 3x3");
|
||||
const double c0 = det(A);
|
||||
const double c1 = A(1,0)*A(0,1) + A(2,0)*A(0,2) + A(1,2)*A(2,1)
|
||||
- A(0,0)*A(1,1) - A(0,0)*A(2,2) - A(1,1)*A(2,2);
|
||||
const double c2 = trace(A);
|
||||
double c[4] = {c0, c1, c2, -1.0}, x[3];
|
||||
int num_roots = ATC::solve_cubic(c, x);
|
||||
double max_root = 0.0;
|
||||
for (int i=0; i<num_roots; i++) max_root = std::max(x[i], max_root);
|
||||
return max_root;
|
||||
}
|
||||
|
664
lib/atc/Matrix.h
664
lib/atc/Matrix.h
|
@ -1,664 +0,0 @@
|
|||
#ifndef MATRIX_H
|
||||
#define MATRIX_H
|
||||
#include "MatrixDef.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* abstract class Matrix - base class for linear algebra subsystem
|
||||
*******************************************************************************/
|
||||
template<typename T>
|
||||
class Matrix
|
||||
{
|
||||
protected:
|
||||
Matrix(const Matrix &c);
|
||||
public:
|
||||
Matrix() {}
|
||||
virtual ~Matrix() {}
|
||||
|
||||
//* stream output functions
|
||||
void print(ostream &o) const { o << tostring(); }
|
||||
void print(ostream &o, const string &name) const;
|
||||
friend ostream& operator<<(ostream &o, const Matrix<T> &m){m.print(o); return o;}
|
||||
void print() const;
|
||||
virtual void print(const string &name) const;
|
||||
virtual string tostring() const;
|
||||
|
||||
// element by element operations
|
||||
DenseMatrix<T> operator/(const Matrix<T>& B) const;
|
||||
DenseMatrix<T> pow(int n) const;
|
||||
DenseMatrix<T> pow(double n) const;
|
||||
|
||||
// functions that return a copy
|
||||
DenseMatrix<T> transpose() const;
|
||||
|
||||
// matrix to scalar functions
|
||||
T sum() const;
|
||||
T stdev() const;
|
||||
T max() const;
|
||||
T min() const;
|
||||
T maxabs() const;
|
||||
T minabs() const;
|
||||
T norm() const;
|
||||
T mean() const;
|
||||
T dot(const Matrix<T> &r) const;
|
||||
T trace() const;
|
||||
|
||||
// row and column operations
|
||||
T row_sum (INDEX i=0) const { return row(*this,i).sum(); }
|
||||
T row_mean (INDEX i=0) const { return row(*this,i).mean(); }
|
||||
T row_norm (INDEX i=0) const { return row(*this,i).norm(); }
|
||||
T row_stdev(INDEX i=0) const { return row(*this,i).stdev(); }
|
||||
T col_sum (INDEX i=0) const { return column(*this,i).sum(); }
|
||||
T col_mean (INDEX i=0) const { return column(*this,i).mean(); }
|
||||
T col_norm (INDEX i=0) const { return column(*this,i).norm(); }
|
||||
T col_stdev(INDEX i=0) const { return column(*this,i).stdev(); }
|
||||
|
||||
// pure virtual functions (required to implement these) ---------------------
|
||||
//* reference index operator
|
||||
virtual T& operator()(INDEX i, INDEX j)=0;
|
||||
//* value index operator
|
||||
virtual T operator()(INDEX i, INDEX j)const=0;
|
||||
//* value flat index operator
|
||||
virtual T& operator [](INDEX i)=0;
|
||||
//* reference flat index operator
|
||||
virtual T operator [](INDEX i) const=0;
|
||||
//* returns the # of rows
|
||||
virtual INDEX nRows() const=0;
|
||||
//* returns the # of columns
|
||||
virtual INDEX nCols() const=0;
|
||||
//* returns a pointer to the data (dangerous)
|
||||
virtual T * get_ptr() const=0;
|
||||
//* resizes the matrix, copy what fits default to OFF
|
||||
virtual void resize(INDEX nRows, INDEX nCols=1, bool copy=false)=0;
|
||||
//* resizes the matrix, zero it out default to ON
|
||||
virtual void reset(INDEX nRows, INDEX nCols=1, bool zero=true)=0;
|
||||
//* resizes and copies data
|
||||
virtual void copy(const T * ptr, INDEX nRows, INDEX nCols=1)=0;
|
||||
//* create restart file
|
||||
virtual void write_restart(FILE *f) const=0;
|
||||
//* writes a matlab command to recreate this in a variable named s
|
||||
virtual void matlab(ostream &o, const string &s="M") const;
|
||||
|
||||
// output to matlab, with variable name s
|
||||
void matlab(const string &s="M") const;
|
||||
|
||||
Matrix<T>& operator+=(const Matrix &r);
|
||||
Matrix<T>& operator-=(const Matrix &r);
|
||||
//* NOTE these two functions are scaling operations not A.B
|
||||
Matrix<T>& operator*=(const Matrix<T>& R);
|
||||
Matrix<T>& operator/=(const Matrix<T>& R);
|
||||
Matrix<T>& operator+=(const T v);
|
||||
Matrix<T>& operator-=(const T v);
|
||||
Matrix<T>& operator*=(const T v);
|
||||
Matrix<T>& operator/=(T v);
|
||||
|
||||
Matrix<T>& operator=(const T &v);
|
||||
Matrix<T>& operator=(const Matrix<T> &c);
|
||||
virtual void set_all_elements_to(const T &v);
|
||||
//* adds a matrix scaled by factor s to this one.
|
||||
void add_scaled(const Matrix<T> &A, const T& s);
|
||||
|
||||
//* sets all elements to zero
|
||||
Matrix& zero();
|
||||
//* returns the total number of elements
|
||||
virtual INDEX size() const;
|
||||
//* returns true if (i,j) is within the range of the matrix
|
||||
bool in_range(INDEX i, INDEX j) const;
|
||||
//* returns true if the matrix size is rs x cs
|
||||
bool is_size(INDEX rs, INDEX cs) const;
|
||||
//* returns true if the matrix is square and not empty
|
||||
bool is_square() const;
|
||||
//* returns true if Matrix, m, is the same size as this
|
||||
bool same_size(const Matrix &m) const;
|
||||
//* returns true if Matrix a and Matrix b are the same size
|
||||
static bool same_size(const Matrix<T> &a, const Matrix<T> &b);
|
||||
//* checks if memory is contiguous, only can be false for clone vector
|
||||
virtual bool memory_contiguous() const { return true; }
|
||||
|
||||
protected:
|
||||
virtual void _set_equal(const Matrix<T> &r);
|
||||
};
|
||||
|
||||
//* Matrix operations
|
||||
//@{
|
||||
//* Sets C as b*C + a*A[tranpose?]*B[transpose?]
|
||||
template<typename T>
|
||||
void MultAB(const Matrix<T> &A, const Matrix<T> &B, DenseMatrix<T> &C,
|
||||
bool At=0, bool Bt=0, T a=1, T b=0);
|
||||
//* performs a matrix-vector multiply
|
||||
template<typename T>
|
||||
void MultMv(const Matrix<T> &A, const Vector<T> &v, DenseVector<T> &c,
|
||||
const bool At, T a, T b);
|
||||
// returns the inverse of a double precision matrix
|
||||
DenseMatrix<double> inv(const Matrix<double>& A);
|
||||
//* returns the trace of a matrix
|
||||
template<typename T>
|
||||
T trace(const Matrix<T>& A) { return A.trace(); }
|
||||
//* computes the determinant of a square matrix
|
||||
double det(const Matrix<double>& A);
|
||||
//* Returns the maximum eigenvalue of a matrix.
|
||||
double max_eigenvalue(const Matrix<double>& A);
|
||||
//@}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// computes the sum of the difference squared of each element.
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
double sum_difference_squared(const Matrix<T>& A, const Matrix<T> &B)
|
||||
{
|
||||
SSCK(A, B, "sum_difference_squared");
|
||||
double v=0.0;
|
||||
for (unsigned i=0; i<A.size(); i++) {
|
||||
double d = A[i]-B[i];
|
||||
v += d*d;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Operator for Matrix-matrix product
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const Matrix<T> &A, const Matrix<T> &B)
|
||||
{
|
||||
DenseMatrix<T> C(0,0,false);
|
||||
MultAB(A,B,C);
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Multiply a Matrix by a scalar
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const Matrix<T> &M, const T s)
|
||||
{
|
||||
DenseMatrix<T> R(M);
|
||||
return R*=s;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Multiply a Matrix by a scalar
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const T s, const Matrix<T> &M)
|
||||
{
|
||||
DenseMatrix<T> R(M);
|
||||
return R*=s;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* inverse scaling operator - must always create memory
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator/(const Matrix<T> &M, const T s)
|
||||
{
|
||||
DenseMatrix<T> R(M);
|
||||
return R*=(1.0/s); // for integer types this may be worthless
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Operator for Matrix-matrix sum
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator+(const Matrix<T> &A, const Matrix<T> &B)
|
||||
{
|
||||
DenseMatrix<T> C(A);
|
||||
return C+=B;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Operator for Matrix-matrix subtraction
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator-(const Matrix<T> &A, const Matrix<T> &B)
|
||||
{
|
||||
DenseMatrix<T> C(A);
|
||||
return C-=B;
|
||||
}
|
||||
/******************************************************************************
|
||||
* Template definitions for class Matrix
|
||||
******************************************************************************/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//* performs a matrix-matrix multiply with general type implementation
|
||||
template<typename T>
|
||||
void MultAB(const Matrix<T> &A, const Matrix<T> &B, DenseMatrix<T> &C,
|
||||
const bool At, const bool Bt, T a, T b)
|
||||
{
|
||||
const INDEX sA[2] = {A.nRows(), A.nCols()}; // m is sA[At] k is sA[!At]
|
||||
const INDEX sB[2] = {B.nRows(), B.nCols()}; // k is sB[Bt] n is sB[!Bt]
|
||||
const INDEX M=sA[At], K=sB[Bt], N=sB[!Bt];
|
||||
GCK(A, B, sA[!At]!=K, "MultAB<T> shared index not equal size");
|
||||
if (!C.is_size(M,N))
|
||||
{
|
||||
C.resize(M,N); // set size of C
|
||||
C.zero();
|
||||
}
|
||||
else C *= b;
|
||||
for (INDEX p=0; p<M; p++)
|
||||
for (INDEX q=0; q<N; q++)
|
||||
for (INDEX r=0; r<K; r++)
|
||||
C(p,q) += A(p*!At+r*At, p*At+r*!At) * B(r*!Bt+q*Bt, r*Bt+q*!Bt);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//* output operator
|
||||
template<typename T>
|
||||
string Matrix<T>::tostring() const
|
||||
{
|
||||
string s;
|
||||
for (INDEX i=0; i<nRows(); i++)
|
||||
{
|
||||
if (i) s += '\n';
|
||||
for (INDEX j=0; j<nCols(); j++)
|
||||
{
|
||||
if (j) s+= '\t';
|
||||
s += ATC_STRING::tostring(MIDX(i,j),5)+" ";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* output operator that wraps the matrix in a nice labeled box
|
||||
template<typename T>
|
||||
void Matrix<T>::print(ostream &o, const string &name) const
|
||||
{
|
||||
o << "------- Begin "<<name<<" -----------------\n";
|
||||
this->print(o);
|
||||
o << "\n------- End "<<name<<" -------------------\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* print operator, use cout by default
|
||||
template<typename T>
|
||||
void Matrix<T>::print() const
|
||||
{
|
||||
print(cout);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* named print operator, use cout by default
|
||||
template<typename T>
|
||||
void Matrix<T>::print(const string &name) const
|
||||
{
|
||||
print(cout, name);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* element by element division
|
||||
template<typename T>
|
||||
DenseMatrix<T> Matrix<T>::operator/ (const Matrix<T>& B) const
|
||||
{
|
||||
SSCK(*this, B, "Matrix<T>::Operator/");
|
||||
DenseMatrix<T> R(*this);
|
||||
R /= B;
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* element-wise raise to a power
|
||||
template<typename T>
|
||||
DenseMatrix<T> Matrix<T>::pow(int n) const
|
||||
{
|
||||
DenseMatrix<T> R(*this);
|
||||
FORi
|
||||
{
|
||||
double val = R[i];
|
||||
for (int k=1; k<n; k++) val *= R[i];
|
||||
for (int k=n; k<1; k++) val /= R[i];
|
||||
R[i] = val;
|
||||
}
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* element-wise raise to a power
|
||||
template<typename T>
|
||||
DenseMatrix<T> Matrix<T>::pow(double n) const
|
||||
{
|
||||
DenseMatrix<T> R(*this);
|
||||
FORi
|
||||
{
|
||||
double val = R[i];
|
||||
R[i] = pow(val,n);
|
||||
}
|
||||
return R;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the transpose of this matrix (makes a copy)
|
||||
template <typename T>
|
||||
DenseMatrix<T> Matrix<T>::transpose() const
|
||||
{
|
||||
DenseMatrix<T> t(this->nCols(), this->nRows());
|
||||
FORij t(j,i) = (*this)(i,j);
|
||||
return t;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the transpose of a matrix (makes a copy)
|
||||
template <typename T>
|
||||
DenseMatrix<T> transpose(const Matrix<T> &A)
|
||||
{
|
||||
return A.transpose();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the sum of all matrix elements
|
||||
template<typename T>
|
||||
T Matrix<T>::sum() const
|
||||
{
|
||||
if (!size()) return T(0);
|
||||
T v = VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v += VIDX(i);
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the standard deviation of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::stdev() const
|
||||
{
|
||||
GCHK(this->size()<2, "Matrix::stdev() size must be > 1");
|
||||
T mean = this->mean();
|
||||
T diff = VIDX(0)-mean;
|
||||
T stdev = diff*diff;
|
||||
for (INDEX i=1; i<this->size(); i++)
|
||||
{
|
||||
diff = VIDX(i)-mean;
|
||||
stdev += diff*diff;
|
||||
}
|
||||
return sqrt(stdev/T(this->size()-1));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the maximum of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::max() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::max() size must be > 0");
|
||||
T v = VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v = std::max(v, VIDX(i));
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the minimum of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::min() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::min() size must be > 0");
|
||||
T v = VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v = std::min(v, VIDX(i));
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the maximum absolute value of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::maxabs() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::maxabs() size must be > 0");
|
||||
T v = VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v = Utility::MaxAbs(v, VIDX(i));
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the minimum absoute value of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::minabs() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::minabs() size must be > 0");
|
||||
T v = VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v = Utility::MinAbs(v, VIDX(i));
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the L2 norm of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::norm() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::norm() size must be > 0");
|
||||
return sqrt(dot(*this));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the average of the matrix
|
||||
template<typename T>
|
||||
T Matrix<T>::mean() const
|
||||
{
|
||||
GCHK(!this->size(), "Matrix::mean() size must be > 0");
|
||||
return sum()/T(this->size());
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Returns the dot product of two vectors
|
||||
template<typename T>
|
||||
T Matrix<T>::dot(const Matrix<T>& r) const
|
||||
{
|
||||
SSCK(*this, r, "Matrix<T>::dot");
|
||||
if (!this->size()) return T(0);
|
||||
T v = r[0]*VIDX(0);
|
||||
for (INDEX i=1; i<this->size(); i++) v += r[i]*VIDX(i);
|
||||
return v;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the sum of the matrix diagonal
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T Matrix<T>::trace() const
|
||||
{
|
||||
const INDEX N = std::min(nRows(),nCols());
|
||||
if (!N) return T(0);
|
||||
T r = MIDX(0,0);
|
||||
for (INDEX i=0; i<N; i++)
|
||||
r += MIDX(i,i);
|
||||
return r;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Adds a matrix to this one
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator+=(const Matrix &r)
|
||||
{
|
||||
SSCK(*this, r, "operator+= or operator +");
|
||||
FORi VIDX(i)+=r[i];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// subtracts a matrix from this one
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator-=(const Matrix &r)
|
||||
{
|
||||
SSCK(*this, r, "operator-= or operator -");
|
||||
FORi VIDX(i)-=r[i];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiplies each element in this by the corresponding element in R
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& R)
|
||||
{
|
||||
SSCK(*this, R, "operator*=");
|
||||
FORi
|
||||
{
|
||||
VIDX(i) *= R[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// divides each element in this by the corresponding element in R
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator/=(const Matrix<T>& R)
|
||||
{
|
||||
SSCK(*this, R, "operator/= or operator/");
|
||||
FORi
|
||||
{
|
||||
GCHK(fabs(R[i])>0,"Operator/: division by zero");
|
||||
VIDX(i) /= R[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// scales this matrix by a constant
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator*=(const T v)
|
||||
{
|
||||
FORi VIDX(i)*=v;
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// adds a constant to this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator+=(const T v)
|
||||
{
|
||||
FORi VIDX(i)+=v;
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// substracts a constant to this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator-=(const T v)
|
||||
{
|
||||
FORi VIDX(i)-=v;
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* scales this matrix by the inverse of a constant
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator/=(T v)
|
||||
{
|
||||
return (*this)*=(1.0/v);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Assigns one matrix to another
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
Matrix<T>& Matrix<T>::operator=(const Matrix<T> &r)
|
||||
{
|
||||
this->_set_equal(r);
|
||||
return *this;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// general matrix assignment (for densely packed matrices)
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void Matrix<T>::_set_equal(const Matrix<T> &r)
|
||||
{
|
||||
this->resize(r.nRows(), r.nCols());
|
||||
const Matrix<T> *pr = &r;
|
||||
if (const SparseMatrix<T> *ps = sparse_cast(pr))
|
||||
copy_sparse_to_matrix(ps, *this);
|
||||
|
||||
else if (diag_cast(pr)) // r is Diagonal?
|
||||
{
|
||||
this->zero();
|
||||
for (INDEX i=0; i<r.size(); i++) MIDX(i,i) = r[i];
|
||||
}
|
||||
else memcpy(this->get_ptr(), r.get_ptr(), r.size()*sizeof(T));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* sets all elements to a constant
|
||||
template<typename T>
|
||||
inline Matrix<T>& Matrix<T>::operator=(const T &v)
|
||||
{
|
||||
set_all_elements_to(v);
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* sets all elements to a constant
|
||||
template<typename T>
|
||||
void Matrix<T>::set_all_elements_to(const T &v)
|
||||
{
|
||||
FORi VIDX(i) = v;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// adds a matrix scaled by factor s to this one.
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void Matrix<T>::add_scaled(const Matrix<T> &A, const T& s)
|
||||
{
|
||||
SSCK(A, *this, "Matrix::add_scaled");
|
||||
FORi VIDX(i) += A[i]*s;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* writes a matlab command to the console
|
||||
template<typename T>
|
||||
void Matrix<T>::matlab(const string &s) const
|
||||
{
|
||||
this->matlab(cout, s);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Writes a matlab script defining the vector to the stream
|
||||
template<typename T>
|
||||
void Matrix<T>::matlab(ostream &o, const string &s) const
|
||||
{
|
||||
o << s <<"=zeros(" << nRows() << ","<<nCols()<<");\n";
|
||||
FORij o << s << "("<<i+1<<","<<j+1<<")=" << MIDX(i,j) << ";\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* sets all matrix elements to zero
|
||||
template<typename T>
|
||||
inline Matrix<T>& Matrix<T>::zero()
|
||||
{
|
||||
set_all_elements_to(T(0));
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns the total number of elements
|
||||
template<typename T>
|
||||
inline INDEX Matrix<T>::size() const
|
||||
{
|
||||
return nRows()*nCols();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns true if (i,j) is within the range of the matrix
|
||||
template<typename T>
|
||||
inline bool Matrix<T>::in_range(INDEX i, INDEX j) const
|
||||
{
|
||||
return i<nRows() && j<nCols();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns true if the matrix size is rs x cs
|
||||
template<typename T>
|
||||
inline bool Matrix<T>::is_size(INDEX rs, INDEX cs) const
|
||||
{
|
||||
return nRows()==rs && nCols()==cs;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns true if the matrix is square and not empty
|
||||
template<typename T>
|
||||
inline bool Matrix<T>::is_square() const
|
||||
{
|
||||
return nRows()==nCols() && nRows();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns true if Matrix, m, is the same size as this
|
||||
template<typename T>
|
||||
inline bool Matrix<T>::same_size(const Matrix<T> &m) const
|
||||
{
|
||||
return is_size(m.nRows(), m.nCols());
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* returns true if Matrix a and Matrix b are the same size
|
||||
template<typename T>
|
||||
inline bool Matrix<T>::same_size(const Matrix<T> &a, const Matrix<T> &b)
|
||||
{
|
||||
return a.same_size(b);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Displays indexing error message and quits
|
||||
template<typename T>
|
||||
void ierror(const Matrix<T> &a, const char *FILE, int LINE, INDEX i, INDEX j)
|
||||
{
|
||||
cout << "Error: Matrix indexing failure ";
|
||||
cout << "in file: " << FILE << ", line: "<< LINE <<"\n";
|
||||
cout << "Tried accessing index (" << i << ", " << j <<")\n";
|
||||
cout << "Matrix size was "<< a.nRows() << "x" << a.nCols() << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Displays custom message and indexing error and quits
|
||||
template<typename T>
|
||||
void ierror(const Matrix<T> &a, INDEX i, INDEX j, const string m)
|
||||
{
|
||||
cout << m << "\n";
|
||||
cout << "Tried accessing index (" << i << ", " << j <<")\n";
|
||||
cout << "Matrix size was "<< a.nRows() << "x" << a.nCols() << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//* Displays matrix compatibility error message
|
||||
template<typename T>
|
||||
void merror(const Matrix<T> &a, const Matrix<T> &b, const string m)
|
||||
{
|
||||
cout << "Error: " << m << "\n";
|
||||
cout << "Matrix sizes were " << a.nRows() << "x" << a.nCols();
|
||||
if (&a != &b) cout << ", and "<< b.nRows() << "x" << b.nCols();
|
||||
cout << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,184 +0,0 @@
|
|||
#ifndef MATRIXDEF_H
|
||||
#define MATRIXDEF_H
|
||||
|
||||
/******************************************************************************
|
||||
* Common definitions for Matrix and Vector classes
|
||||
* This header file contains macros and inline functions needed for the matrix
|
||||
* classes. All error checking should be defined here as a macro so that it is
|
||||
* neatly disabled when EXTENDED_ERROR_CHECKING is not defined
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* Headers and namespaces used by Matrix and Vector classes
|
||||
******************************************************************************/
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "StringManip.h"
|
||||
#include "Utility.h"
|
||||
|
||||
using std::cout;
|
||||
using std::ostream;
|
||||
using std::fstream;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::scientific;
|
||||
using std::showbase;
|
||||
|
||||
/******************************************************************************
|
||||
* Typedefs used by Matrix and Vector classes
|
||||
******************************************************************************/
|
||||
//* @typedef INDEX
|
||||
//* @brief indexing type (default: unsigned) for matrix classes
|
||||
typedef unsigned INDEX;
|
||||
//* @typedef CLONE_TYPE
|
||||
//* @brief dimension of matrix to clone
|
||||
enum CLONE_TYPE { CLONE_ROW=0, CLONE_COL=1, CLONE_DIAG=2 };
|
||||
//* @struct TRIPLET
|
||||
//* @brief Triplet output entity
|
||||
template <typename T>
|
||||
struct TRIPLET { TRIPLET<T>(int _i=0, int _j=0, T _v=T(0)) : i(_i), j(_j), v(_v) {}
|
||||
INDEX i, j; T v; };
|
||||
|
||||
/******************************************************************************
|
||||
* Definitions for row/column major storage
|
||||
******************************************************************************/
|
||||
#define COL_STORAGE /* <--- comment out this line for row-major storage*/
|
||||
#ifdef COL_STORAGE
|
||||
#define DATA(i,j) _data[(i)+_nRows*(j)]
|
||||
#else
|
||||
#define ROW_STORAGE
|
||||
#define DATA(i,j) _data[(i)*_nCols+(j)]
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* error checking macros
|
||||
* MICK: checks if index (i,j) is in range MATRIX ONLY
|
||||
* VICK: checks if index (i) is in range VECTOR ONLY
|
||||
* MICM: checks if index (i,j) is in range, displays message MATRIX ONLY
|
||||
* VICM: checks if index (i) is in range, displays message VECTOR ONLY
|
||||
* SQCK: checks if matrix is square, displays message MATRIX ONLY
|
||||
* SSCK: checks if a has the same size as b VECTOR/MATRIX
|
||||
* GCK: generic two object check, checks if c is true VECTOR/MATRIX
|
||||
* GCHK: generic check, checks if c is true ANYTHING
|
||||
******************************************************************************/
|
||||
#define MICK(i,j) /**/
|
||||
#define VICK(i) /**/
|
||||
#define MICM(i,j,m) /**/
|
||||
#define VICM(i,m) /**/
|
||||
#define SQCK(a,m) /**/
|
||||
#define SSCK(a,b,m) /**/
|
||||
#define SSCK(a,b,m) /**/
|
||||
#define GCK(a,b,c,m) /**/
|
||||
#define GCHK(c,m) /**/
|
||||
|
||||
// the following two convert __LINE__ to a string
|
||||
#define STRING2(x) #x
|
||||
#define STRING(x) STRING2(x)
|
||||
// prints file and line number for error messages
|
||||
#define ERROR(x) __FILE__":"STRING(__LINE__)" "x
|
||||
|
||||
/******************************************************************************
|
||||
* Shortcuts for Vector and Matrix indexing
|
||||
******************************************************************************/
|
||||
#define MIDX(i,j) (*this)(i,j)
|
||||
#define VIDX(i) (*this)[i]
|
||||
/******************************************************************************
|
||||
* Shortcuts for Vector and Matrix loops over all elements
|
||||
******************************************************************************/
|
||||
#define FORi for(INDEX i=0; i<this->size(); i++)
|
||||
#define FORij for(INDEX i=0; i<nRows(); i++) for (INDEX j=0; j<nCols(); j++)
|
||||
|
||||
/******************************************************************************
|
||||
* BLAS and LAPACK definitions
|
||||
******************************************************************************/
|
||||
#ifdef MKL
|
||||
#include "mkl.h"
|
||||
#define dgemv_ dgemv
|
||||
#define dgemm_ dgemm
|
||||
#define dgetrf_ dgetrf
|
||||
#define dgetri_ dgetri
|
||||
#define dgecon_ dgecon
|
||||
#define dlange_ dlange
|
||||
#else
|
||||
extern "C"
|
||||
{
|
||||
extern void dgemv_(char*,int*,int*,double*,const double*,int*,const double*,int *,double*,double*,int*);
|
||||
extern void dgemm_(char*,char*,int*,int*,int*,double*,const double*,int*,const double*,int*,double*,double*,int*);
|
||||
extern void dgetrf_(int*,int*,double*,int*,int*,int*);
|
||||
extern void dgetri_(int*,double*,int*,int*,double*,int*,int*);
|
||||
extern void dgecon_(char*,int*,double*,int*,double*,double*,double*,int*,int*);
|
||||
extern double dlange_(char*,int*,int*,const double*,int*,double*);
|
||||
};
|
||||
#endif
|
||||
|
||||
// forward declarations of matrix and vector classes
|
||||
template<typename T> class Matrix;
|
||||
template<typename T> class DenseMatrix;
|
||||
template<typename T> class SparseMatrix;
|
||||
template<typename T> class SparseVector;
|
||||
template<typename T> class DiagonalMatrix;
|
||||
template<typename T> class Vector;
|
||||
template<typename T> class DenseVector;
|
||||
template<typename T> class CloneVector;
|
||||
|
||||
//* forward declaration of operations
|
||||
//@{
|
||||
template<class T> DenseVector<T> operator*(const Matrix<T> &M, const SparseVector<T> &v);
|
||||
template<class T> DenseVector<T> operator*(const SparseVector<T> &v, const Matrix<T> &M);
|
||||
template<class T> SparseVector<T> operator*(const SparseMatrix<T> &M, const SparseVector<T> &v);
|
||||
template<class T> SparseVector<T> operator*(const SparseVector<T> &v, const SparseMatrix<T> &M);
|
||||
template<class T> DenseVector<T> operator*(const SparseMatrix<T> &A, const Vector<T>& x);
|
||||
template<class T> DenseVector<T> operator*(const Vector<T> &A, const SparseMatrix<T>& x);
|
||||
template<class T> DenseMatrix<T> operator*(const SparseMatrix<T> &A, const Matrix<T>& D);
|
||||
template<class T> SparseMatrix<T> operator*(const SparseMatrix<T> &A, const DiagonalMatrix<T>& D);
|
||||
template<class T> SparseMatrix<T> operator*(const SparseMatrix<T> &A, const SparseMatrix<T> &B);
|
||||
template<class T> T dot(const SparseVector<T> &a, const SparseVector<T> &b);
|
||||
//@}
|
||||
|
||||
template<class T> CloneVector<T> column(Matrix<T> &c, INDEX i) {
|
||||
return CloneVector<T>(c, CLONE_COL, i);
|
||||
}
|
||||
template<class T> CloneVector<T> row(Matrix<T> &c, INDEX i) {
|
||||
return CloneVector<T>(c, CLONE_ROW, i);
|
||||
}
|
||||
template<class T> CloneVector<T> diagonal(Matrix<T> &c) {
|
||||
return CloneVector<T>(c, CLONE_DIAG);
|
||||
}
|
||||
template<class T> const CloneVector<T> column(const Matrix<T> &c, INDEX i) {
|
||||
return CloneVector<T>(c, CLONE_COL, i);
|
||||
}
|
||||
template<class T> const CloneVector<T> row(const Matrix<T> &c, INDEX i) {
|
||||
return CloneVector<T>(c, CLONE_ROW, i);
|
||||
}
|
||||
template<class T> const CloneVector<T> diagonal(const Matrix<T> &c) {
|
||||
return CloneVector<T>(c, CLONE_DIAG);
|
||||
}
|
||||
template<class T> const SparseMatrix<T> *sparse_cast(const Matrix<T> *m);
|
||||
template<class T> const DiagonalMatrix<T> *diag_cast(const Matrix<T> *m);
|
||||
template<class T> void copy_sparse_to_matrix(const SparseMatrix<T> *s, Matrix<T> &m);
|
||||
|
||||
// double precision shortcuts
|
||||
typedef Matrix<double> MATRIX; // matrix of double
|
||||
typedef Vector<double> VECTOR; // vector of double
|
||||
typedef DenseMatrix<double> DENS_MAT; // dense matrix of double type
|
||||
typedef CloneVector<double> CLON_VEC; // cloned vector of double type
|
||||
typedef DenseVector<double> DENS_VEC; // dense vector of double type
|
||||
typedef DiagonalMatrix<double> DIAG_MAT; // diagonal matrix of double type
|
||||
typedef SparseMatrix<double> SPAR_MAT; // sparse matrix of double type
|
||||
typedef SparseVector<double> SPAR_VEC; // sparse matrix of double type
|
||||
typedef Vector<INDEX> IVECTOR; // general Vector of INDEX type
|
||||
|
||||
// forward declaration of error messages
|
||||
template<typename T> void ierror(const Matrix<T> &a, const char *FILE, int LINE, INDEX i, INDEX j=0);
|
||||
template<typename T> void ierror(const Matrix<T> &a, INDEX i, INDEX j, const string m);
|
||||
template<typename T> void merror(const Matrix<T> &a, const Matrix<T> &b, const string m);
|
||||
inline void gerror(const string m) { cout<<"Error: "<<m<<"\n"; exit(EXIT_FAILURE); }
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef MATRIXLIBRARY_H
|
||||
#define MATRIXLIBRARY_H
|
||||
|
||||
#include "DenseMatrix.h"
|
||||
#include "DenseVector.h"
|
||||
#include "CloneVector.h"
|
||||
#include "DiagonalMatrix.h"
|
||||
#include "SparseMatrix.h"
|
||||
#include "SparseVector.h"
|
||||
|
||||
template<typename T>
|
||||
const SparseMatrix<T> *sparse_cast(const Matrix<T> *m)
|
||||
{
|
||||
return dynamic_cast<const SparseMatrix<T>*>(m);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void copy_sparse_to_matrix(const SparseMatrix<T> *s, Matrix<T> &m)
|
||||
{
|
||||
m.zero();
|
||||
TRIPLET<T> triplet;
|
||||
for (INDEX i=0; i<s->size(); i++)
|
||||
{
|
||||
triplet = s->get_triplet(i);
|
||||
m(triplet.i, triplet.j) = triplet.v;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,706 +0,0 @@
|
|||
#include <string>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include "OutputManager.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
//#define EXTENDED_ERROR_CHECKING
|
||||
|
||||
namespace ATC {
|
||||
|
||||
static const int kFieldPrecison = 12;
|
||||
static const int kFieldWidth = kFieldPrecison + 6;
|
||||
|
||||
static const int kFileNameSize = 26;
|
||||
static string tensor_component_names[9] = {"11","12","13",
|
||||
"21","22","23",
|
||||
"31","32","33"};
|
||||
static string sym_tensor_component_names[6] = {"11","22","33","12","13","23"};
|
||||
static string vector_component_names[3] = {"_X","_Y","_Z"};
|
||||
static string list_component_names[26] = {"_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z"};
|
||||
|
||||
string* get_component_names(int type) {
|
||||
string* componentNames = list_component_names;
|
||||
if (type==VECTOR_OUTPUT)
|
||||
componentNames = vector_component_names;
|
||||
else if (type == SYM_TENSOR_OUTPUT)
|
||||
componentNames = sym_tensor_component_names;
|
||||
else if (type == TENSOR_OUTPUT)
|
||||
componentNames = tensor_component_names;
|
||||
return componentNames;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
OutputManager::OutputManager(string outputPrefix, OutputType otype)
|
||||
: outputPrefix_(outputPrefix),
|
||||
dataType_(POINT),
|
||||
outputType_(otype),
|
||||
firstStep_(true),
|
||||
writeGlobalsHeader_(true),
|
||||
firstGlobalsWrite_(true),
|
||||
tensorToComponents_(false), // paraview does not support tensors
|
||||
vectorToComponents_(false),
|
||||
initialized_(false)
|
||||
{}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
OutputManager::OutputManager()
|
||||
: outputPrefix_("NULL"),
|
||||
dataType_(POINT),
|
||||
outputType_(ENSIGHT),
|
||||
firstStep_(true),
|
||||
writeGlobalsHeader_(true),
|
||||
firstGlobalsWrite_(true),
|
||||
tensorToComponents_(false), // paraview does not support tensors
|
||||
vectorToComponents_(false),
|
||||
initialized_(false)
|
||||
{}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
OutputManager::~OutputManager() {}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::set_option(OutputOption option, bool value) {
|
||||
if (option == OUTPUT_VECTOR_COMPONENTS) vectorToComponents_ = value;
|
||||
else if (option == OUTPUT_TENSOR_COMPONENTS) tensorToComponents_ = value;
|
||||
else throw ATC_Error(0,"unsupported output option");
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::initialize(string outputPrefix, OutputType otype)
|
||||
{
|
||||
if (outputPrefix_ != outputPrefix ) { // new stream with existing object
|
||||
outputPrefix_ = outputPrefix;
|
||||
initialized_ = false;
|
||||
}
|
||||
outputTimes_.clear();
|
||||
outputType_ = otype;
|
||||
firstStep_ = true;
|
||||
firstGlobalsWrite_ = true;
|
||||
writeGlobalsHeader_ = true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dump text-based fields to disk for later restart
|
||||
void OutputManager::write_restart_file(string fileName, OUTPUT_LIST *data)
|
||||
{
|
||||
FILE * fp=NULL;
|
||||
fp=fopen(fileName.c_str(),"wb"); // open
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++) {
|
||||
const MATRIX* field_data = iter->second;
|
||||
for (int i = 0; i < field_data->nRows(); ++i) {
|
||||
for (int j = 0; j < field_data->nCols(); ++j) {
|
||||
double x = (*field_data)(i,j);
|
||||
fwrite(&x,sizeof(double),1,fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read a file corresponding to a write by write_restart_file
|
||||
void OutputManager::read_restart_file(string fileName, OUTPUT_LIST *data)
|
||||
{
|
||||
FILE * fp=NULL;
|
||||
fp=fopen(fileName.c_str(),"rb"); // open
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++) {
|
||||
MATRIX* field_data = iter->second;
|
||||
for (int i = 0; i < field_data->nRows(); ++i) {
|
||||
for (int j = 0; j < field_data->nCols(); ++j) {
|
||||
double myVal;
|
||||
fread(&myVal,sizeof(double),1,fp);
|
||||
(*field_data)(i,j) = myVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_globals(void)
|
||||
{
|
||||
if ( outputPrefix_ == "NULL") return;
|
||||
string file = outputPrefix_ + ".GLOBALS";
|
||||
ofstream text;
|
||||
if ( firstGlobalsWrite_ ) text.open(file.c_str(),ios_base::out);
|
||||
else text.open(file.c_str(),ios_base::app);
|
||||
firstGlobalsWrite_ = false;
|
||||
|
||||
map<string, double>::iterator iter;
|
||||
// header
|
||||
if ( firstStep_ || writeGlobalsHeader_) {
|
||||
text << "# time:1 ";
|
||||
int index = 2;
|
||||
for (iter = globalData_.begin(); iter != globalData_.end(); iter++)
|
||||
{
|
||||
string name = iter->first;
|
||||
string str; stringstream out; out << ":" << index++;
|
||||
str = out.str();
|
||||
name.append(str);
|
||||
text.width(kFieldWidth); text << name << " ";
|
||||
}
|
||||
text << '\n';
|
||||
}
|
||||
writeGlobalsHeader_ = false;
|
||||
// data
|
||||
text.width(kFieldWidth); text << outputTimes_[outputTimes_.size()-1] << " ";
|
||||
for (iter = globalData_.begin();
|
||||
iter != globalData_.end(); iter++) {
|
||||
double value = iter->second;
|
||||
text << setw(kFieldWidth) << std::scientific << std::setprecision(kFieldPrecison) << value << " ";
|
||||
}
|
||||
text << "\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_geometry(const MATRIX &coordinates,
|
||||
const Array2D<int> *connectivities)
|
||||
{
|
||||
if ( outputPrefix_ == "NULL") return;
|
||||
// geometry based on a reference configuration
|
||||
string geom_file_name = outputPrefix_ + ".geo";
|
||||
string geom_file_text = outputPrefix_ + ".XYZ";
|
||||
|
||||
// open file
|
||||
FILE * fp=NULL;
|
||||
ofstream text;
|
||||
char buffer[80];
|
||||
if ( ! initialized_ ) {
|
||||
fp=fopen(geom_file_name.c_str(),"wb"); // open
|
||||
strcpy(buffer,"C Binary");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// write geometry once
|
||||
if (outputType_ == GNUPLOT) text.open(geom_file_text.c_str(),ios_base::out);
|
||||
}
|
||||
else {
|
||||
fp=fopen(geom_file_name.c_str(),"ab"); // append
|
||||
|
||||
// if (outputType_ == GNUPLOT) text.open(geom_file_text.c_str(),ios_base::app);
|
||||
}
|
||||
if (fp == NULL) {
|
||||
throw ATC_Error(0,"can not create Ensight geometry file");
|
||||
}
|
||||
|
||||
// write preamble
|
||||
strcpy(buffer,"BEGIN TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"Ensight geometry file");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"description");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"node id assign");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"element id assign");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// per part
|
||||
strcpy(buffer,"part");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
int part_number=1;
|
||||
fwrite(&part_number,sizeof(int),1,fp);
|
||||
strcpy(buffer,"description");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// write coordinates
|
||||
strcpy(buffer,"coordinates");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
number_of_nodes_ = coordinates.nCols();
|
||||
fwrite(&number_of_nodes_,sizeof(int),1,fp);
|
||||
int number_of_spatial_dimensions = coordinates.nRows();
|
||||
if (number_of_spatial_dimensions != 3)
|
||||
throw ATC_Error(0,"Ensight writer needs a 3D geometry");
|
||||
|
||||
for (int i = 0; i < number_of_spatial_dimensions; ++i)
|
||||
{
|
||||
for (int j = 0; j < number_of_nodes_; ++j)
|
||||
{
|
||||
float x = (float) coordinates(i,j);
|
||||
fwrite(&x,sizeof(float),1,fp);
|
||||
}
|
||||
}
|
||||
|
||||
// write mesh connectivities or point "connectivities"
|
||||
if (connectivities)
|
||||
{
|
||||
dataType_ = MESH;
|
||||
strcpy(buffer,"hexa8");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
int number_of_elements = connectivities->nCols();
|
||||
fwrite(&number_of_elements,sizeof(int),1,fp);
|
||||
int number_of_nodes_per_element = connectivities->nRows();
|
||||
for (int j = 0; j < number_of_elements; ++j)
|
||||
{
|
||||
for (int i = 0; i < number_of_nodes_per_element; ++i)
|
||||
{
|
||||
int inode = (*connectivities)(i,j) +1; // 1 based numbering
|
||||
fwrite(&inode,sizeof(int),1,fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buffer,"point");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
int number_of_elements = number_of_nodes_;
|
||||
fwrite(&number_of_elements,sizeof(int),1,fp);
|
||||
int number_of_nodes_per_element = 1;
|
||||
for (int j = 0; j < number_of_elements; ++j)
|
||||
{
|
||||
int inode = j +1; // 1 based numbering
|
||||
fwrite(&inode,sizeof(int),1,fp);
|
||||
}
|
||||
}
|
||||
|
||||
// end per part
|
||||
strcpy(buffer,"END TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
fclose(fp);
|
||||
|
||||
// text output
|
||||
if (outputType_ == GNUPLOT )
|
||||
{
|
||||
for (int j = 0; j < number_of_nodes_; ++j)
|
||||
{
|
||||
for (int i = 0; i < number_of_spatial_dimensions; ++i)
|
||||
{
|
||||
text << setw(kFieldWidth) << std::scientific << std::setprecision(kFieldPrecison) << coordinates(i,j) << " ";
|
||||
}
|
||||
text << "\n";
|
||||
}
|
||||
text << "\n";
|
||||
}
|
||||
|
||||
if (!initialized_) initialized_ = true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//*
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_geometry(OUTPUT_LIST &part_coordinates)
|
||||
{
|
||||
if ( outputPrefix_ == "NULL") return;
|
||||
// geometry based on a reference configuration
|
||||
string geom_file_name = outputPrefix_ + ".geo";
|
||||
string geom_file_text = outputPrefix_ + ".XYZ";
|
||||
|
||||
// open file
|
||||
FILE * fp =NULL;
|
||||
ofstream text;
|
||||
char buffer[80];
|
||||
if ( ! initialized_ )
|
||||
{
|
||||
fp=fopen(geom_file_name.c_str(),"wb"); // open
|
||||
strcpy(buffer,"C Binary");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
if (outputType_ == GNUPLOT) text.open(geom_file_text.c_str(),ios_base::out);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp=fopen(geom_file_name.c_str(),"ab"); // append
|
||||
if (outputType_ == GNUPLOT) text.open(geom_file_text.c_str(),ios_base::app);
|
||||
}
|
||||
if (fp == NULL) {
|
||||
throw ATC_Error(0,"can not create Ensight geometry file");
|
||||
}
|
||||
|
||||
// write preamble
|
||||
strcpy(buffer,"BEGIN TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"Ensight geometry file");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"description");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"node id assign");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"element id assign");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// per part
|
||||
int part_number=1;
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = part_coordinates.begin(); iter != part_coordinates.end(); iter++)
|
||||
{
|
||||
string part_name = iter->first;
|
||||
DenseMatrix<double> coordinates = *(iter->second);
|
||||
strcpy(buffer,"part");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
fwrite(&part_number,sizeof(int),1,fp);
|
||||
strcpy(buffer,part_name.c_str());
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// write coordinates
|
||||
strcpy(buffer,"coordinates");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
number_of_nodes_ = coordinates.nCols();
|
||||
fwrite(&number_of_nodes_,sizeof(int),1,fp);
|
||||
int number_of_spatial_dimensions = coordinates.nRows();
|
||||
if (number_of_spatial_dimensions != 3)
|
||||
{
|
||||
throw ATC_Error(0,"Ensight writer needs a 3D geometry");
|
||||
}
|
||||
for (int i=0; i<number_of_spatial_dimensions; i++)
|
||||
{
|
||||
for (int j=0; j<number_of_nodes_; j++)
|
||||
{
|
||||
float x = (float)coordinates(i,j);
|
||||
fwrite(&x,sizeof(float),1,fp);
|
||||
}
|
||||
}
|
||||
|
||||
// write mesh connectivities or point "connectivities"
|
||||
strcpy(buffer,"point");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
int number_of_elements = number_of_nodes_;
|
||||
fwrite(&number_of_elements,sizeof(int),1,fp);
|
||||
int number_of_nodes_per_element = 1;
|
||||
for (int j = 0; j < number_of_elements; ++j)
|
||||
{
|
||||
int inode = j +1; // 1 based numbering
|
||||
fwrite(&inode,sizeof(int),1,fp);
|
||||
}
|
||||
++part_number;
|
||||
}
|
||||
|
||||
strcpy(buffer,"END TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
fclose(fp);
|
||||
|
||||
if (!initialized_) initialized_ = true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/** pack "soln" into data */
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_data(double time, FIELDS *soln, OUTPUT_LIST *data, const int *node_map)
|
||||
{
|
||||
// pack
|
||||
OUTPUT_LIST combined_data;
|
||||
if (soln)
|
||||
{
|
||||
FIELDS::iterator iter;
|
||||
for (iter = soln->begin(); iter != soln->end(); iter++)
|
||||
{
|
||||
FieldName field_index = iter->first;
|
||||
MATRIX* field_data = &(iter->second);
|
||||
string field_name = field_to_string(field_index);
|
||||
combined_data[field_name] = field_data;
|
||||
}
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++)
|
||||
{
|
||||
string field_name = iter->first;
|
||||
MATRIX* field_data = iter->second;
|
||||
combined_data[field_name] = field_data;
|
||||
}
|
||||
}
|
||||
write_data(time, &(combined_data), node_map);
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/** write (ensight gold format "C" binary) data */
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_data(double time, OUTPUT_LIST *data, const int *node_map)
|
||||
{
|
||||
if (! initialized_) throw ATC_Error(0,"must write geometry before data");
|
||||
|
||||
// write data
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++)
|
||||
{
|
||||
string field_name = iter->first;
|
||||
const MATRIX* field_data = iter->second;
|
||||
write_data(field_name, field_data, node_map);
|
||||
}
|
||||
|
||||
// write dictionary
|
||||
write_dictionary(time,data);
|
||||
|
||||
// write text dump
|
||||
if (outputType_ == GNUPLOT) {
|
||||
write_text(data);
|
||||
if (firstStep_ && node_map) {
|
||||
string map_file_text = outputPrefix_ + ".MAP";
|
||||
ofstream text;
|
||||
text.open(map_file_text.c_str(),ios_base::out);
|
||||
for (int i=0; i< number_of_nodes_ ; i++) {
|
||||
text << node_map[i] << "\n";
|
||||
}
|
||||
text.close();
|
||||
}
|
||||
}
|
||||
|
||||
// global variables
|
||||
if (! globalData_.empty()) write_globals();
|
||||
|
||||
if (firstStep_) firstStep_ = false;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/** write (ensight gold format "C" binary) data */
|
||||
//-----------------------------------------------------------------------------
|
||||
void OutputManager::write_data(string field_name, const MATRIX *field_data, const int *node_map)
|
||||
{
|
||||
int ndof = field_data->nCols();
|
||||
int col_start = 0;
|
||||
int col_end = ndof;
|
||||
string filenames[kFileNameSize];
|
||||
int nfiles = 1;
|
||||
filenames[0] = outputPrefix_ + "." + field_name;
|
||||
int type = data_type(ndof);
|
||||
if (use_component_names(type)){
|
||||
nfiles = ndof;
|
||||
string* component_names = get_component_names(type);
|
||||
for (int ifile = 0; ifile < nfiles; ++ifile)
|
||||
{
|
||||
string comp_name = field_name + component_names[ifile];
|
||||
filenames[ifile] = outputPrefix_ + "." + comp_name;
|
||||
}
|
||||
}
|
||||
|
||||
for (int ifile = 0; ifile < nfiles; ++ifile)
|
||||
{
|
||||
// for vector/tensor to components
|
||||
if ( nfiles > 1 )
|
||||
{
|
||||
col_start = ifile;
|
||||
col_end = ifile+1;
|
||||
}
|
||||
|
||||
// open or append data file
|
||||
string data_file_name = filenames[ifile];
|
||||
FILE * fp;
|
||||
if ( outputTimes_.size() == 0 ) {
|
||||
fp=fopen(data_file_name.c_str(),"wb"); // open
|
||||
}
|
||||
else {
|
||||
fp=fopen(data_file_name.c_str(),"ab"); // append
|
||||
}
|
||||
if (fp == NULL) {
|
||||
throw ATC_Error(0,"can not create Ensight data file: "+data_file_name);
|
||||
}
|
||||
|
||||
// write data
|
||||
char buffer[80];
|
||||
strcpy(buffer,"BEGIN TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
strcpy(buffer,"field name"); // NOTE could be the field name
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
|
||||
// per part
|
||||
strcpy(buffer,"part");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
int part_number = 1;
|
||||
fwrite(&part_number,sizeof(int),1,fp);
|
||||
strcpy(buffer,"coordinates");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
if (node_map)
|
||||
{
|
||||
for (int j = col_start; j < col_end; ++j)
|
||||
{
|
||||
for (int i = 0; i < number_of_nodes_; ++i)
|
||||
{
|
||||
int inode = node_map[i];
|
||||
float x = (float) (*field_data)(inode,j);
|
||||
fwrite(&x,sizeof(float),1,fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = col_start; j < col_end; ++j)
|
||||
{
|
||||
for (int i = 0; i < field_data->nRows(); ++i)
|
||||
{
|
||||
float x = (float) (*field_data)(i,j);
|
||||
fwrite(&x,sizeof(float),1,fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end per part
|
||||
|
||||
strcpy(buffer,"END TIME STEP");
|
||||
fwrite(buffer,sizeof(char),80,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputManager::write_text(OUTPUT_LIST *data)
|
||||
{
|
||||
string data_file_text = outputPrefix_ + ".DATA";
|
||||
ofstream text;
|
||||
if (firstStep_) text.open(data_file_text.c_str(),ios_base::out);
|
||||
else text.open(data_file_text.c_str(),ios_base::app);
|
||||
|
||||
// write data label header
|
||||
if (firstStep_)
|
||||
{
|
||||
text.width(6); text << "# index:1" << " "; // give an ordinate for gnuplot
|
||||
text.width(10); text << " step:2" << " ";
|
||||
int k =3;
|
||||
if (data)
|
||||
{
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++)
|
||||
{
|
||||
int ncols = iter->second->nCols();
|
||||
string field_name = iter->first;
|
||||
if (ncols == 1) {
|
||||
string str; stringstream out; out << ":" << k; str = out.str();
|
||||
field_name.append(str);
|
||||
text.width(kFieldWidth); text << field_name << " ";
|
||||
k++;
|
||||
}
|
||||
else {
|
||||
for (int i = 1; i <= ncols; i++) {
|
||||
string str; stringstream out; out <<"_"<<i<<":"<<k; str = out.str();
|
||||
string name = field_name;
|
||||
name.append(str);
|
||||
text.width(kFieldWidth); text << name << " ";
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { throw ATC_Error(0," data missing from output");}
|
||||
text << "\n";
|
||||
}
|
||||
text << "# timestep " << outputTimes_.size() << " : "
|
||||
<< outputTimes_[outputTimes_.size()-1] << "\n";
|
||||
|
||||
int nrows = 0;
|
||||
OUTPUT_LIST::iterator iter;
|
||||
iter = data->begin();
|
||||
const MATRIX* field_data = iter->second;
|
||||
nrows = field_data->nRows();
|
||||
|
||||
for (int i = 0; i < nrows; ++i)
|
||||
{
|
||||
text.width(6); text << i << " "; // give an ordinate for gnuplot
|
||||
text.width(10); text << outputTimes_.size() << " ";
|
||||
OUTPUT_LIST::iterator iter;
|
||||
for (iter = data->begin(); iter != data->end(); iter++)
|
||||
{
|
||||
const MATRIX* field_data = iter->second;
|
||||
for (int j = 0; j < field_data->nCols(); ++j)
|
||||
{
|
||||
text.width(kFieldWidth);
|
||||
text << setw(kFieldWidth) << std::scientific << std::setprecision(kFieldPrecison) << (*field_data)(i,j) << " ";
|
||||
}
|
||||
}
|
||||
text <<"\n";
|
||||
}
|
||||
text <<"\n";
|
||||
}
|
||||
|
||||
/** write (ensight gold : ASCII "C" format) dictionary */
|
||||
void OutputManager::write_dictionary(double time, OUTPUT_LIST *data)
|
||||
{
|
||||
// store the time step value
|
||||
outputTimes_.push_back(time);
|
||||
|
||||
// file names
|
||||
string dict_file_name = outputPrefix_ + ".case";
|
||||
string geom_file_name = outputPrefix_ + ".geo";
|
||||
|
||||
// open file
|
||||
FILE * fp;
|
||||
if ((fp=fopen(dict_file_name.c_str(),"w")) == NULL)
|
||||
{
|
||||
throw ATC_Error(0,"can not create Ensight case file");
|
||||
}
|
||||
|
||||
// write file
|
||||
fprintf(fp,"FORMAT\n");
|
||||
fprintf(fp,"type: ensight gold\n");
|
||||
fprintf(fp,"GEOMETRY\n");
|
||||
if ( dataType_ == POINT) {
|
||||
fprintf(fp,"model: 1 1 %s change_coords_only\n", geom_file_name.c_str());
|
||||
} else {
|
||||
fprintf(fp,"model: %s\n", geom_file_name.c_str());
|
||||
}
|
||||
fprintf(fp,"VARIABLE\n");
|
||||
|
||||
// data types
|
||||
if (!data) throw ATC_Error(0,"no data for output");
|
||||
OUTPUT_LIST::iterator iter;
|
||||
int ncols = 0;
|
||||
for (iter = data->begin(); iter != data->end(); iter++) {
|
||||
string field_name = iter->first;
|
||||
string field_file = outputPrefix_ + "." + field_name;
|
||||
const MATRIX* field_data = iter->second;
|
||||
int fieldCols = field_data->nCols();
|
||||
ncols += fieldCols;
|
||||
int type = data_type(fieldCols);
|
||||
if (use_component_names(type)){
|
||||
string* component_names = get_component_names(type);
|
||||
for (int j = 0; j < fieldCols; ++j)
|
||||
{
|
||||
string comp_name = field_name + component_names[j];
|
||||
string comp_file = outputPrefix_ + "." + comp_name;
|
||||
fprintf(fp,"scalar per node: 1 1 %s %s\n",
|
||||
comp_name.c_str(),comp_file.c_str());
|
||||
}
|
||||
}
|
||||
else if (type == VECTOR_OUTPUT) {
|
||||
fprintf(fp,"vector per node: 1 1 %s %s\n",
|
||||
field_name.c_str(),field_file.c_str());
|
||||
}
|
||||
else if (type == SYM_TENSOR_OUTPUT) {
|
||||
fprintf(fp,"tensor symm per node: 1 1 %s %s\n",
|
||||
field_name.c_str(),field_file.c_str());
|
||||
}
|
||||
else if (type == TENSOR_OUTPUT) {
|
||||
fprintf(fp,"tensor asymm per node: 1 1 %s %s\n",
|
||||
field_name.c_str(),field_file.c_str());
|
||||
}
|
||||
else {
|
||||
fprintf(fp,"scalar per node: 1 1 %s %s\n",
|
||||
field_name.c_str(),field_file.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!firstStep_ && ncols != nDataCols_) {
|
||||
throw ATC_Error(0,"number of columns of data has changed: start new output");
|
||||
}
|
||||
nDataCols_ = ncols;
|
||||
|
||||
int nsteps = outputTimes_.size();
|
||||
fprintf(fp,"TIME\n");
|
||||
fprintf(fp,"time set: 1\n");
|
||||
fprintf(fp,"number of steps: %10d\n",nsteps);
|
||||
if ( dataType_ == POINT) {
|
||||
fprintf(fp,"filename start number: 0\n");
|
||||
fprintf(fp,"filename increment: 1\n");
|
||||
}
|
||||
fprintf(fp,"time values:\n");
|
||||
for (int j = 0; j < nsteps; ++j) {
|
||||
double t = outputTimes_[j];
|
||||
fprintf(fp,"%12.5e",t);
|
||||
if ((j+1)%6 == 0) fprintf(fp,"\n");
|
||||
}
|
||||
fprintf(fp,"\n");
|
||||
fprintf(fp,"FILE\n");
|
||||
fprintf(fp,"file set: 1\n");
|
||||
fprintf(fp,"number of steps: %10d\n",nsteps);
|
||||
fclose(fp);
|
||||
};
|
||||
|
||||
} // end ATC namespace
|
||||
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
#ifndef OUTPUT_MANAGER_H
|
||||
#define OUTPUT_MANAGER_H
|
||||
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// NOTE : number of rows to data type:
|
||||
// 1 -> scalar
|
||||
// 3 -> vector x,y,z
|
||||
// NOT 6 -> tensor xx,xy,xz,yy,yz,zz
|
||||
// 6 -> tensor xx,yy,zz,xy,zx,yz
|
||||
// 9 -> tensor xx,xy,xz,yx,yy,yz,zx,zy,zz
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
|
||||
enum OutputType { ENSIGHT=0, GNUPLOT };
|
||||
enum OutputDataType { POINT=0, MESH };
|
||||
enum OutputDataCardinality { SCALAR_OUTPUT=0, VECTOR_OUTPUT, TENSOR_OUTPUT,
|
||||
SYM_TENSOR_OUTPUT, LIST_OUTPUT };
|
||||
enum OutputOption { OUTPUT_VECTOR_COMPONENTS=0, OUTPUT_TENSOR_COMPONENTS};
|
||||
|
||||
class OutputManager{
|
||||
|
||||
public:
|
||||
OutputManager(void);
|
||||
OutputManager(string outputPrefix, OutputType otype = ENSIGHT);
|
||||
~OutputManager(void);
|
||||
|
||||
/** initialize output */
|
||||
void initialize(string outputPrefix, OutputType otype = ENSIGHT);
|
||||
|
||||
/** set output options */
|
||||
void set_option(OutputOption option, bool value);
|
||||
|
||||
// Dump text-based field info to disk for later restart
|
||||
void write_restart_file(string fileName, OUTPUT_LIST *data);
|
||||
|
||||
// Read text-based field file written from write_restart_file
|
||||
void read_restart_file(string fileName, OUTPUT_LIST *data);
|
||||
|
||||
/** write initial/reference geometry
|
||||
default is to write point data,
|
||||
if connectivities are given then mesh data will be output
|
||||
coordinates : num _total_ points/nodes X num spatial dim
|
||||
connectivities : num elements X num nodes per element*/
|
||||
void write_geometry(const MATRIX &coordinates,
|
||||
const Array2D<int> *connectivity=NULL);
|
||||
void write_geometry(OUTPUT_LIST &part_coordinates);
|
||||
|
||||
/** write data from a time step
|
||||
specify node_map to handle periodic soln & data */
|
||||
void write_data(double time, OUTPUT_LIST *data, const int *node_map=NULL);
|
||||
|
||||
void write_data(double time, FIELDS *soln, OUTPUT_LIST *data,
|
||||
const int *node_map=NULL);
|
||||
|
||||
/*
|
||||
void write_data (double time,
|
||||
map<string, map<string, DenseMatrix<double> * > * > parts_data,
|
||||
const int * node_map = NULL);
|
||||
*/
|
||||
/** add a scalar to a text output file */
|
||||
void add_global(const string& name, const double& value) {
|
||||
globalData_[name] = value; }
|
||||
|
||||
/** delete a scalar from the output */
|
||||
void delete_global(const string& name) { globalData_.erase(name); }
|
||||
|
||||
/** reset the stored output scalars */
|
||||
void reset_globals() { globalData_.clear(); writeGlobalsHeader_=true; }
|
||||
|
||||
/** return data type: scalar, vector, tensor, list */
|
||||
int data_type(const DENS_MAT & data) const {
|
||||
return data_type(data.nCols());
|
||||
}
|
||||
int data_type(int cols) const {
|
||||
if (cols == 1) return SCALAR_OUTPUT;
|
||||
else if (cols == 3) return VECTOR_OUTPUT;
|
||||
else if (cols == 6) return SYM_TENSOR_OUTPUT;
|
||||
else if (cols == 9) return TENSOR_OUTPUT;
|
||||
else return LIST_OUTPUT;
|
||||
}
|
||||
bool use_component_names(int type) {
|
||||
if ( (type==LIST_OUTPUT) ||
|
||||
((type==SYM_TENSOR_OUTPUT || type==TENSOR_OUTPUT) && tensorToComponents_)
|
||||
|| (type==VECTOR_OUTPUT && vectorToComponents_) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void write_data(string name, const MATRIX *data, const int *node_map=NULL);
|
||||
void write_text(OUTPUT_LIST *data);
|
||||
void write_dictionary(double time, OUTPUT_LIST *data);
|
||||
void write_globals();
|
||||
|
||||
//* status booleans
|
||||
bool initialized_, firstStep_, firstGlobalsWrite_, writeGlobalsHeader_;
|
||||
|
||||
/** number of columns of data */
|
||||
int nDataCols_;
|
||||
/** number of nodes */
|
||||
int number_of_nodes_; // NOTE it would be nicer if node_map came with a size
|
||||
/** data type */
|
||||
int dataType_;
|
||||
/** base name for output files */
|
||||
string outputPrefix_;
|
||||
/** list of output timesteps */
|
||||
vector<double> outputTimes_;
|
||||
/** output type */
|
||||
int outputType_;
|
||||
/** output tensor as its components */
|
||||
bool tensorToComponents_;
|
||||
/** output vector as its components */
|
||||
bool vectorToComponents_;
|
||||
/** global variables */
|
||||
map<string,double> globalData_;
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -1,224 +0,0 @@
|
|||
/**
|
||||
* @class PhysicsModel
|
||||
* @brief An adaptor for the FE_Engine of the specific weak form of
|
||||
* the continuum PDE for the FE_Engine.
|
||||
* It is assumed that the PDE fits this template:
|
||||
* DENSITY(FIELDS) FIELD_RATE
|
||||
* = DIV FLUX(FIELDS, GRAD_FIELDS) + SOURCE(FIELDS,GRAD_FIELDS)
|
||||
* + PRESCRIBED_SOURCE(X,t) + EXTRINSIC_SOURCE(FIELDS,GRAD_FIELDS)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PHYSICS_MODEL_H
|
||||
#define PHYSICS_MODEL_H
|
||||
|
||||
|
||||
// included headers
|
||||
#include <map>
|
||||
#include "Array2D.h"
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_Error.h"
|
||||
#include "Material.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
#include "StringManip.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ATC_STRING;
|
||||
|
||||
namespace ATC
|
||||
{
|
||||
|
||||
// Forward declarations
|
||||
class ATC_Transfer;
|
||||
|
||||
class PhysicsModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
PhysicsModel(string fileName,
|
||||
ATC_Transfer * atcTransfer)
|
||||
: atcTransfer_(atcTransfer)
|
||||
{
|
||||
parse_material_file(fileName);
|
||||
}
|
||||
|
||||
// destructor
|
||||
virtual ~PhysicsModel()
|
||||
{
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
if (mat) delete mat;
|
||||
}
|
||||
}
|
||||
|
||||
/** parse material file */
|
||||
void parse_material_file(string fileName)
|
||||
{
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
if (mat) delete mat;
|
||||
}
|
||||
fstream fileId(fileName.c_str(), std::ios::in);
|
||||
if (!fileId.is_open()) throw ATC_Error(0,"cannot open material file");
|
||||
vector<string> line;
|
||||
int index = 0;
|
||||
while(fileId.good()) {
|
||||
get_command_line(fileId, line);
|
||||
if (line.size() == 0 || line[0] == "#") continue;
|
||||
if (line[0] == "material") {
|
||||
string tag = line[1];
|
||||
Material * mat = new Material(tag,fileId);
|
||||
materials_.push_back(mat);
|
||||
materialNameToIndexMap_[tag] = index++;
|
||||
}
|
||||
}
|
||||
if (int(materials_.size()) == 0) {
|
||||
throw ATC_Error(0,"No materials were defined"); }
|
||||
cout << " ATC:: " << int(materials_.size()) << " materials defined\n";
|
||||
fileId.close();
|
||||
}
|
||||
|
||||
/** initialize */
|
||||
virtual void initialize(void) = 0;
|
||||
|
||||
// set timescale parameters based on a given lengthscale
|
||||
virtual void set_timescales(const double lengthscale) {};
|
||||
|
||||
/** access number of materials */
|
||||
int get_nMaterials(void) const
|
||||
{
|
||||
return materials_.size();
|
||||
}
|
||||
|
||||
/** access material index from name */
|
||||
int material_index(const string & name) const
|
||||
{
|
||||
string tag = name;
|
||||
to_lower(tag); // this is an artifact of StringManip parsing
|
||||
map<string,int>::const_iterator iter;
|
||||
iter = materialNameToIndexMap_.find(tag);
|
||||
if (iter == materialNameToIndexMap_.end()) {
|
||||
throw ATC_Error(0,"No material named "+name+" found");
|
||||
}
|
||||
int index = iter->second;
|
||||
return index;
|
||||
}
|
||||
|
||||
/** access to parameter values */
|
||||
bool parameter_value(const string& name, double& value,
|
||||
const int imat = 0) const
|
||||
{
|
||||
// search owned parameters
|
||||
value = 0.0;
|
||||
map<string,double>::const_iterator it = parameterValues_.find(name);
|
||||
if (it != parameterValues_.end()) {
|
||||
value = it->second;
|
||||
return true;
|
||||
}
|
||||
// interogate material models
|
||||
bool found = materials_[imat]->get_parameter(name,value);
|
||||
return found;
|
||||
}
|
||||
|
||||
/** return fields ids and length */
|
||||
virtual void get_num_fields(map<FieldName,int> & fieldSizes,
|
||||
Array2D<bool> & fieldMask) const = 0;
|
||||
|
||||
/** is the material model linear */
|
||||
virtual bool is_linear(FieldName name) {
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
bool linear = mat->linear_flux(name)
|
||||
&& mat->linear_source(name)
|
||||
&& mat->constant_density(name);
|
||||
if (! linear) return linear;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** is rhs linear */
|
||||
virtual bool has_linear_rhs(FieldName name) {
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
bool constant = mat->linear_flux(name) && mat->linear_source(name);
|
||||
if (! constant) return constant;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** is mass matrix constant */
|
||||
virtual bool has_constant_mass(FieldName name) {
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
bool constant = mat->constant_density(name);
|
||||
if (! constant) return constant;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** energy or other preserved quantity */
|
||||
virtual void E_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &capacity,
|
||||
const int matIndex = 0) const
|
||||
{
|
||||
throw ATC_Error(0,"E_integrand not implemented for this PhysicsModel");
|
||||
}
|
||||
|
||||
/** heat/momentum/energy/mass capacity used in the LHS mass matrix */
|
||||
virtual void M_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &capacity,
|
||||
const int matIndex = 0) const
|
||||
{
|
||||
throw ATC_Error(0,"M_integrand not implemented for this PhysicsModel");
|
||||
}
|
||||
// flux that is integrated with N as its weight
|
||||
virtual void N_integrand(const Array2D<bool> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &flux,
|
||||
const int matIndex = 0) const
|
||||
{
|
||||
throw ATC_Error(0,"N_integrand not implemented for this PhysicsModel");
|
||||
}
|
||||
|
||||
/** flux that is integrated with Grad N as its weight */
|
||||
virtual void B_integrand(const Array2D<bool> & mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
GRAD_FIELDS &flux,
|
||||
const int matIndex = 0) const
|
||||
{
|
||||
throw ATC_Error(0,"B_integrand not implemented for this PhysicsModel");
|
||||
}
|
||||
|
||||
/** has a integrand for the N weighted integral */
|
||||
virtual bool has_N_integrand() const { return false; }
|
||||
|
||||
/** has a integrand for the B=grad_x N weighted integral */
|
||||
virtual bool has_B_integrand() const { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
/** associated ATC Transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
// parameter values
|
||||
map<string, double> parameterValues_;
|
||||
|
||||
// material models
|
||||
vector<Material *> materials_;
|
||||
map<string,int> materialNameToIndexMap_;
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
#include "ATC_Transfer.h"
|
||||
#include "PhysicsModelThermal.h"
|
||||
#include "Material.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
PhysicsModelThermal::PhysicsModelThermal(string matFileName,
|
||||
ATC_Transfer * atcTransfer)
|
||||
: PhysicsModel(matFileName,atcTransfer)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
PhysicsModelThermal::~PhysicsModelThermal(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// initialize
|
||||
//--------------------------------------------------------------
|
||||
void PhysicsModelThermal::initialize(void)
|
||||
{
|
||||
string list[2] = {"heat_capacity",
|
||||
"heat_flux"};
|
||||
set<string> needs(list,list+2);
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
if (! (mat->check_registry(needs)) ) {
|
||||
throw ATC_Error(0,"material does not provide all interfaces for physics");
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
// compute heat capacity
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelThermal::M_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &capacity,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material* material = materials_[matIndex];
|
||||
for (int n = 0; n < mask.get_length(); n++) {
|
||||
if (mask(n) == TEMPERATURE) {
|
||||
material->heat_capacity(fields, capacity[TEMPERATURE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// compute total energy
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelThermal::E_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &energy,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material* material = materials_[matIndex];
|
||||
for (int n = 0; n < mask.get_length(); n++) {
|
||||
if (mask(n) == TEMPERATURE) {
|
||||
material->thermal_energy(fields, energy[TEMPERATURE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// compute heat flux
|
||||
//--------------------------------------------------------------
|
||||
void PhysicsModelThermal::B_integrand(const Array2D<bool> & mask,
|
||||
const FIELDS & fields,
|
||||
const GRAD_FIELDS & gradFields,
|
||||
GRAD_FIELDS & flux,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material *material = materials_[matIndex];
|
||||
material->heat_flux(fields, gradFields, flux[TEMPERATURE]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#ifndef PHYSICS_MODEL_THERMAL_H
|
||||
#define PHYSICS_MODEL_THERMAL_H
|
||||
|
||||
#include "PhysicsModel.h"
|
||||
|
||||
namespace ATC{
|
||||
|
||||
class PhysicsModelThermal : public PhysicsModel {
|
||||
|
||||
public:
|
||||
|
||||
// constructor (take material parameter/s)
|
||||
PhysicsModelThermal(std::string matFileName,
|
||||
ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
virtual ~PhysicsModelThermal();
|
||||
|
||||
/** checks materials for necessary interfaces */
|
||||
virtual void initialize(void);
|
||||
|
||||
virtual void get_num_fields(map<FieldName,int> & fieldSizes, Array2D<bool> & fieldMask) const
|
||||
{
|
||||
fieldSizes[TEMPERATURE] = 1;
|
||||
fieldMask(TEMPERATURE,FLUX) = true;
|
||||
}
|
||||
|
||||
/** heat capacity */
|
||||
virtual void M_integrand(const Array<FieldName> & mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &capacity,
|
||||
const int matIndex = 0) const;
|
||||
/** energy */
|
||||
virtual void E_integrand(const Array<FieldName> & mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &energy,
|
||||
const int matIndex = 0) const;
|
||||
|
||||
/** this model has a B weighted integrand */
|
||||
virtual bool has_B_integrand() const {return true;};
|
||||
|
||||
/** flux that is integrated with Grad N as its weight */
|
||||
virtual void B_integrand(const Array2D<bool> & mask,
|
||||
const FIELDS & fields,
|
||||
const GRAD_FIELDS & grad_fields,
|
||||
GRAD_FIELDS & flux,
|
||||
const int matIndex = 0) const;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,123 +0,0 @@
|
|||
#include "PhysicsModelTwoTemperature.h"
|
||||
#include "Material.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace ATC {
|
||||
//==============================================================
|
||||
// Class PhysicsModelTwoTemperature
|
||||
//==============================================================
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------------
|
||||
PhysicsModelTwoTemperature::PhysicsModelTwoTemperature(string matFileName,
|
||||
ATC_Transfer * atcTransfer)
|
||||
: PhysicsModel(matFileName,atcTransfer)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
// Destructor
|
||||
//---------------------------------------------------------------------
|
||||
PhysicsModelTwoTemperature::~PhysicsModelTwoTemperature(void)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// intialization
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelTwoTemperature::initialize(void)
|
||||
{
|
||||
string list[5] = {"heat_capacity",
|
||||
"electron_heat_capacity",
|
||||
"heat_flux",
|
||||
"electron_heat_flux",
|
||||
"electron_phonon_exchange"};
|
||||
set<string> needs(list,list+5);
|
||||
vector< Material* >::iterator iter;
|
||||
for (iter = materials_.begin(); iter != materials_.end(); iter++) {
|
||||
Material * mat = *iter;
|
||||
if (! (mat->check_registry(needs)) ) {
|
||||
throw ATC_Error(0,"material " + mat->label() + " does not provide all interfaces for physics");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// compute energy
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelTwoTemperature::E_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &energy,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material* material = materials_[matIndex];
|
||||
for (int n = 0; n < mask.get_length(); n++) {
|
||||
if (mask(n) == TEMPERATURE) {
|
||||
material->thermal_energy(fields, energy[TEMPERATURE]);
|
||||
}
|
||||
else if (mask(n) == ELECTRON_TEMPERATURE) {
|
||||
material->electron_thermal_energy(fields, energy[ELECTRON_TEMPERATURE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// compute heat capacities
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelTwoTemperature::M_integrand(const Array<FieldName> &mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &capacity,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material* material = materials_[matIndex];
|
||||
for (int n = 0; n < mask.get_length(); n++) {
|
||||
if (mask(n) == TEMPERATURE) {
|
||||
material->heat_capacity(fields, capacity[TEMPERATURE]);
|
||||
}
|
||||
else if (mask(n) == ELECTRON_TEMPERATURE) {
|
||||
material->electron_heat_capacity(fields, capacity[ELECTRON_TEMPERATURE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// compute heat fluxes
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelTwoTemperature::B_integrand(const Array2D<bool> & mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
GRAD_FIELDS &flux,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material * material = materials_[matIndex];
|
||||
if (mask(TEMPERATURE,FLUX)) {
|
||||
material->heat_flux(fields, grad_fields, flux[TEMPERATURE]);
|
||||
}
|
||||
if (mask(ELECTRON_TEMPERATURE,FLUX)) {
|
||||
material->electron_heat_flux(fields, grad_fields, flux[ELECTRON_TEMPERATURE]);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// compute exchange fluxes
|
||||
//---------------------------------------------------------------------
|
||||
void PhysicsModelTwoTemperature::N_integrand(const Array2D<bool> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &flux,
|
||||
const int matIndex) const
|
||||
{
|
||||
Material * material = materials_[matIndex];
|
||||
FIELD exchange_flux;
|
||||
material->electron_phonon_exchange(fields, exchange_flux);
|
||||
if (mask(TEMPERATURE,SOURCE)) {
|
||||
flux[TEMPERATURE] = exchange_flux;
|
||||
}
|
||||
if (mask(ELECTRON_TEMPERATURE,SOURCE)) {
|
||||
flux[ELECTRON_TEMPERATURE] = -1.*exchange_flux;
|
||||
}
|
||||
}
|
||||
}// end namespace
|
|
@ -1,71 +0,0 @@
|
|||
#ifndef PHYSICS_MODEL_TWO_TEMPERATURE_H
|
||||
#define PHYSICS_MODEL_TWO_TEMPERATURE_H
|
||||
|
||||
// included headers
|
||||
#include "PhysicsModel.h"
|
||||
|
||||
namespace ATC{
|
||||
|
||||
class PhysicsModelTwoTemperature : public PhysicsModel {
|
||||
|
||||
/** system:
|
||||
\dot T_e = diffusion_e + exchange_e
|
||||
\dot T_p = diffusion_p + exchange_p
|
||||
*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// constructor (take material parameter/s)
|
||||
PhysicsModelTwoTemperature(string matFileName,
|
||||
ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
virtual ~PhysicsModelTwoTemperature();
|
||||
|
||||
/** checks materials for necessary interfaces */
|
||||
virtual void initialize(void);
|
||||
|
||||
virtual void get_num_fields(map<FieldName,int> & fieldSizes,
|
||||
Array2D<bool> & fieldMask) const
|
||||
{
|
||||
fieldSizes[TEMPERATURE] = 1; fieldSizes[ELECTRON_TEMPERATURE] = 1;
|
||||
fieldMask(ELECTRON_TEMPERATURE,FLUX) = true;
|
||||
fieldMask(ELECTRON_TEMPERATURE,SOURCE) = true;
|
||||
}
|
||||
|
||||
/** energy */
|
||||
virtual void E_integrand(const Array<FieldName> & mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &energy,
|
||||
const int matIndex = 0) const;
|
||||
|
||||
/** capacity that used to form the mass matrix */
|
||||
virtual void M_integrand(const Array<FieldName> & mask,
|
||||
const FIELDS &fields,
|
||||
FIELDS &flux,
|
||||
const int matIndex = 0) const;
|
||||
|
||||
/** this model has a B weighted integrand */
|
||||
virtual bool has_B_integrand() const {return true;}
|
||||
|
||||
/** flux that is integrated with Grad N as its weight */
|
||||
virtual void B_integrand(const Array2D<bool> & mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
GRAD_FIELDS &flux,
|
||||
const int matIndex = 0) const;
|
||||
|
||||
/** this model has a N weighted integrand */
|
||||
virtual bool has_N_integrand() const {return true;}
|
||||
|
||||
/** flux that is integrated with N as its weight */
|
||||
virtual void N_integrand(const Array2D<bool> &mask,
|
||||
const FIELDS &fields,
|
||||
const GRAD_FIELDS &grad_fields,
|
||||
FIELDS &flux,
|
||||
const int matIndex = 0) const;
|
||||
};
|
||||
}; // end namespace
|
||||
#endif
|
|
@ -1,442 +0,0 @@
|
|||
#include "PrescribedDataManager.h"
|
||||
#include "FE_Engine.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PrescribedDataManager
|
||||
//-------------------------------------------------------------------------
|
||||
PrescribedDataManager::PrescribedDataManager
|
||||
(FE_Engine * feEngine,
|
||||
const map<FieldName,int> & fieldSize) :
|
||||
feEngine_(feEngine), fieldSizes_(fieldSize)
|
||||
{
|
||||
// construct & initialize internal data
|
||||
nNodes_ = feEngine_->get_nNodes();
|
||||
nElems_ = feEngine_->get_nElements();
|
||||
map<FieldName,int>::const_iterator field;
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
int thisSize = field->second;
|
||||
// nodal ics & essential bcs
|
||||
ics_[thisField].reset(nNodes_,thisSize);
|
||||
bcs_[thisField].reset(nNodes_,thisSize);
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int idof = 0; idof < thisSize ; ++idof) {
|
||||
ics_[thisField](inode,idof) = NULL;
|
||||
bcs_[thisField](inode,idof) = NULL;
|
||||
}
|
||||
}
|
||||
// element based sources
|
||||
elementSources_[thisField].reset(nElems_,thisSize);
|
||||
for (int ielem = 0; ielem < nElems_ ; ++ielem) {
|
||||
for (int idof = 0; idof < thisSize ; ++idof) {
|
||||
elementSources_[thisField](ielem,idof) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ~PrescribedDataManager
|
||||
//-------------------------------------------------------------------------
|
||||
PrescribedDataManager::~PrescribedDataManager()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// add_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::add_field(FieldName fieldName, int size)
|
||||
{
|
||||
// check to see if field exists
|
||||
if (fieldSizes_.find(fieldName) == fieldSizes_.end()) return;
|
||||
|
||||
// construct & initialize internal data
|
||||
nNodes_ = feEngine_->get_nNodes();
|
||||
nElems_ = feEngine_->get_nElements();
|
||||
|
||||
// nodal ics & essential bcs
|
||||
ics_[fieldName].reset(nNodes_,size);
|
||||
bcs_[fieldName].reset(nNodes_,size);
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int idof = 0; idof < size ; ++idof) {
|
||||
ics_[fieldName](inode,idof) = NULL;
|
||||
bcs_[fieldName](inode,idof) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// element based sources
|
||||
elementSources_[fieldName].reset(nElems_,size);
|
||||
for (int ielem = 0; ielem < nElems_ ; ++ielem) {
|
||||
for (int idof = 0; idof < size ; ++idof) {
|
||||
elementSources_[fieldName](ielem,idof) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// remove_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::remove_field(FieldName fieldName)
|
||||
{
|
||||
// check to see if field exists
|
||||
if (fieldSizes_.find(fieldName) == fieldSizes_.end())
|
||||
return;
|
||||
|
||||
// delete field in maps
|
||||
fieldSizes_.erase(fieldName);
|
||||
ics_.erase(fieldName);
|
||||
bcs_.erase(fieldName);
|
||||
elementSources_.erase(fieldName);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// fix_initial_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::fix_initial_field
|
||||
(const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f)
|
||||
{
|
||||
using std::set;
|
||||
set<int> nodeSet = (feEngine_->get_feMesh())->get_nodeset(nodesetName);
|
||||
set<int>::const_iterator iset;
|
||||
for (iset = nodeSet.begin(); iset != nodeSet.end(); iset++) {
|
||||
int inode = *iset;
|
||||
ics_[thisField](inode,thisIndex) = (XT_Function*) f; // NOTE const cast?
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// fix_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::fix_field
|
||||
(const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f)
|
||||
{
|
||||
using std::set;
|
||||
// fix fields
|
||||
set<int> nodeSet = (feEngine_->get_feMesh())->get_nodeset(nodesetName);
|
||||
set<int>::const_iterator iset;
|
||||
for (iset = nodeSet.begin(); iset != nodeSet.end(); iset++) {
|
||||
int inode = *iset;
|
||||
bcs_[thisField](inode,thisIndex) = (XT_Function*) f;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// unfix_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::unfix_field
|
||||
(const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex)
|
||||
{
|
||||
using std::set;
|
||||
set<int> nodeSet = (feEngine_->get_feMesh())->get_nodeset(nodesetName);
|
||||
set<int>::const_iterator iset;
|
||||
for (iset = nodeSet.begin(); iset != nodeSet.end(); iset++) {
|
||||
int inode = *iset;
|
||||
bcs_[thisField](inode,thisIndex) = NULL;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// fix_flux
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::fix_flux
|
||||
(const string facesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f)
|
||||
{
|
||||
const set< pair <int,int> > * fset
|
||||
= & ( (feEngine_->get_feMesh())->get_faceset(facesetName));
|
||||
set< pair<int,int> >::const_iterator iset;
|
||||
for (iset = fset->begin(); iset != fset->end(); iset++) {
|
||||
pair<int,int> face = *iset;
|
||||
// allocate, if necessary
|
||||
Array < XT_Function * > & dof = faceSources_[thisField][face];
|
||||
if (dof.get_length() == 0) {
|
||||
int ndof = (fieldSizes_.find(thisField))->second;
|
||||
dof.reset(ndof);
|
||||
for(int i = 0; i < ndof; i++) dof(i) = NULL;
|
||||
}
|
||||
dof(thisIndex) = (XT_Function*) f;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// unfix_flux
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::unfix_flux
|
||||
(const string facesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex)
|
||||
{
|
||||
const set< pair <int,int> > * fset
|
||||
= & ( (feEngine_->get_feMesh())->get_faceset(facesetName));
|
||||
set< pair<int,int> >::const_iterator iset;
|
||||
for (iset = fset->begin(); iset != fset->end(); iset++) {
|
||||
pair<int,int> face = *iset;
|
||||
Array < XT_Function * > & dof = faceSources_[thisField][face];
|
||||
dof(thisIndex) = NULL;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// fix_source
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::fix_source
|
||||
(const string elemsetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function *f)
|
||||
{
|
||||
using std::set;
|
||||
set<int> elemSet = (feEngine_->get_feMesh())->get_elementset(elemsetName);
|
||||
set<int>::const_iterator iset;
|
||||
for (iset = elemSet.begin(); iset != elemSet.end(); iset++) {
|
||||
int ielem = *iset;
|
||||
// fix source
|
||||
elementSources_[thisField](ielem,thisIndex) = (XT_Function*) f;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// unfix_source
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::unfix_source
|
||||
(const string elemsetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex)
|
||||
{
|
||||
using std::set;
|
||||
set<int> elemSet = (feEngine_->get_feMesh())->get_elementset(elemsetName);
|
||||
set<int>::const_iterator iset;
|
||||
for (iset = elemSet.begin(); iset != elemSet.end(); iset++) {
|
||||
int ielem = *iset;
|
||||
elementSources_[thisField](ielem,thisIndex) = NULL;
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// set_initial_conditions
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::set_initial_conditions(const double t,
|
||||
FIELDS &fields,
|
||||
FIELDS &dot_fields,
|
||||
FIELDS &ddot_fields,
|
||||
FIELDS &dddot_fields)
|
||||
{
|
||||
map<FieldName,int>::const_iterator field;
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
int thisSize = field->second;
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
XT_Function *f = ics_[thisField](inode,thisIndex);
|
||||
if (!f) f = bcs_[thisField](inode,thisIndex);
|
||||
if (f)
|
||||
{
|
||||
DENS_VEC coords(3);
|
||||
coords = (feEngine_->get_feMesh())->nodal_coordinates(inode);
|
||||
double *x = coords.get_ptr();
|
||||
fields [thisField](inode,thisIndex) = f->f(x,t);
|
||||
dot_fields [thisField](inode,thisIndex) = f->dfdt(x,t);
|
||||
ddot_fields [thisField](inode,thisIndex) = f->ddfdt(x,t);
|
||||
dddot_fields[thisField](inode,thisIndex) = f->dddfdt(x,t);
|
||||
}
|
||||
else throw ATC_Error(0,"all initial conditions have not been defined");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// set_fixed_fields
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::set_fixed_fields(const double t,
|
||||
FIELDS &fields,
|
||||
FIELDS &dot_fields,
|
||||
FIELDS &ddot_fields,
|
||||
FIELDS &dddot_fields)
|
||||
{
|
||||
map<FieldName,int>::const_iterator field;
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
int thisSize = field->second;
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
XT_Function * f = bcs_[thisField](inode,thisIndex);
|
||||
if (f) {
|
||||
DENS_VEC coords(3);
|
||||
coords = (feEngine_->get_feMesh())->nodal_coordinates(inode);
|
||||
double * x = coords.get_ptr();
|
||||
FIELD * myField = & fields[thisField];
|
||||
fields [thisField](inode,thisIndex) = f->f(x,t);
|
||||
dot_fields [thisField](inode,thisIndex) = f->dfdt(x,t);
|
||||
ddot_fields [thisField](inode,thisIndex) = f->ddfdt(x,t);
|
||||
dddot_fields[thisField](inode,thisIndex) = f->dddfdt(x,t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// set_fixed_field
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::set_fixed_field(
|
||||
const double t,
|
||||
const FieldName & fieldName,
|
||||
DENS_MAT & fieldMatrix)
|
||||
{
|
||||
map<FieldName,int>::iterator fieldSizeIter = fieldSizes_.find(fieldName);
|
||||
if (fieldSizeIter == fieldSizes_.end()) {
|
||||
throw ATC_Error(0, "Unrecognized FieldName in PrescribedDataManager::set_fixed_field()");
|
||||
}
|
||||
int thisSize = fieldSizeIter->second;
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
XT_Function * f = bcs_[fieldName](inode,thisIndex);
|
||||
if (f) {
|
||||
DENS_VEC coords(3);
|
||||
coords = (feEngine_->get_feMesh())->nodal_coordinates(inode);
|
||||
fieldMatrix(inode,thisIndex) = f->f(coords.get_ptr(),t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// set_fixed_dfield
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::set_fixed_dfield(
|
||||
const double t,
|
||||
const FieldName & fieldName,
|
||||
DENS_MAT & dfieldMatrix)
|
||||
{
|
||||
map<FieldName,int>::iterator fieldSizeIter = fieldSizes_.find(fieldName);
|
||||
if (fieldSizeIter == fieldSizes_.end()) {
|
||||
throw ATC_Error(0, "Unrecognized FieldName in PrescribedDataManager::set_fixed_dfield()");
|
||||
}
|
||||
int thisSize = fieldSizeIter->second;
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
XT_Function * f = bcs_[fieldName](inode,thisIndex);
|
||||
if (f) {
|
||||
DENS_VEC coords(3);
|
||||
coords = (feEngine_->get_feMesh())->nodal_coordinates(inode);
|
||||
dfieldMatrix(inode,thisIndex) = f->dfdt(coords.get_ptr(),t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// set_sources
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::set_sources
|
||||
(double t,
|
||||
FIELDS & sources)
|
||||
{
|
||||
// zero
|
||||
Array<bool> fieldMask(NUM_FIELDS);
|
||||
fieldMask = false;
|
||||
map<FieldName,int>::const_iterator field;
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
fieldMask(thisField) = true;
|
||||
int thisSize = field->second;
|
||||
sources[thisField].reset(nNodes_,thisSize);
|
||||
}
|
||||
// compute boundary fluxes
|
||||
feEngine_->add_fluxes(fieldMask,t,faceSources_,sources);
|
||||
|
||||
// compute internal sources
|
||||
feEngine_->add_sources(fieldMask,t,elementSources_,sources);
|
||||
|
||||
// mask out nodes with essential bcs
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
int thisSize = field->second;
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
XT_Function * f = bcs_[thisField](inode,thisIndex);
|
||||
if (f) {
|
||||
sources[thisField](inode,thisIndex) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// print
|
||||
//-------------------------------------------------------------------------
|
||||
void PrescribedDataManager::print(void)
|
||||
{
|
||||
// print and check consistency
|
||||
enum dataType {FREE=0,FIELD,SOURCE};
|
||||
Array2D < int > bcTypes;
|
||||
Array <int> conn;
|
||||
map<FieldName,int>::const_iterator field;
|
||||
XT_Function * f;
|
||||
for (field = fieldSizes_.begin(); field!=fieldSizes_.end(); field++) {
|
||||
FieldName thisField = field->first;
|
||||
int thisFieldSize = field->second;
|
||||
string fieldName = field_to_string(thisField);
|
||||
int thisSize = field->second;
|
||||
bcTypes.reset(nNodes_,thisSize);
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
f = bcs_[thisField](inode,thisIndex);
|
||||
if (f) { bcTypes(inode,thisIndex) = FIELD; }
|
||||
else { bcTypes(inode,thisIndex) = FREE; }
|
||||
}
|
||||
}
|
||||
// FIXED has higher precidence than SOURCE
|
||||
for (int ielem = 0; ielem < nElems_ ; ++ielem) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
f = elementSources_[thisField](ielem,thisIndex);
|
||||
if (f) {
|
||||
feEngine_->element_connectivity(ielem,conn);
|
||||
for (int i = 0; i < conn.get_length() ; ++i) {
|
||||
int inode = conn(i);
|
||||
if (bcTypes(inode,thisIndex) != FIELD)
|
||||
{ bcTypes(inode,thisIndex) = SOURCE; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
map < pair<int,int>, Array < XT_Function * > > & fset
|
||||
= faceSources_[thisField];
|
||||
map < pair<int,int>, Array < XT_Function * > > ::const_iterator iset;
|
||||
for (iset = fset.begin(); iset != fset.end(); iset++) {
|
||||
pair<int,int> face = iset->first;
|
||||
Array < XT_Function * > fs = iset->second;
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
f = fs(thisIndex);
|
||||
if (f) {
|
||||
feEngine_->face_connectivity(face,conn);
|
||||
for (int i = 0; i < conn.get_length() ; ++i) {
|
||||
int inode = conn(i);
|
||||
if (bcTypes(inode,thisIndex) != FIELD)
|
||||
{ bcTypes(inode,thisIndex) = SOURCE; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int inode = 0; inode < nNodes_ ; ++inode) {
|
||||
for (int thisIndex = 0; thisIndex < thisSize ; ++thisIndex) {
|
||||
cout << "node: " << inode << " " << fieldName;
|
||||
if (thisFieldSize > 1) { cout << " " << thisIndex; }
|
||||
f = ics_[thisField](inode,thisIndex);
|
||||
if (f) { cout << " IC"; }
|
||||
if (bcTypes(inode,thisIndex) == FIELD ) {cout << " FIXED"; }
|
||||
else if (bcTypes(inode,thisIndex) == SOURCE) {cout << " SOURCE"; }
|
||||
cout << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
|
@ -1,157 +0,0 @@
|
|||
#ifndef PRESCRIBED_DATA_MANAGER_H
|
||||
#define PRESCRIBED_DATA_MANAGER_H
|
||||
|
||||
// manager for initial conditions, essential/natural "boundary" conditions
|
||||
// and sources
|
||||
|
||||
// to do:
|
||||
// handle no sources, time-independent sources
|
||||
// prescribed surface sources
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "XT_Function.h"
|
||||
#include "PhysicsModel.h"
|
||||
#include "FE_Element.h"
|
||||
#include "Array.h"
|
||||
#include "Array2D.h"
|
||||
#include "FE_Engine.h"
|
||||
|
||||
//clase FE_Engine
|
||||
|
||||
|
||||
namespace ATC {
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
|
||||
class PrescribedDataManager {
|
||||
|
||||
public:
|
||||
|
||||
/** exclusive conditions: free | fixed field | flux or domain source */
|
||||
//enum Bc_Type {FREE=0,FIELD,SOURCE};
|
||||
|
||||
PrescribedDataManager(FE_Engine * feEngine,
|
||||
const map<FieldName,int> & fieldSize);
|
||||
~PrescribedDataManager();
|
||||
|
||||
/** add/remove a field */
|
||||
void add_field(FieldName fieldName, int size);
|
||||
void remove_field(FieldName fieldName);
|
||||
|
||||
/** direct access to ics */
|
||||
map < FieldName, Array2D < XT_Function * > > *
|
||||
get_ics(void) { return & ics_; }
|
||||
const Array2D < XT_Function * > *
|
||||
get_ics(FieldName fieldName) { return & ics_[fieldName]; }
|
||||
/** direct access to bcs */
|
||||
map < FieldName, Array2D < XT_Function * > > *
|
||||
get_bcs(void) { return & bcs_; }
|
||||
const Array2D < XT_Function * > *
|
||||
get_bcs(FieldName fieldName) { return & bcs_[fieldName]; }
|
||||
|
||||
/** query initial state */
|
||||
bool is_initially_fixed(const int node,
|
||||
const FieldName thisField,
|
||||
const int thisIndex=0) const
|
||||
{
|
||||
return ((ics_.find(thisField)->second))(node,thisIndex) ? true : false ;
|
||||
}
|
||||
/** query state */
|
||||
bool is_fixed(const int node,
|
||||
const FieldName thisField,
|
||||
const int thisIndex=0) const
|
||||
{
|
||||
return ((bcs_.find(thisField)->second))(node,thisIndex) ? true : false ;
|
||||
}
|
||||
|
||||
/** set initial field values */
|
||||
void fix_initial_field (const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f);
|
||||
/** un/set field values at fixed nodes */
|
||||
void fix_field (const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f);
|
||||
void unfix_field (const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex);
|
||||
/** un/set fluxes */
|
||||
void fix_flux (const string facesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f);
|
||||
void unfix_flux(const string facesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex);
|
||||
/** un/set sources */
|
||||
void fix_source(const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex,
|
||||
const XT_Function * f);
|
||||
void unfix_source(const string nodesetName,
|
||||
const FieldName thisField,
|
||||
const int thisIndex);
|
||||
/** get initial conditions */
|
||||
void set_initial_conditions(const double time,
|
||||
FIELDS & fields,
|
||||
FIELDS & dot_fields,
|
||||
FIELDS & ddot_fields,
|
||||
FIELDS & dddot_fields);
|
||||
/** get "boundary" conditions on fields */
|
||||
void set_fixed_fields(const double time,
|
||||
FIELDS & fields,
|
||||
FIELDS & dot_fields,
|
||||
FIELDS & ddot_fields,
|
||||
FIELDS & dddot_fields);
|
||||
/** get "boundary" conditions on a single field */
|
||||
void set_fixed_field(const double time,
|
||||
const FieldName & fieldName,
|
||||
DENS_MAT & fieldMatrix);
|
||||
/** get "boundary" conditions on a single time derivative field */
|
||||
void set_fixed_dfield(const double time,
|
||||
const FieldName & fieldName,
|
||||
DENS_MAT & dfieldMatrix);
|
||||
/** get "sources" (flux and sources: divided by leading coef of ODE) */
|
||||
void set_sources(const double time,
|
||||
FIELDS & sources);
|
||||
|
||||
/** debugging status output */
|
||||
void print(void);
|
||||
|
||||
private:
|
||||
/** number of nodes */
|
||||
int nNodes_;
|
||||
|
||||
/** number of elements */
|
||||
int nElems_;
|
||||
|
||||
/** names and sizes of fields */
|
||||
map<FieldName,int> fieldSizes_;
|
||||
|
||||
/** access to all the FE computations */
|
||||
FE_Engine * feEngine_;
|
||||
|
||||
// node numbering & dof numbering : contiguous
|
||||
// fieldname & bc_type : types/enums
|
||||
/** ics : XT_Function * f = ics_[field](inode,idof) */
|
||||
map < FieldName, Array2D < XT_Function * > > ics_;
|
||||
|
||||
/** bcs: essential bcs XT_Function * f = bcs_[field][face](idof) */
|
||||
map < FieldName, Array2D < XT_Function * > > bcs_;
|
||||
|
||||
/** sources : XT_Function * f = faceSources_[field][face](idof) */
|
||||
map < FieldName, map < pair <int, int>, Array < XT_Function * > > >
|
||||
faceSources_;
|
||||
/** sources : XT_Function * f = elementSources_[field](ielem,idof) */
|
||||
map < FieldName, Array2D < XT_Function * > > elementSources_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/** Quadrature : creat Gaussian quadrature lists */
|
||||
#ifndef QUADRATURE_H
|
||||
#define QUADRATURE_H
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const int line_ngauss = 10;
|
||||
static double line_xg[line_ngauss], line_wg[line_ngauss];
|
||||
/** domain of integration is -1 to 1 */
|
||||
static void set_line_quadrature(int ng, double* xg, double* wg)
|
||||
{
|
||||
/** integration schemes : 3, 4, 5, 10 point Gauss */
|
||||
|
||||
if (ng == 3) {
|
||||
xg[0] = 0.0; wg[0] = 8.0/9.0;
|
||||
xg[1] = -sqrt(3.0/5.0); wg[1] = 5.0/9.0;
|
||||
xg[2] = sqrt(3.0/5.0); wg[2] = 5.0/9.0;
|
||||
}
|
||||
else if (ng == 4) {
|
||||
xg[0] = -sqrt((3.0/7.0)-(sqrt(120.0)/35.0)); wg[0] = (1.0/2.0)+(5.0/(3.0*sqrt(120.0)));
|
||||
xg[1] = sqrt((3.0/7.0)-(sqrt(120.0)/35.0)); wg[1] = (1.0/2.0)+(5.0/(3.0*sqrt(120.0)));
|
||||
xg[2] = -sqrt((3.0/7.0)+(sqrt(120.0)/35.0)); wg[2] = (1.0/2.0)-(5.0/(3.0*sqrt(120.0)));
|
||||
xg[3] = sqrt((3.0/7.0)+(sqrt(120.0)/35.0)); wg[3] = (1.0/2.0)-(5.0/(3.0*sqrt(120.0)));
|
||||
}
|
||||
else if (ng == 5) {
|
||||
xg[0] = 0.0; wg[0] = 0.5688888888888889;
|
||||
xg[1] = -sqrt((35.0-sqrt(280.0))/63.0); wg[1] = 0.4786286704993658;
|
||||
xg[2] = sqrt((35.0-sqrt(280.0))/63.0); wg[2] = 0.4786286704993658;
|
||||
xg[3] = -sqrt((35.0+sqrt(280.0))/63.0); wg[3] = 0.2369268850561891;
|
||||
xg[4] = sqrt((35.0+sqrt(280.0))/63.0); wg[4] = 0.2369268850561891;
|
||||
}
|
||||
else if (ng == 10) {
|
||||
xg[0] = -0.14887434; wg[0] = 0.29552422;
|
||||
xg[1] = 0.14887434; wg[1] = 0.29552422;
|
||||
xg[2] = -0.43339539; wg[2] = 0.26926672;
|
||||
xg[3] = 0.43339539; wg[3] = 0.26926672;
|
||||
xg[4] = -0.67940957; wg[4] = 0.21908636;
|
||||
xg[5] = 0.67940957; wg[5] = 0.21908636;
|
||||
xg[6] = -0.86506337; wg[6] = 0.14945135;
|
||||
xg[7] = 0.86506337; wg[7] = 0.14945135;
|
||||
xg[8] = -0.97390653; wg[8] = 0.06667134;
|
||||
xg[9] = 0.97390653; wg[9] = 0.06667134;
|
||||
}
|
||||
else { cout << "Invalid choice of number of Gauss points for Quadrature" << endl; }
|
||||
//else { throw ATC_Error(0,"Invalid choice of number of Gauss points for Quadrature"); }
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
#include "Solver.h"
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
namespace ATC {
|
||||
// Utility functions used by solvers, but not globally accessible.
|
||||
static const double PI_OVER_3 = acos(-1.0)*(1.0/3.0);
|
||||
static bool is_zero(double x)
|
||||
{
|
||||
static double GT_ZERO = 1.0e2*std::numeric_limits<double>::epsilon();
|
||||
static double LT_ZERO = -GT_ZERO;
|
||||
return x>LT_ZERO && x<GT_ZERO;
|
||||
}
|
||||
static double sign(double x)
|
||||
{
|
||||
static double s[] = {-1.0,1.0};
|
||||
return s[x>0];
|
||||
}
|
||||
|
||||
// Linear solver
|
||||
int solve_linear(double c[2], double x0[1])
|
||||
{
|
||||
if (c[1] == 0) return 0; // constant function
|
||||
*x0 = -c[0] / c[1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Quadratic solver
|
||||
int solve_quadratic(double c[3], double x0[2])
|
||||
{
|
||||
if (is_zero(c[2])) return solve_linear(c, x0);
|
||||
const double ainv = 1.0/c[2]; // ax^2 + bx + c = 0
|
||||
const double p = 0.5 * c[1] * ainv; // -b/2a
|
||||
const double q = c[0] * ainv; // c/a
|
||||
double D = p*p-q;
|
||||
|
||||
if (is_zero(D)) { // quadratic has one repeated root
|
||||
x0[0] = -p;
|
||||
return 1;
|
||||
}
|
||||
if (D > 0) { // quadratic has two real roots
|
||||
D = sqrt(D);
|
||||
x0[0] = D - p;
|
||||
x0[1] = -D - p;
|
||||
return 2;
|
||||
}
|
||||
return 0; // quadratic has no real roots
|
||||
}
|
||||
|
||||
// Cubic solver
|
||||
int solve_cubic(double c[4], double x0[3])
|
||||
{
|
||||
int num_roots;
|
||||
if (is_zero(c[3])) return solve_quadratic(c, x0);
|
||||
// normalize to x^3 + Ax^2 + Bx + C = 0
|
||||
const double c3inv = 1.0/c[3];
|
||||
const double A = c[2] * c3inv;
|
||||
const double B = c[1] * c3inv;
|
||||
const double C = c[0] * c3inv;
|
||||
|
||||
// substitute x = t - A/3 so t^3 + pt + q = 0
|
||||
const double A2 = A*A;
|
||||
const double p = (1.0/3.0)*((-1.0/3.0)*A2 + B);
|
||||
const double q = 0.5*((2.0/27.0)*A*A2 - (1.0/3.0)*A*B + C);
|
||||
|
||||
// Cardano's fomula
|
||||
const double p3 = p*p*p;
|
||||
const double D = q*q + p3;
|
||||
if (is_zero(D)) {
|
||||
if (is_zero(q)) { // one triple soln
|
||||
x0[0] = 0.0;
|
||||
num_roots = 1;
|
||||
}
|
||||
else { // one single and one double soln
|
||||
const double u = pow(fabs(q), 1.0/3.0)*sign(q);
|
||||
x0[0] = -2.0*u;
|
||||
x0[1] = u;
|
||||
num_roots = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (D < 0.0) { // three real roots
|
||||
const double phi = 1.0/3.0 * acos(-q/sqrt(-p3));
|
||||
const double t = 2.0 * sqrt(-p);
|
||||
x0[0] = t * cos(phi);
|
||||
x0[1] = -t * cos(phi + PI_OVER_3);
|
||||
x0[2] = -t * cos(phi - PI_OVER_3);
|
||||
num_roots = 3;
|
||||
}
|
||||
else { // one real root
|
||||
const double sqrt_D = sqrt(D);
|
||||
const double u = pow(sqrt_D + fabs(q), 1.0/3.0);
|
||||
if (q > 0) x0[0] = -u + p / u;
|
||||
else x0[0] = u - p / u;
|
||||
num_roots = 1;
|
||||
}
|
||||
}
|
||||
double sub = (1.0/3.0)*A;
|
||||
for (int i=0; i<num_roots; i++) x0[i] -= sub;
|
||||
return num_roots;
|
||||
}
|
||||
|
||||
// Testing code
|
||||
#if 0
|
||||
//* runs test cases for cubic roots for all branches
|
||||
void test()
|
||||
{
|
||||
double x[3];
|
||||
// repeated root
|
||||
double c3r[] = { 4.0, -12.0, 12.0, -4.0};
|
||||
print_soln(solve_cubic(c3r,x), 4, c3r, x);
|
||||
std::cout << "SOLN: x = {1.0}\n";
|
||||
// one real root
|
||||
double c31[] = {1.0, 2.0, 3.0, 4.0};
|
||||
print_soln(solve_cubic(c31,x), 4, c31, x);
|
||||
std::cout << "SOLN: x = {-0.60583}\n";
|
||||
// two real roots
|
||||
double c32[] = {18.0, -3.0, -4.0, 1.0,};
|
||||
print_soln(solve_cubic(c32,x), 4, c32, x);
|
||||
std::cout << "SOLN: x = {-2.0, 3.0}\n";
|
||||
// three real roots
|
||||
double c33[] = {-6.0, 11.0, -6.0, 1.0};
|
||||
print_soln(solve_cubic(c33,x), 4, c33, x);
|
||||
std::cout << "SOLN: x = {3.0, 2.0, 1.0}\n";
|
||||
}
|
||||
|
||||
//* Outputs the solution to the screen.
|
||||
void print_soln(int N, int NC, double *c, double *x0)
|
||||
{
|
||||
std::cout << N << " real root" << (N>1?"s":"") << " of: ";
|
||||
switch (NC) {
|
||||
case 4: std::cout << c[3] << "x^3+";
|
||||
case 3: std::cout << c[2] << "x^2+";
|
||||
case 2: std::cout << c[1] << "x+";
|
||||
case 1: std::cout << c[0];
|
||||
default: std::cout << " are ";
|
||||
}
|
||||
std::cout << "x = {";
|
||||
for (int i=0; i<N; i++) {
|
||||
if (i) std::cout << ", ";
|
||||
std::cout << x0[i];
|
||||
}
|
||||
std::cout << "}\n";
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef SOLVER_H
|
||||
#define SOLVER_H
|
||||
|
||||
namespace ATC {
|
||||
//* Solves a linear system, returns the number of roots found.
|
||||
int solve_linear(double c[2], double x0[1]);
|
||||
//* Solves a quadratic system, returns the number of roots found.
|
||||
int solve_quadratic(double c[3], double x0[2]);
|
||||
//* Solves a cubic system, returns the number of roots found.
|
||||
int solve_cubic(double c[4], double x0[3]);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,930 +0,0 @@
|
|||
#ifndef SPARSEMATRIX_INL_H
|
||||
#define SPARSEMATRIX_INL_H
|
||||
|
||||
template <typename T>
|
||||
TRI_COORD<T>::TRI_COORD(unsigned row, unsigned col) : i(row), j(col) {}
|
||||
template <typename T>
|
||||
TRI_COORD<T>::TRI_COORD(unsigned row, unsigned col, T val, bool add_to)
|
||||
: i(row), j(col), v(val), add(add_to) {}
|
||||
|
||||
// General flat index by value operator (by nth nonzero)
|
||||
template <typename T> inline T SparseMatrix<T>::operator[](INDEX i) const
|
||||
{
|
||||
VICK(i); return _val[i];
|
||||
}
|
||||
|
||||
// General flat index by reference operator (by nth nonzero)
|
||||
template <typename T> inline T& SparseMatrix<T>::operator[](INDEX i)
|
||||
{
|
||||
VICK(i); return _val[i];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SparseMatrix<T>::_zero = T(0);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// triplet comparison operator returns true if x < y
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool triplet_comparision(const TRI_COORD<T> &x, const TRI_COORD<T> &y)
|
||||
{
|
||||
const bool row_less = (x.i) < (y.i);
|
||||
const bool row_equal = (x.i) == (y.i);
|
||||
const bool col_less = (x.j) < (y.j);
|
||||
return (row_less || (row_equal && col_less));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// triplet comparison operator returns true if x == y
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool triplets_equal(const TRI_COORD<T> &x, const TRI_COORD<T> &y)
|
||||
{
|
||||
return x.i==y.i && x.j==y.j;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiply sparse matrix by a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const SparseMatrix<T> &A, const Vector<T>& x)
|
||||
{
|
||||
SparseMatrix<T>::compress(A);
|
||||
GCK(A, x, A.nCols()!=x.size(), "SparseMatrix * Vector")
|
||||
DenseVector<T> y(A.nRows(), true);
|
||||
INDEX i, j;
|
||||
for (i=0; i<A._nRowsCRS; i++)
|
||||
for (j=A._ia[i]; j<A._ia[i+1]; j++)
|
||||
y(i) += A._val[j]*x(A._ja[j]);
|
||||
|
||||
return y;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiply a vector by a sparse matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const Vector<T>& x, const SparseMatrix<T> &A)
|
||||
{
|
||||
return A.transMat(x);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiply sparse matrix by dense matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator*(const SparseMatrix<T> &A, const Matrix<T>& D)
|
||||
{
|
||||
GCK(A, D, A.nCols()!=D.nRows(),"SparseMatrix * DenseMatrix")
|
||||
DenseMatrix<T> C(A.nRows(), D.nCols(), true); // initialized to zero
|
||||
|
||||
const INDEX J = D.nCols();
|
||||
|
||||
INDEX i, ik, j, k;
|
||||
for (i=0; i<A._nRowsCRS; i++)
|
||||
for (ik=A._ia[i]; ik<A._ia[i+1]; ik++)
|
||||
for (j=0; j<J; j++)
|
||||
C(i, j) += A._val[ik]*D(A._ja[ik],j); // C(i,j) = S(i,k) * D(k, j)
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiply sparse matrix by a diagonal matrix - scales each column
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T> operator*(const SparseMatrix<T> &A, const DiagonalMatrix<T>& D)
|
||||
{
|
||||
GCK(A, D, A.nCols()!=D.nRows(),"SparseMatrix * DiagonalMatrix")
|
||||
SparseMatrix<T> C(A); // C has same sparcity as A
|
||||
|
||||
// C(i,j) = A(i,k) * D(k, j) * j==k
|
||||
INDEX i, ij, j;
|
||||
for (i=0; i<A._nRowsCRS; i++)
|
||||
for (ij=A._ia[i]; ij<A._ia[i+1]; ij++)
|
||||
C[ij] = A._val[ij]*D(A._ja[ij],A._ja[ij]);
|
||||
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiplies two sparse matrices - assumes their output is sparse
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T> operator*(const SparseMatrix<T> &A, const SparseMatrix<T> &B)
|
||||
{
|
||||
SparseMatrix<T> At(A.transpose());
|
||||
SparseMatrix<T>::compress(B);
|
||||
|
||||
GCK(A, B, A.nCols()!=B.nRows(), "SparseMatrix * SparseMatrix");
|
||||
|
||||
SparseMatrix<T> C(A.nRows(), B.nCols());
|
||||
if (At.empty() || B.empty()) return C;
|
||||
|
||||
INDEX k, ki, kj;
|
||||
INDEX K = std::min(At._nRowsCRS, B._nRowsCRS);
|
||||
for (k=0; k<K; k++) // loop over rows of A or B (smallest)
|
||||
for (ki=At._ia[k]; ki<At._ia[k+1]; ki++) // loop over row nonzeros of A
|
||||
for (kj=B._ia[k]; kj<B._ia[k+1]; kj++) // loop over row nonzeros of B
|
||||
C.add(At._ja[ki], B._ja[kj], At[ki]*B[kj]); // C(i,j) = At(k,i)*B(k, j)
|
||||
|
||||
C.compress();
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// default constructor - creates an empty sparsematrix with specified size
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>::SparseMatrix(INDEX rows, INDEX cols)
|
||||
: _val(NULL), _ia(NULL), _ja(NULL), _size(0), _nRowsCRS(0),
|
||||
_nRows(rows),_nCols(cols) {}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>::SparseMatrix(const SparseMatrix<T>& C)
|
||||
: _val(NULL), _ia(NULL), _ja(NULL)
|
||||
{
|
||||
_copy(C);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy constructor - converts from DenseMatrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>::SparseMatrix(const DenseMatrix<T>& C)
|
||||
: _val(NULL), _ia(NULL), _ja(NULL)
|
||||
{
|
||||
reset(C);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// destructor, cleans up internal storage
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>::~SparseMatrix()
|
||||
{
|
||||
_delete();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns internal storage for CRS
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::_create(INDEX size, INDEX nrows)
|
||||
{
|
||||
_size = size;
|
||||
_nRowsCRS = nrows;
|
||||
// assign memory to hold matrix
|
||||
try
|
||||
{
|
||||
_val = (_size*nrows) ? new T [_size] : NULL;
|
||||
_ia = (_size*nrows) ? new INDEX [_nRowsCRS+1] : NULL;
|
||||
_ja = (_size*nrows) ? new INDEX [_size] : NULL;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
cout << "Could not allocate SparseMatrix of "<< _size << " nonzeros.\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!_ia) return;
|
||||
// automatically handle the ends of rowpointer
|
||||
*_ia = 0; // first non-zero is the zero index
|
||||
_ia[_nRowsCRS] = _size; // last row pointer is the size
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// cleans up internal storage, but retains nRows & nCols
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::_delete()
|
||||
{
|
||||
vector<TRI_COORD<T> >().swap(_tri); // completely deletes _tri
|
||||
delete [] _val;
|
||||
delete [] _ia;
|
||||
delete [] _ja;
|
||||
_size = _nRowsCRS = 0;
|
||||
_val = NULL;
|
||||
_ia = _ja = NULL;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// full memory copy of C into this
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::_copy(const SparseMatrix<T> &C)
|
||||
{
|
||||
compress(C);
|
||||
_delete();
|
||||
_create(C.size(), C._nRowsCRS);
|
||||
if (_size) {
|
||||
std::copy(C._val, C._val+_size, _val);
|
||||
std::copy(C._ja, C._ja+_size, _ja);
|
||||
}
|
||||
if (_nRowsCRS) {
|
||||
std::copy(C._ia, C._ia+_nRowsCRS+1, _ia);
|
||||
}
|
||||
_nCols = C._nCols;
|
||||
_nRows = C._nRows;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
// general sparse matrix assignment
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::_set_equal(const Matrix<T> &r)
|
||||
{
|
||||
this->resize(r.nRows(), r.nCols());
|
||||
const Matrix<T> *ptr_r = &r;
|
||||
|
||||
const SparseMatrix<T> *s_ptr = dynamic_cast<const SparseMatrix<T>*>(ptr_r);
|
||||
if (s_ptr) this->reset(*s_ptr);
|
||||
else if (dynamic_cast<const DiagonalMatrix<T>*>(ptr_r))
|
||||
for (INDEX i=0; i<r.size(); i++) set(i,i,r[i]);
|
||||
else if (dynamic_cast<const DenseMatrix<T>*>(ptr_r)) this->reset(r);
|
||||
else
|
||||
{
|
||||
cout <<"Error in general sparse matrix assignment\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the first row number with a nonzero entry or -1 if no rows
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
int SparseMatrix<T>::_first_nonzero_row_crs() const
|
||||
{
|
||||
if (!_nRowsCRS) return -1;
|
||||
INDEX r;
|
||||
for (r=0; r<_nRowsCRS; r++)
|
||||
if (_ia[r+1]>0) return r;
|
||||
return -1;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// converts T to CRS
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::compress(const SparseMatrix<T> &C)
|
||||
{
|
||||
const_cast<SparseMatrix<T>*>(&C)->compress();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// merges all the _tri triples with CRS storage
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::compress()
|
||||
{
|
||||
if (_tri.empty()) return;
|
||||
|
||||
// sort and find the number of unique triplets
|
||||
const INDEX nUnique = CountUniqueTriplets();
|
||||
|
||||
// max number of rows in new CRS structure
|
||||
const INDEX nRows = std::max((INDEX)_tri.back().i+1, _nRowsCRS);
|
||||
|
||||
// make a new CRS structure
|
||||
INDEX *ia = new INDEX [nRows+1];
|
||||
INDEX *ja = new INDEX [nUnique];
|
||||
T *val = new T [nUnique];
|
||||
|
||||
ia[0] = 0;
|
||||
INDEX i;
|
||||
for (i=1; i<nRows; i++) ia[i]=~0; // ~0 is max(INDEX)
|
||||
ia[nRows] = nUnique;
|
||||
|
||||
INDEX crs_pt, crs_row, tri_ct;
|
||||
|
||||
// get the first CRS and triplet coordinates (if they exist)
|
||||
TRI_COORD<T> nextCRS, nextTRI(_tri[0]), next;
|
||||
int first_row = _first_nonzero_row_crs();
|
||||
if (first_row != -1) nextCRS = TRI_COORD<T>(first_row, _ja[0], _val[0]);
|
||||
|
||||
// merge sorted triplets into a new CRS structure
|
||||
crs_pt = crs_row = tri_ct = 0; // initialize counters
|
||||
for (i=0; i<nUnique; i++)
|
||||
{
|
||||
// is the next non-zero in the new triplet vector
|
||||
if (tri_ct<_tri.size()
|
||||
&& (triplet_comparision(nextTRI, nextCRS) || crs_pt>=_size)) {
|
||||
next = nextTRI;
|
||||
// advance the triplet counter, and skip voided TRIPLET entries
|
||||
do tri_ct++;
|
||||
while ( tri_ct<_tri.size() && !~_tri[tri_ct].j );
|
||||
|
||||
// if not at the end of the vector, set the next triplet
|
||||
if (tri_ct<_tri.size()) nextTRI = _tri[tri_ct];
|
||||
}
|
||||
// is the next nonzero in the old CRS data
|
||||
else if (crs_pt < _size) {
|
||||
next = nextCRS;
|
||||
// advance the CRS counter, skip if it was the last one
|
||||
if (++crs_pt >= _size) continue;
|
||||
crs_row += _ia[crs_row+1]==crs_pt; // did the row advance
|
||||
nextCRS = TRI_COORD<T>(crs_row, _ja[crs_pt], _val[crs_pt]);
|
||||
}
|
||||
else cout << "SparseMatrix - Error in compressing CRS\n";
|
||||
|
||||
// add next to the new CRS structure
|
||||
// is this a new row (is j>0 and is ja[j] == 0)?
|
||||
if (ia[next.i]==~0) ia[next.i] = i;
|
||||
ja[i] = next.j;
|
||||
val[i] = next.v;
|
||||
}
|
||||
// sweep backwards through row pointers and check for skipped rows
|
||||
for (i=nRows-1; i>0; i--) ia[i] = (ia[i]==~0) ? ia[i+1] : ia[i];
|
||||
_delete();
|
||||
_val = val;
|
||||
_ia = ia;
|
||||
_ja = ja;
|
||||
_size = nUnique;
|
||||
_nRowsCRS = nRows;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts the triplets, condenses duplicates, and returns the # of unique values
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX SparseMatrix<T>::CountUniqueTriplets()
|
||||
{
|
||||
std::sort(_tri.begin(), _tri.end(), triplet_comparision<T>);
|
||||
INDEX i, nUnique=1 + _size;
|
||||
// count unique entries
|
||||
for (i=_tri.size()-1; i>0; i--) { // for all new triplets
|
||||
if (triplets_equal(_tri[i-1], _tri[i])) { // previous has same index?
|
||||
if (_tri[i].add) _tri[i-1].v += _tri[i].v; // add to previous
|
||||
else _tri[i-1].v = _tri[i].v; // replace previous
|
||||
_tri[i].j = ~0; // void this entry's col
|
||||
}
|
||||
else nUnique++;
|
||||
}
|
||||
return nUnique;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Index by copy operator - return zero if not found
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T SparseMatrix<T>::operator()(INDEX i, INDEX j) const
|
||||
{
|
||||
MICK(i,j); // Matrix Index ChecKing
|
||||
compress(*this);
|
||||
if (i>=_nRowsCRS || _ia[i+1]==_ia[i]) return 0.0;
|
||||
unsigned f = std::lower_bound(_ja+_ia[i], _ja+_ia[i+1]-1, j) - _ja;
|
||||
if (f>=_ia[i] && f<_ia[i+1] && _ja[f] == j) return _val[f];
|
||||
return 0.0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Index by reference operator - add to _tri if not found
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T& SparseMatrix<T>::operator()(INDEX i, INDEX j)
|
||||
{
|
||||
compress(*this);
|
||||
MICK(i,j); // Matrix Index ChecKing
|
||||
if (i < _nRowsCRS && _ia[i+1]>_ia[i]) {
|
||||
unsigned f = std::lower_bound(_ja+_ia[i], _ja+_ia[i+1]-1, j) - _ja;
|
||||
if (f>=_ia[i] && f<_ia[i+1] && _ja[f] == j) return _val[f];
|
||||
}
|
||||
// NEVER use index operator as LHS to modify values not already in the
|
||||
// sparcity pattern - the crude check below will only catch this on the
|
||||
// second infraction.
|
||||
if (_zero != T(0)) cout << "Use add or set for SparseMatrix\n";
|
||||
return _zero;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets (i,j) to value
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::set(INDEX i, INDEX j, T v)
|
||||
{
|
||||
MICK(i,j); // Matrix Index ChecKing
|
||||
if (i < _nRowsCRS)
|
||||
{
|
||||
const int loc = Utility::SearchSorted(_ja, j, _ia[i], _ia[i+1]);
|
||||
if (loc >=0 )
|
||||
{
|
||||
_val[loc] = v;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_tri.push_back(TRI_COORD<T>(i,j,v,false));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds (i,j) to value
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::add(INDEX i, INDEX j, T v)
|
||||
{
|
||||
MICK(i,j); // Matrix Index ChecKing
|
||||
if (i < _nRowsCRS)
|
||||
{
|
||||
const int loc = Utility::SearchSorted(_ja, j, _ia[i], _ia[i+1]);
|
||||
if (loc >=0 )
|
||||
{
|
||||
_val[loc] += v;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_tri.push_back(TRI_COORD<T>(i,j,v,true));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns a triplet value of the ith nonzero
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
TRIPLET<T> SparseMatrix<T>::get_triplet(INDEX i) const
|
||||
{
|
||||
compress(*this);
|
||||
if (i >= _ia[_nRowsCRS]) {
|
||||
gerror("ERROR: tried indexing triplet of sparse matrix beyond range");
|
||||
}
|
||||
|
||||
INDEX row(std::lower_bound(_ia, _ia+_nRowsCRS, i)-_ia);
|
||||
row -= _ia[row] != i;
|
||||
return TRIPLET<T>(row, _ja[i], _val[i]);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// full reset - completely wipes out all SparseMatrix data, zero is ignored
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::reset(INDEX rows, INDEX cols, bool zero)
|
||||
{
|
||||
_delete();
|
||||
_nRows = rows;
|
||||
_nCols = cols;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// resize - changes the _nRows and _nCols without changing anything else
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::resize(INDEX rows, INDEX cols, bool copy)
|
||||
{
|
||||
GCHK(_nRowsCRS>rows, "SparseMatrix::resize CRS rows exceed specified rows");
|
||||
_nRows = rows;
|
||||
_nCols = cols; // a check on this would be expensive
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// get sparsity from DenseMatrix, if TOL < 0, then only zero values are added
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::reset(const DenseMatrix<T>& D, double TOL)
|
||||
{
|
||||
_delete(); // clears all values
|
||||
// if TOL is specified then TOL = TOL^2 * max(abs(D))^2
|
||||
if (TOL > 0.0)
|
||||
{
|
||||
TOL *= D.maxabs();
|
||||
TOL *= TOL;
|
||||
}
|
||||
_nRows = D.nRows();
|
||||
_nCols = D.nCols();
|
||||
for (INDEX i=0; i<D.nRows(); i++)
|
||||
for (INDEX j=0; j<D.nCols(); j++)
|
||||
if (D(i,j)*D(i,j) >= TOL) // if TOL wasn't specified then TOL < 0
|
||||
set(i, j, D(i,j));
|
||||
|
||||
compress();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy - dangerous: ignores rows & columns
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::copy(const T * ptr, INDEX rows, INDEX cols)
|
||||
{
|
||||
cout << "SparseMatrix<T>::copy() has no effect.\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// dense_copy - copy to dense matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::dense_copy(DenseMatrix <T> & D ) const
|
||||
{
|
||||
SparseMatrix<T>::compress(*this);
|
||||
D.reset(nRows(),nCols());
|
||||
for (INDEX i=0; i<_nRowsCRS; i++)
|
||||
for (INDEX j=_ia[i]; j<_ia[i+1]; j++)
|
||||
D(i, _ja[j]) = _val[j];
|
||||
}
|
||||
template<typename T>
|
||||
DenseMatrix <T> SparseMatrix<T>::dense_copy(void) const
|
||||
{
|
||||
DenseMatrix<T> D;
|
||||
dense_copy(D);
|
||||
return D;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns true if the matrix has no non-zero elements
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool SparseMatrix<T>::empty() const
|
||||
{
|
||||
return _size==0 && _tri.empty();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of rows specified by the user
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline INDEX SparseMatrix<T>::nRows() const
|
||||
{
|
||||
return _nRows;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of columns specified by the user
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
inline INDEX SparseMatrix<T>::nCols() const
|
||||
{
|
||||
return _nCols;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of non-zeros in the matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX SparseMatrix<T>::size() const
|
||||
{
|
||||
compress(*this);
|
||||
return _size;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the number of nonzero elements in a row
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
INDEX SparseMatrix<T>::RowSize(INDEX r) const
|
||||
{
|
||||
compress(*this);
|
||||
GCHK(r>=_nRows, "Rowsize: invalid row");
|
||||
if (r >= _nRowsCRS) return 0;
|
||||
return _ia[r+1]-_ia[r];
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns a pointer to the data, causes a compress
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T* SparseMatrix<T>::get_ptr() const
|
||||
{
|
||||
compress(*this);
|
||||
return _val;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns true if (i,j) falls in the user specified range
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool SparseMatrix<T>::in_range(INDEX i, INDEX j) const
|
||||
{
|
||||
return i < nRows() && j < nCols();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns this sparsematrix from another one - full memory copy
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>& SparseMatrix<T>::operator=(const SparseMatrix<T> &C)
|
||||
{
|
||||
_delete();
|
||||
_copy(C);
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// assigns this sparsematrix from another one - full memory copy
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>& SparseMatrix<T>::operator=(const T v)
|
||||
{
|
||||
// set_all_elements only changes _data, so we need a compress
|
||||
compress(*this);
|
||||
return set_all_elements_to(v);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// scales this sparse matrix by a constant
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>& SparseMatrix<T>::operator*=(const T &a)
|
||||
{
|
||||
compress(*this);
|
||||
for (INDEX i=0; i<size(); i++) _val[i] *= a;
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Multiplies this Sparsematrix tranposed times a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> SparseMatrix<T>::transMat(const Vector<T> &x) const
|
||||
{
|
||||
DenseVector<T> y(nCols(), true);
|
||||
GCK(*this, x, nRows()!=x.size(),"operator *: Sparse matrix incompatible with Vector.")
|
||||
|
||||
INDEX i, ij;
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
y(_ja[ij]) += _val[ij]*x(i);
|
||||
return y;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return matrix transpose
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T> SparseMatrix<T>::transpose() const
|
||||
{
|
||||
compress(*this);
|
||||
SparseMatrix<T> At(nCols(), nRows());
|
||||
|
||||
for (INDEX i=0; i<_nRowsCRS; i++)
|
||||
for (INDEX ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
At.set(_ja[ij], i, _val[ij]);
|
||||
compress(At);
|
||||
return At;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Matrix Transpose/DenseMatrix multiply
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> SparseMatrix<T>::transMat(const DenseMatrix<T> &D) const
|
||||
{
|
||||
compress(*this);
|
||||
GCK(*this, D, nRows()!=D.nRows(),"transMat: Sparse matrix incompatible with DenseMatrix.")
|
||||
DenseMatrix<T> C(nCols(), D.nCols(), true); // initialized to zero
|
||||
INDEX j, k, ki;
|
||||
|
||||
for (k=0; k<_nRowsCRS; k++)
|
||||
for (ki=_ia[k]; ki<_ia[k+1]; ki++)
|
||||
for (j=0; j<D.nCols(); j++)
|
||||
C(_ja[ki], j) += _val[ki]*D(k,j); // C(i,j) = S(k,i) * D(k, j)
|
||||
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Matrix Transpose/SparseMatrix multiply - IS THIS REALLY NEEDED??
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseMatrix<T> SparseMatrix<T>::transMat(const SparseMatrix<T> &D) const
|
||||
{
|
||||
compress(*this);
|
||||
GCK(*this, D, nRows()!=D.nRows(),"transMat: Sparse matrix incompatible with DenseMatrix.")
|
||||
DenseMatrix<T> C(nCols(), D.nCols(), true); // initialized to zero
|
||||
|
||||
INDEX k, ki, kj;
|
||||
for (k=0; k<_nRowsCRS; k++)
|
||||
for (kj=D._ia[k]; kj<D._ia[k+1]; kj++)
|
||||
for (ki=_ia[k]; ki<_ia[k+1]; ki++)
|
||||
C(_ja[ki], D._ja[kj]) += _val[ki]*D._val[kj]; // C(i,j) = S(k,i)*D(k,j)
|
||||
|
||||
return C;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiplies each row by the corresponding element in Vector scale
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>& SparseMatrix<T>::row_scale(const Vector<T> &v)
|
||||
{
|
||||
compress(*this);
|
||||
INDEX i,ij;
|
||||
GCK(*this, v, v.size()!=nRows(), "Incompatible Vector length in row_scale.");
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++) _val[ij] *= v[i];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// multiples each column by the corresponding element in Vector scale
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
SparseMatrix<T>& SparseMatrix<T>::col_scale(const Vector<T> &v)
|
||||
{
|
||||
compress(*this);
|
||||
INDEX i,ij;
|
||||
GCK(*this, v, v.size()!=nCols(), "Incompatible Vector length in col_scale.");
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++) _val[ij] *= v[_ja[ij]];
|
||||
return *this;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a vector of the sums of each column
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<T> SparseMatrix<T>::col_sum() const
|
||||
{
|
||||
compress(*this);
|
||||
INDEX i,ij;
|
||||
GCHK(!nRows(), "SparseMatrix::Matrix not initialized in col_sum.")
|
||||
DenseVector<T> csum(nCols());
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++) csum(_ja[ij]) += _val[ij];
|
||||
return(csum);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns a vector with the number of nonzeros in each column
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DenseVector<INDEX> SparseMatrix<T>::column_count() const
|
||||
{
|
||||
compress(*this);
|
||||
INDEX i,j;
|
||||
DenseVector<INDEX> counts(nCols());
|
||||
|
||||
for (i=0; i<_nRowsCRS; i++)
|
||||
for(j=_ia[i]; j<_ia[i+1]; j++) counts(_ja[j])++;
|
||||
return(counts);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes a the nonzeros of a row to a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::get_row(INDEX i, DenseVector<T>& row, DenseVector<INDEX>& indx) const
|
||||
{
|
||||
GCHK(i>=nRows(), "get_row() - invalid row number");
|
||||
row.resize(RowSize(i));
|
||||
indx.resize(row.size());
|
||||
INDEX idx=0, ij;
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
{
|
||||
row(idx) = _val[ij];
|
||||
indx(idx++) = _ja[ij];
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes the product of N'DN
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::
|
||||
WeightedLeastSquares(const SparseMatrix<T> &N, const DiagonalMatrix<T> &D)
|
||||
{
|
||||
compress(N);
|
||||
GCK(N,D,N.nRows()!=D.nRows(),"SparseMatrix::WeightedLeastSquares()");
|
||||
INDEX k, ki, kj;
|
||||
|
||||
resize(N.nCols(), N.nCols()); // set size of this matrix
|
||||
for (k=0; k<_size; k++) _val[k] = 0.0;
|
||||
// compute R(i,j) = N(k,i) D(k,q) N(i,j) = N(k,i)*D(k,k)*N(k,j) (sum on k)
|
||||
for (k=0; k<N._nRowsCRS; k++)
|
||||
for (ki=N._ia[k]; ki<N._ia[k+1]; ki++)
|
||||
for (kj=N._ia[k]; kj<N._ia[k+1]; kj++)
|
||||
add(N._ja[ki],N._ja[kj], D[k]*N[kj]*N[ki]);
|
||||
compress();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return a diagonal matrix containing the diagonal entries of this matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
DiagonalMatrix<T> SparseMatrix<T>::get_diag() const
|
||||
{
|
||||
compress(*this);
|
||||
DiagonalMatrix<T> D(nRows(), true); // initialized to zero
|
||||
INDEX i, ij;
|
||||
for (i=0; i<_nRowsCRS; i++)
|
||||
{
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
{
|
||||
if (_ja[ij]>=i) // have we reached or passed the diagonal?
|
||||
{
|
||||
if (_ja[ij]==i) D[i]=_val[ij]; // this this the diagonal?
|
||||
break; // D[i] is already zero if there is no diagonal
|
||||
}
|
||||
}
|
||||
}
|
||||
return D;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// output function - builds a string with each nonzero triplet value
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
string SparseMatrix<T>::tostring() const
|
||||
{
|
||||
compress(*this);
|
||||
string out;
|
||||
INDEX i, ij;
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
{
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
{
|
||||
if (ij) out += "\n"; // append newline if not first nonzero
|
||||
out += "(" + ATC_STRING::tostring(i) + ", "; // append "(i,"
|
||||
out += ATC_STRING::tostring(_ja[ij]) + ") = "; // append "j) = "
|
||||
out += ATC_STRING::tostring(_val[ij]); // append "value"
|
||||
}
|
||||
}
|
||||
return out; // return the completed string
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the maximum value in the row
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T SparseMatrix<T>::get_row_max(INDEX row) const
|
||||
{
|
||||
compress(*this);
|
||||
if (!RowSize(row)) return (T)0; // if there are no nonzeros in the row
|
||||
INDEX ij;
|
||||
T max = _val[_ia[row]];
|
||||
for(ij=_ia[row]+1; ij<_ia[row+1]; ij++) max = std::max(max,_val[ij]);
|
||||
return max;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the minimum value in the row
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T SparseMatrix<T>::get_row_min(INDEX row) const
|
||||
{
|
||||
compress(*this);
|
||||
if (!RowSize(row)) return (T)0; // if there are no nonzeros in the row
|
||||
INDEX ij;
|
||||
T min = _val[_ia[row]];
|
||||
for(ij=_ia[row]+1; ij<_ia[row+1]; ij++) min = std::min(min,_val[ij]);
|
||||
return min;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// prints a histogram of the values of a row to the screen
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::print_row_histogram(const string &name, INDEX nbins) const
|
||||
{
|
||||
compress(*this);
|
||||
cout << "Begin histogram " << name << "\n";
|
||||
cout << "# rows: " << _nRows << " columns: " << _nCols
|
||||
<< " size: " << _size << "\n";
|
||||
for(INDEX i=0; i<_nRows; i++)
|
||||
{
|
||||
print_row_histogram(i, nbins);
|
||||
cout << "\n";
|
||||
}
|
||||
cout << "End histogram " << name << "\n";
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// prints a histogram of the values of a row to the screen
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::print_row_histogram(INDEX row, INDEX nbins) const
|
||||
{
|
||||
compress(*this);
|
||||
if (!nbins) nbins++;
|
||||
vector<INDEX> counts(nbins, 0);
|
||||
const T min = get_row_min(row);
|
||||
const T max = get_row_max(row);
|
||||
const T range = max-min;
|
||||
const double bin_size = range/double(nbins);
|
||||
if (range<=0.0) counts[nbins-1]=RowSize(row);
|
||||
else
|
||||
{
|
||||
for(INDEX ij=_ia[row]; ij<_ia[row+1]; ij++)
|
||||
{
|
||||
INDEX bin = INDEX((_val[ij]-min)/bin_size);
|
||||
counts[bin-(bin==nbins)]++;
|
||||
}
|
||||
}
|
||||
cout<<showbase<<scientific;
|
||||
cout<<"# Histogram: row "<<row<<" min "<<min<<" max "<<max<<" cnt " <<RowSize(row)<<"\n";
|
||||
T bin_start = min;
|
||||
for(INDEX i=0; i<nbins; i++)
|
||||
{
|
||||
cout << "(" << bin_start << ",";
|
||||
bin_start += bin_size;
|
||||
cout << bin_start << ") " << counts[i] << "\n";
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Outputs a string to a sparse Matlab type
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::matlab(ostream &o, const string &s) const
|
||||
{
|
||||
compress(*this);
|
||||
INDEX i, ij;
|
||||
o << s <<" = sparse(" << nRows() << "," << nCols() << ");\n";
|
||||
o << showbase << scientific;
|
||||
for(i=0; i<_nRowsCRS; i++)
|
||||
for(ij=_ia[i]; ij<_ia[i+1]; ij++)
|
||||
o<<s<<"("<<i+1<<","<<_ja[ij]+1<<")="<<_val[ij]<<";\n";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes the matrix to a binary file (after a compress).
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::binary_write(std::fstream& f) const
|
||||
{
|
||||
compress(*this);
|
||||
f.write((char*)&_size, sizeof(INDEX)); // writes number of nonzeros
|
||||
f.write((char*)&_nRowsCRS, sizeof(INDEX)); // writes number of rows in crs
|
||||
f.write((char*)&_nRows, sizeof(INDEX)); // write matrix rows
|
||||
f.write((char*)&_nCols, sizeof(INDEX)); // write number of columns
|
||||
if (!_size) return;
|
||||
f.write((char*)_val, sizeof(T) *_size);
|
||||
f.write((char*)_ja, sizeof(INDEX)*_size);
|
||||
f.write((char*)_ia, sizeof(INDEX)*(_nRowsCRS+1));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads a SparseMatrix from a binary file. (wipes out any original data)
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::binary_read(std::fstream& f)
|
||||
{
|
||||
_delete();
|
||||
f.read((char*)&_size, sizeof(INDEX));
|
||||
f.read((char*)&_nRowsCRS, sizeof(INDEX));
|
||||
f.read((char*)&_nRows, sizeof(INDEX));
|
||||
f.read((char*)&_nCols, sizeof(INDEX));
|
||||
if (!_size) return;
|
||||
_create(_size,_nRowsCRS);
|
||||
f.read((char*)_val, sizeof(T)*_size);
|
||||
f.read((char*)_ja, sizeof(INDEX)*_size);
|
||||
f.read((char*)_ia, sizeof(INDEX)*(_nRowsCRS+1));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes the sparse matrix to a file in a binary format
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void SparseMatrix<T>::write_restart(FILE *f) const
|
||||
{
|
||||
compress(*this);
|
||||
fwrite(&_size, sizeof(INDEX), 1 ,f); // write number of nonzeros
|
||||
fwrite(&_nRowsCRS, sizeof(INDEX), 1 ,f); // write number of rows
|
||||
fwrite(&_nRows, sizeof(INDEX), 1 ,f); // write number of columns
|
||||
fwrite(&_nCols, sizeof(INDEX), 1 ,f); // write number of columns
|
||||
if (!_size) return;
|
||||
fwrite(_val, sizeof(T), _size ,f);
|
||||
fwrite(_ja, sizeof(T), _size ,f);
|
||||
fwrite(_ia, sizeof(INDEX), _nRowsCRS+1 ,f);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
#ifndef SPARSEMATRIX_H
|
||||
#define SPARSEMATRIX_H
|
||||
#include <exception>
|
||||
#include "MatrixLibrary.h"
|
||||
#include <algorithm>
|
||||
|
||||
/**
|
||||
* @struct TRI_COORD
|
||||
* @brief Triplet SparseMatrix entry
|
||||
*/
|
||||
template <typename T>
|
||||
struct TRI_COORD
|
||||
{
|
||||
TRI_COORD<T>(unsigned row=0, unsigned col=0);
|
||||
TRI_COORD<T>(unsigned row, unsigned col, T val, bool add_to=0);
|
||||
unsigned i, j;
|
||||
T v;
|
||||
bool add;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class SparseMatrix
|
||||
* @brief Stores data in triplet format or CRS format
|
||||
*/
|
||||
template<typename T>
|
||||
class SparseMatrix : public Matrix<T>
|
||||
{
|
||||
//* SparseMatrix-Vector multiplication (S * v)
|
||||
friend DenseVector<T> operator*<T>(const SparseMatrix<T> &A, const Vector<T>& x);
|
||||
//* SparseMatrix-DenseMatrix multiplication (S * F)
|
||||
friend DenseMatrix<T> operator*<T>(const SparseMatrix<T> &A, const Matrix<T>& D);
|
||||
//* SparseMatrix-DiagonalMatrix multiplication (S * D)
|
||||
friend SparseMatrix<T> operator*<T>(const SparseMatrix<T> &A, const DiagonalMatrix<T>& D);
|
||||
//* SparseMatrix-SparseMatrix multiplication (S * S)
|
||||
friend SparseMatrix<T> operator*<T>(const SparseMatrix<T> &A, const SparseMatrix<T> &B);
|
||||
//* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
friend SparseVector<T> operator*<T>(const SparseMatrix<T> &M, const SparseVector<T> &v);
|
||||
//* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
friend SparseVector<T> operator*<T>(const SparseVector<T> &v, const SparseMatrix<T> &M);
|
||||
public:
|
||||
SparseMatrix(INDEX rows=0, INDEX cols=0);
|
||||
SparseMatrix(const SparseMatrix<T>& c);
|
||||
SparseMatrix(const DenseMatrix<T>& c);
|
||||
~SparseMatrix();
|
||||
|
||||
//* General index by value (requires a binary search on the row)
|
||||
T operator()(INDEX i, INDEX j) const;
|
||||
//* General index by reference (requires a binary search on the row)
|
||||
T& operator()(INDEX i, INDEX j);
|
||||
//* General flat index by value operator (by nth nonzero)
|
||||
T operator[](INDEX i) const;
|
||||
//* General flat index by reference operator (by nth nonzero)
|
||||
T& operator[](INDEX i);
|
||||
//* adds a value to index i,j
|
||||
void set(INDEX i, INDEX j, T v);
|
||||
//* sets a value to index i,j
|
||||
void add(INDEX i, INDEX j, T v);
|
||||
//* return a triplet value of the ith nonzero
|
||||
TRIPLET<T> get_triplet(INDEX i) const;
|
||||
|
||||
//* full reset - completely wipes out all SparseMatrix data
|
||||
void reset(INDEX rows=0, INDEX cols=0, bool zero=true);
|
||||
//* only changes the bounds of the matrix, no deletion
|
||||
void resize(INDEX rows=0, INDEX cols=0, bool zero=true);
|
||||
//* reset - from DenseMatrix - this will be SLOW
|
||||
void reset(const DenseMatrix<T>& D, double TOL=-1.0);
|
||||
//* copy data
|
||||
void copy(const T * ptr, INDEX rows=0, INDEX cols=0);
|
||||
|
||||
void dense_copy(DenseMatrix<T>& D) const;
|
||||
DenseMatrix<T> dense_copy(void) const;
|
||||
|
||||
//* returns true if the matrix has no nonzero elements
|
||||
bool empty() const;
|
||||
//* returns the user-specified number of rows
|
||||
INDEX nRows() const;
|
||||
//* returns the user-specified number of cols
|
||||
INDEX nCols() const;
|
||||
//* returns the number of non-zero elements
|
||||
INDEX size() const;
|
||||
//* returns the number of non-zeros in a row
|
||||
INDEX RowSize(INDEX r) const;
|
||||
//* returns a pointer to the nonzero data
|
||||
inline T* get_ptr() const;
|
||||
//* checks if the index i,j falls in the user-specified range
|
||||
bool in_range(INDEX i, INDEX j) const;
|
||||
|
||||
/*
|
||||
* \section assignment operators
|
||||
*/
|
||||
//* copies SparseMatrix R to this
|
||||
SparseMatrix<T>& operator=(const SparseMatrix &R);
|
||||
//* sets all nonzero values to a constant
|
||||
SparseMatrix<T>& operator=(const T v);
|
||||
//* scales all nonzero values by a constant
|
||||
SparseMatrix<T>& operator*=(const T &a);
|
||||
|
||||
/*
|
||||
* \section Multiplication operations
|
||||
*/
|
||||
|
||||
//* S' * F
|
||||
DenseMatrix<T> transMat(const DenseMatrix<T> &D) const;
|
||||
//* S' * S
|
||||
DenseMatrix<T> transMat(const SparseMatrix<T> &S) const;
|
||||
//* S' * v
|
||||
DenseVector<T> transMat(const Vector<T> &x) const;
|
||||
|
||||
SparseMatrix<T> transpose() const;
|
||||
SparseMatrix<T>& row_scale(const Vector<T> &v);
|
||||
SparseMatrix<T>& col_scale(const Vector<T> &v);
|
||||
DenseVector<T> col_sum() const;
|
||||
DenseVector<INDEX> column_count() const;
|
||||
DiagonalMatrix<T> get_diag() const;
|
||||
void get_row(INDEX i, DenseVector<T>& row, DenseVector<INDEX>& indx) const;
|
||||
void WeightedLeastSquares(const SparseMatrix<T> &N, const DiagonalMatrix<T> &D);
|
||||
|
||||
T get_row_max(INDEX row) const;
|
||||
T get_row_min(INDEX row) const;
|
||||
|
||||
/*
|
||||
* \section I/O functions
|
||||
*/
|
||||
//* outputs this SparseMatrix to a formatted string
|
||||
string tostring() const;
|
||||
using Matrix<T>::matlab;
|
||||
//* writes a command to recreate this matrix in matlab to a stream
|
||||
void matlab(ostream &o, const string &name="S") const;
|
||||
//* prints a row histogram for each row
|
||||
void print_row_histogram(const string &name, INDEX nbins = 10) const;
|
||||
//* prints a histogram of the values in a row
|
||||
void print_row_histogram(INDEX row, INDEX nbins) const;
|
||||
//! Writes the matrix to a binary file (after a compress).
|
||||
void binary_write(std::fstream& f) const;
|
||||
//! Reads a SparseMatrix from a binary file. (wipes out any original data)
|
||||
void binary_read(std::fstream& f);
|
||||
//* Dump templated type to disk; operation not safe for all types
|
||||
void write_restart(FILE *f) const;
|
||||
|
||||
/*
|
||||
* \section Utility functions
|
||||
*/
|
||||
//* converts all triplets and merges with CRS
|
||||
void compress();
|
||||
//* converts T to CRS
|
||||
static void compress(const SparseMatrix<T> &C);
|
||||
//* sorts and returns the # of unique triplets
|
||||
INDEX CountUniqueTriplets();
|
||||
|
||||
private:
|
||||
//* creates a CRS structure
|
||||
void _create(INDEX size, INDEX nrows);
|
||||
//* clears all memory and nulls references
|
||||
void _delete();
|
||||
//* copys all data from another SparseMatrix
|
||||
void _copy(const SparseMatrix<T> &C);
|
||||
//* general sparse matrix assignment
|
||||
void _set_equal(const Matrix<T> &r);
|
||||
//* returns the first row with a nonzero in it (from the CRS structure only)
|
||||
int _first_nonzero_row_crs() const;
|
||||
|
||||
/*
|
||||
* \section CRS storage variables
|
||||
*/
|
||||
T * _val; // matrix non-zeros
|
||||
INDEX *_ia, *_ja; // ptrs to rows, column indexes
|
||||
INDEX _size, _nRowsCRS; // # of non-zeros, rows
|
||||
|
||||
//* new (unsorted triplet values - won't intersect CRS values)
|
||||
mutable vector<TRI_COORD<T> > _tri;
|
||||
/*
|
||||
* \section User specified variables
|
||||
*/
|
||||
INDEX _nRows, _nCols;
|
||||
static T _zero;
|
||||
};
|
||||
|
||||
#include "SparseMatrix-inl.h"
|
||||
#endif
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
// SparseVector-inl.h: provides templated functions for SparseVector in
|
||||
// separate header
|
||||
|
||||
template<class T>
|
||||
SparseVector<T> sparse_rand(unsigned n, unsigned fill, int seed=1234)
|
||||
{
|
||||
srand(seed);
|
||||
const double rmax_inv = 1.0/double(RAND_MAX);
|
||||
SparseVector<T> r(n);
|
||||
while (r.size()<fill)
|
||||
r(rand()%r.nRows())=double(::rand()*rmax_inv);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Multiplies a Matrix by a SparseVector (M*v) and returns a DenseVector.
|
||||
template<class T>
|
||||
DenseVector<T> operator*(const Matrix<T> &M, const SparseVector<T> &v)
|
||||
{
|
||||
DenseVector<T> y(M.nRows());
|
||||
STORE::const_iterator it=v.data_.begin();
|
||||
for (; it!=v.data_.end(); it++) {
|
||||
const unsigned j = it->first;
|
||||
const T& vj = it->second;
|
||||
for (unsigned i=0; i<M.nRows(); i++) y(i)+=M(i,j)*vj;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// Multiplies a SparseVector by a Matrix (M'*v) and returns a DenseVector.
|
||||
template<class T>
|
||||
DenseVector<T> operator*(const SparseVector<T> &v, const Matrix<T> &M)
|
||||
{
|
||||
DenseVector<T> y(M.nCols());
|
||||
STORE::const_iterator it=v.data_.begin();
|
||||
for (; it!=v.data_.end(); it++) {
|
||||
const unsigned i = it->first;
|
||||
const T& vi = it->second;
|
||||
for (unsigned j=0; j<M.nCols(); j++) y(j)+=vi*M(i,j);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// Computes the dot product between two SparseVectors of equal length.
|
||||
template<class T>
|
||||
T dot(const SparseVector<T> &a, const SparseVector<T> &b)
|
||||
{
|
||||
double v = 0.0;
|
||||
for (STORE::const_iterator ai=a.data_.begin(); ai!=a.data_.end(); ai++) {
|
||||
STORE::const_iterator bi=b.data_.find(ai->first);
|
||||
if (bi == b.data_.end()) continue;
|
||||
v += ai->second * bi->second;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
// Computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
template<class T>
|
||||
SparseVector<T> operator*(const SparseMatrix<T> &M, const SparseVector<T> &v)
|
||||
{
|
||||
SparseVector<T> y(M.nRows());
|
||||
for (unsigned i=0; i<M.nRows(); i++) {
|
||||
double yi=0.0;
|
||||
for (unsigned ij=M._ia[i]; ij<M._ia[i+1]; ij++) {
|
||||
const unsigned j = M._ja[ij];
|
||||
STORE::const_iterator it = v._data.find(j);
|
||||
if (it == v._data.end()) continue;
|
||||
yi += M._v[ij] * it->second;
|
||||
}
|
||||
if (yi!=0.0) y(i)+=yi;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
template<class T>
|
||||
SparseVector<T> operator*(const SparseVector<T> &v, const SparseMatrix<T> &M)
|
||||
{
|
||||
SparseVector<T> y(M.nCols());
|
||||
for (unsigned i=0; i<M.nRows(); i++) {
|
||||
STORE::const_iterator it = v._data.find(i);
|
||||
if (it == v._data.end()) continue;
|
||||
for (unsigned ij=M._ia[i]; ij<M._ia[i+1]; ij++)
|
||||
y(M._ja[ij]) += it->second * M._v[ij];
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// General constructor - sets the vector length.
|
||||
template<class T>
|
||||
SparseVector<T>::SparseVector(unsigned n) : length_(n){}
|
||||
|
||||
// Outputs the vector to string
|
||||
template<class T>
|
||||
std::string SparseVector<T>::tostring() const
|
||||
{
|
||||
if (size() > nRows()/2) return Vector<T>::tostring();
|
||||
STORE::const_iterator it=data_.begin();
|
||||
std::string str;
|
||||
using ATC_STRING::tostring;
|
||||
for (; it!=data_.end(); it++)
|
||||
str += tostring(it->first)+": "+tostring(it->second)+'\n';
|
||||
return str;
|
||||
}
|
||||
|
||||
// Indexes the ith component of the vector or returns zero if not found.
|
||||
template<class T>
|
||||
T SparseVector<T>::operator()(unsigned i, unsigned j) const
|
||||
{
|
||||
STORE::const_iterator it = data_.find(i);
|
||||
if (it == data_.end()) return 0.0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Indexes the ith component of the vector or returns zero if not found.
|
||||
template<class T>
|
||||
T& SparseVector<T>::operator()(unsigned i, unsigned j)
|
||||
{
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
// Indexes the ith component of the vector or returns zero if not found.
|
||||
template<class T> T SparseVector<T>::operator[](unsigned i) const
|
||||
{
|
||||
return (*this)(i);
|
||||
}
|
||||
|
||||
// Indexes the ith component of the vector or returns zero if not found.
|
||||
template<class T> T& SparseVector<T>::operator[](unsigned i)
|
||||
{
|
||||
return (*this)[i];
|
||||
}
|
||||
|
||||
// Returns the number of nonzeros in the sparse vector.
|
||||
template<class T> inline unsigned SparseVector<T>::size() const
|
||||
{ return data_.size(); }
|
||||
|
||||
// Returns the number of nonzeros in the sparse vector.
|
||||
template<class T> inline unsigned SparseVector<T>::nRows() const
|
||||
{ return length_; }
|
||||
|
||||
// Changes the size of the SparseVector
|
||||
template<class T>
|
||||
void SparseVector<T>::resize(unsigned nRows, unsigned nCols, bool copy)
|
||||
{
|
||||
length_ = nRows;
|
||||
STORE::iterator it;
|
||||
for (it=data_.begin(); it!=data_.end(); it++) {
|
||||
if (it->second >= length_) data_.erase(it);
|
||||
else if (!copy) it->second=T(0);
|
||||
}
|
||||
}
|
||||
// same as resize, but zero rather than copy
|
||||
template<class T>
|
||||
void SparseVector<T>::reset(unsigned nRows, unsigned nCols, bool zero)
|
||||
{
|
||||
resize(nRows, nCols, !zero);
|
||||
}
|
||||
// sets all elements to zero but preserves sparcity
|
||||
template<class T>
|
||||
void SparseVector<T>::zero()
|
||||
{
|
||||
STORE::iterator it;
|
||||
for (it=data_.begin(); it!=data_.end(); it++) it->second=T(0);
|
||||
}
|
||||
|
||||
// TODO
|
||||
template<class T>
|
||||
void SparseVector<T>::copy(const T* ptr, unsigned nRows, unsigned nCols)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// TODO
|
||||
template<class T>
|
||||
void SparseVector<T>::write_restart(FILE *F) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// writes a stream to a matlab script to recreate this variable
|
||||
template<class T>
|
||||
void SparseVector<T>::matlab(ostream &o, const string &s) const
|
||||
{
|
||||
o << s << "=sparse(" << nRows() << ",1);\n";
|
||||
o << showbase << scientific;
|
||||
STORE::const_iterator it;
|
||||
for (it=data_.begin(); it!=data_.end(); it++)
|
||||
o << s << "(" << it->first+1 << ") = " << it->second << ";\n";
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
#ifndef SPARSEVECTOR_H
|
||||
#define SPARSEVECTOR_H
|
||||
#include "MatrixLibrary.h"
|
||||
|
||||
// No C++ templated typedefs, so use a define, gets cleaned up at end,
|
||||
// so don't use outside of this class
|
||||
#define STORE typename std::map<unsigned, T>
|
||||
|
||||
/** SparseVector class - an implimentation of a vector that contains a
|
||||
** majority of zero element, and provides the relevant operations
|
||||
** specified by the base class Vector.
|
||||
**/
|
||||
template<class T>
|
||||
class SparseVector : public Vector<T> {
|
||||
//* Multiplies a Matrix by a SparseVector (M*v) and returns a DenseVector.
|
||||
friend DenseVector<T> operator*<T>(const Matrix<T> &M, const SparseVector<T> &v);
|
||||
//* Multiplies a SparseVector by a Matrix (M'*v) and returns a DenseVector.
|
||||
friend DenseVector<T> operator*<T>(const SparseVector<T> &v, const Matrix<T> &M);
|
||||
//* Computes the dot product between two SparseVectors of equal length.
|
||||
friend T dot<T>(const SparseVector<T> &a, const SparseVector<T> &b);
|
||||
//* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
friend SparseVector<T> operator*<T>(const SparseMatrix<T> &M, const SparseVector<T> &v);
|
||||
//* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v).
|
||||
friend SparseVector<T> operator*<T>(const SparseVector<T> &v, const SparseMatrix<T> &M);
|
||||
public:
|
||||
//* Constructor - sets length of vector (NOT # of nonzeros).
|
||||
SparseVector(unsigned length=0);
|
||||
//* Copies another SparseVector
|
||||
SparseVector(const SparseVector<T> &c);
|
||||
//* Copies a general Vector (avoid if possible, its going to be slow).
|
||||
SparseVector(const Vector<T> &c);
|
||||
|
||||
//* Overrides output to string function to list only nonzeros and indices.
|
||||
std::string tostring() const;
|
||||
//* Indexing operators (w/ const overloading).
|
||||
//@{
|
||||
T operator()(unsigned i, unsigned j=0) const;
|
||||
// NOTE reading a non-const SparseVector will call this and add zero entries.
|
||||
T& operator()(unsigned i, unsigned j=0);
|
||||
T operator[](unsigned i) const;
|
||||
T& operator[](unsigned i);
|
||||
//@}
|
||||
//* assignment operators
|
||||
//@{
|
||||
SparseVector<T>& operator=(SparseVector<T> &c);
|
||||
SparseVector<T>& operator=(Vector<T> &c);
|
||||
//@}
|
||||
//* Return the number of rows in the Vector.
|
||||
unsigned nRows() const;
|
||||
//* Returns the number of columns - always 1.
|
||||
unsigned nCols() const { return 1; }
|
||||
//* Change # of Vector rows Vector and optionally keeps nonzeros (ignores nCols).
|
||||
void resize(unsigned nRows, unsigned nCols=1, bool copy=0);
|
||||
//* Return the number of nonzeros in the Vector.
|
||||
unsigned size() const;
|
||||
//* Changes size of Vector rows and optionally removes nonzeros.
|
||||
void reset (unsigned nRows, unsigned nCols=1, bool zero=0);
|
||||
//* zeros out all elements while preserving sparcity pattern
|
||||
void zero();
|
||||
//* TODO impliment copy (or maybe not necessary)
|
||||
void copy(const T* ptr, unsigned nRows, unsigned nCols=1);
|
||||
//* Writes a restart file (TODO impliment this if needed/wanted).
|
||||
void write_restart(FILE *F) const;
|
||||
|
||||
// output to matlab (is this needed)
|
||||
// using Matrix<T>::matlab;
|
||||
//* Writes a matlab string to a stream that creates this object with a name.
|
||||
void matlab(ostream &o, const string &s="v") const;
|
||||
|
||||
protected:
|
||||
//* Banned operators
|
||||
//@{
|
||||
SparseVector(const Matrix<T> &c);
|
||||
SparseVector<T>& operator=(Matrix<T> &c);
|
||||
T* get_ptr() const {return NULL; }
|
||||
//@}
|
||||
|
||||
STORE data_; //*> sparse data structure
|
||||
unsigned length_; //*> number of rows
|
||||
};
|
||||
|
||||
#include "SparseVector-inl.h"
|
||||
#undef STORE
|
||||
#endif
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
#ifndef STRINGMANIP_H
|
||||
#define STRINGMANIP_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
using std::cout;
|
||||
using std::transform;
|
||||
using std::fstream;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
//* A collection of string convesion/manipulation routines
|
||||
namespace ATC_STRING
|
||||
{
|
||||
//* converts anything that has iostream::<< defined to a string
|
||||
template<typename T>
|
||||
inline string tostring(const T &v, int precision=0)
|
||||
{
|
||||
std::ostringstream out;
|
||||
if (precision) out << std::setprecision(precision);
|
||||
out << v;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
//* convert a string to anything that has iostream::>> defined
|
||||
template<typename T>
|
||||
inline T str2T(const string &s, T v)
|
||||
{
|
||||
std::istringstream in(s);
|
||||
if (!(in >> v)) cout<<"Error: str2T invalid string conversion\n";\
|
||||
return v;
|
||||
}
|
||||
|
||||
//* convert a string to a double
|
||||
inline double str2dbl(const string &s) { return str2T(s, double(0.0)); }
|
||||
|
||||
//* convert a string to an int
|
||||
inline int str2int(const string &s) { return str2T(s, int(0)); }
|
||||
|
||||
//* replaces all characters in a set of characters with a character
|
||||
//* @param str input string
|
||||
//* @param *s pointer to array of characters that will be replaced
|
||||
//* @param r character to replace characters in s[] with
|
||||
static void replace_all_of(string &str, const char *s, const char r)
|
||||
{
|
||||
int found;
|
||||
found = str.find_first_of(s);
|
||||
while (found != string::npos)
|
||||
{
|
||||
str[found] = r;
|
||||
found = str.find_first_of(s, found+1);
|
||||
}
|
||||
}
|
||||
|
||||
//* converts the string to lowercase
|
||||
inline string& to_lower(string &s)
|
||||
{
|
||||
transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(tolower));
|
||||
return s;
|
||||
}
|
||||
|
||||
//* converts the string to uppercase
|
||||
inline string& to_upper(string &s)
|
||||
{
|
||||
transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(toupper));
|
||||
return s;
|
||||
}
|
||||
|
||||
//* removes any whitespace from the beginning or end of string
|
||||
static string& trim(string &s)
|
||||
{
|
||||
if (s.empty()) return s;
|
||||
size_t found = s.find_last_not_of(" \t\n");
|
||||
if (found < s.size()-1) s.erase(found+1);
|
||||
found = s.find_first_not_of(" \t\n");
|
||||
if (found != string::npos) s = s.substr(found);
|
||||
return s;
|
||||
}
|
||||
|
||||
//* splits delimited string into a vector of strings
|
||||
static void split_up_string(const string &s, vector<string> &ss, char del=' ')
|
||||
{
|
||||
ss.clear();
|
||||
size_t begin=0, end=0;
|
||||
while (end != string::npos)
|
||||
{
|
||||
begin = s.find_first_not_of(del, end); // find beginning of fragment
|
||||
end = s.find_first_of(del,begin);
|
||||
if (begin != string::npos) // safe if end is npos-1
|
||||
ss.push_back(s.substr(begin,end-begin));
|
||||
}
|
||||
}
|
||||
|
||||
//* scans a string for a list of commands delimited by ', \t' with # comments
|
||||
//* @param line The input line to be parsed
|
||||
//* @cs A vector of strings parsed from the input line
|
||||
static void get_command_strings(string line, vector<string> &cs)
|
||||
{
|
||||
if (line.find('#') != string::npos) line.erase(line.find("#"));
|
||||
replace_all_of(line, "\t,", ' ');
|
||||
to_lower(trim(line));
|
||||
split_up_string(line, cs);
|
||||
}
|
||||
|
||||
//* reads a single line from a file and splits it into a vector of strings
|
||||
//* returns the number of strings in the vector
|
||||
inline int get_command_line(fstream &fid, vector<string> &cs)
|
||||
{
|
||||
string line;
|
||||
getline(fid, line);
|
||||
get_command_strings(line, cs);
|
||||
return cs.size();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,629 +0,0 @@
|
|||
/** Thermostat : a class for atom-continuum control of energy/temperature */
|
||||
|
||||
#ifndef THERMOSTAT_H
|
||||
#define THERMOSTAT_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "AtomicRegulator.h"
|
||||
|
||||
// other headers
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace ATC {
|
||||
|
||||
/**
|
||||
* @class Thermtostat
|
||||
* @brief Manager class for atom-continuum control of thermal energy
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class Thermostat
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class Thermostat : public AtomicRegulator {
|
||||
|
||||
public:
|
||||
|
||||
/** thermostat types */
|
||||
enum ThermostatType {
|
||||
NONE=0,
|
||||
RESCALE,
|
||||
HOOVER,
|
||||
FLUX
|
||||
};
|
||||
|
||||
// constructor
|
||||
Thermostat(ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
~Thermostat(){};
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize();
|
||||
|
||||
// data access, intended for method objects
|
||||
/** reset the nodal power to a prescribed value */
|
||||
void reset_lambda_power(DENS_MAT & target);
|
||||
/** return the nodal power induced by lambda */
|
||||
DENS_VEC & get_nodal_atomic_lambda_power(){return nodalAtomicLambdaPower_;};
|
||||
/** return value filtered lambda */
|
||||
DENS_VEC & get_filtered_lambda_power(){return lambdaPowerFiltered_;};
|
||||
/** access to thermostat type */
|
||||
ThermostatType get_thermostat_type() const {return thermostatType_;};
|
||||
|
||||
protected:
|
||||
|
||||
/** thermostat type flag */
|
||||
ThermostatType thermostatType_;
|
||||
|
||||
// thermostat data
|
||||
/** lambda power applied to atoms */
|
||||
DENS_VEC nodalAtomicLambdaPower_;
|
||||
/** filtered lambda power */
|
||||
DENS_VEC lambdaPowerFiltered_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
Thermostat();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ThermostatShapeFunction
|
||||
* @brief Base class for implementation of thermostat algorithms using the shape function matrices
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatShapeFunction
|
||||
// base class for all thermostats of general form
|
||||
// of N^T w N lambda = rhs
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatShapeFunction : public RegulatorShapeFunction {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatShapeFunction(Thermostat * thermostat);
|
||||
|
||||
~ThermostatShapeFunction(){};
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights);
|
||||
|
||||
// member data
|
||||
/** pointer to thermostat object for data */
|
||||
Thermostat * thermostat_;
|
||||
/** pointer to lammps atomic velocities */
|
||||
double ** v_;
|
||||
/** MD mass matrix */
|
||||
MATRIX & mdMassMatrix_;
|
||||
/** mass of ATC internal atoms on this processor */
|
||||
DENS_VEC atomicMass_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatShapeFunction();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ThermostatRescale
|
||||
* @brief Enforces constraint on atomic kinetic energy based on FE temperature
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatRescale
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatRescale : public ThermostatShapeFunction {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatRescale(Thermostat * thermostat);
|
||||
|
||||
~ThermostatRescale(){};
|
||||
|
||||
/** applies thermostat to atoms in the post-corrector phase */
|
||||
virtual void apply_post_corrector(double dt);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
/** apply solution to atomic quantities */
|
||||
void apply_to_atoms(double ** atomicVelocity,
|
||||
double dt);
|
||||
|
||||
/** FE temperature field */
|
||||
DENS_MAT & nodalTemperature_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatRescale();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ThermostatGlc
|
||||
* @brief Base class for implementation of thermostat algorithms based on Gaussian least constraints (GLC)
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatGlc
|
||||
// base clas for all thermostats of general form of a
|
||||
// Gaussian least constraint (GLC)
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatGlc : public ThermostatShapeFunction {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatGlc(Thermostat * thermostat);
|
||||
|
||||
~ThermostatGlc(){};
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
|
||||
/** compute force induced by lambda */
|
||||
virtual void compute_lambda_force(double * const * atomicQuantity,
|
||||
DENS_MAT & lambdaForce);
|
||||
|
||||
/** apply forces to atoms */
|
||||
virtual void apply_to_atoms(double ** atomicVelocity,
|
||||
const DENS_MAT & lambdaForce,
|
||||
double dt);
|
||||
|
||||
// member data
|
||||
/** pointer to a time filtering object */
|
||||
TimeFilter * timeFilter_;
|
||||
|
||||
/** power induced by lambda */
|
||||
DENS_VEC & nodalAtomicLambdaPower_;
|
||||
|
||||
/** filtered lambda power */
|
||||
DENS_VEC & lambdaPowerFiltered_;
|
||||
|
||||
/** atomic force induced by lambda */
|
||||
DENS_MAT & lambdaForce_;
|
||||
|
||||
/** bool to determine if node is fixed or not */
|
||||
Array2D<bool> & isFixedNode_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatGlc();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ThermostatPower
|
||||
* @brief Enforces GLC on atomic forces based on FE power
|
||||
* when using fractional step time integration
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatPower
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatPower : public ThermostatGlc {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatPower(Thermostat * thermostat);
|
||||
|
||||
~ThermostatPower();
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
/** applies thermostat to atoms in the predictor phase */
|
||||
virtual void apply_pre_predictor(double dt);
|
||||
|
||||
/** applies thermostat to atoms in the pre-corrector phase */
|
||||
virtual void apply_pre_corrector(double dt);
|
||||
|
||||
/** applies thermostat to atoms in the post-corrector phase */
|
||||
virtual void apply_post_corrector(double dt);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** destroys allocated memory */
|
||||
void destroy();
|
||||
|
||||
/** update the nodal quantities after predictor step */
|
||||
virtual void update_nodal_quantities_predictor(double dt);
|
||||
|
||||
/** compute the change in nodal atomic temperature */
|
||||
virtual void compute_delta_nodal_atomic_temperature(double dt);
|
||||
|
||||
/** update the nodal quantities after pre-corrector step */
|
||||
virtual void update_nodal_quantities_pre_corrector(double dt);
|
||||
|
||||
/** undoes the update the nodal quantities after pre-corrector step */
|
||||
virtual void undo_update_nodal_quantities_pre_corrector(double dt);
|
||||
|
||||
/** update the nodal quantities after post-corrector step */
|
||||
virtual void update_nodal_quantities_post_corrector(double dt);
|
||||
|
||||
/** sets up appropriate rhs for thermostat equations */
|
||||
virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes,
|
||||
double dt);
|
||||
|
||||
/** apply forces to atoms */
|
||||
virtual void apply_to_atoms(double ** atomicVelocity,
|
||||
const DENS_MAT & lambdaForce,
|
||||
double dt);
|
||||
|
||||
/** solves the non-linear equation for lambda iteratively */
|
||||
void iterate_lambda(const MATRIX & rhs,
|
||||
double * const * atomicVelocity,
|
||||
double dt);
|
||||
|
||||
/** set weighting factor for in matrix Nhat^T * weights * Nhat */
|
||||
virtual void set_weights(DIAG_MAT & weights);
|
||||
|
||||
// data
|
||||
/** reference to AtC FE temperature */
|
||||
DENS_MAT & nodalTemperature_;
|
||||
|
||||
/** reference to AtC restricted atomic temperature */
|
||||
DENS_MAT & nodalAtomicTemperature_;
|
||||
|
||||
/** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */
|
||||
DENS_MAT & heatSource_;
|
||||
|
||||
/** reference to weights for Nhat */
|
||||
DIAG_MAT & nodalWeights_;
|
||||
|
||||
/** change in FE temperature over a timestep */
|
||||
DENS_MAT deltaTemperature_;
|
||||
|
||||
/** change in restricted atomic FE temperature over a timestep */
|
||||
DENS_MAT deltaNodalAtomicTemperature_;
|
||||
|
||||
/** FE temperature rate of change */
|
||||
DENS_MAT nodalTemperatureRoc_;
|
||||
|
||||
/** local version of velocity used as predicted final veloctiy */
|
||||
double ** myAtomicVelocity_;
|
||||
|
||||
/** pointer to lammps atomic forces */
|
||||
double ** f_;
|
||||
|
||||
/** number of total atoms on this processor */
|
||||
int nLocalTotal_;
|
||||
|
||||
/** maximum number of iterations used in iterative solve for lambda */
|
||||
int lambdaMaxIterations_;
|
||||
|
||||
/** tolerance used in iterative solve for lambda */
|
||||
double lambdaTolerance_;
|
||||
|
||||
/** coefficient to account for effect of time filtering on rhs terms */
|
||||
double filterCoefficient_;
|
||||
/** reference to ATC unity shape function on ghost atoms */
|
||||
SPAR_MAT & Nstar_;
|
||||
|
||||
/** maps ghost atom and LAMMPS atom ids */
|
||||
Array<int> & ghostToAtom_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatPower();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatHoover
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatHoover : public ThermostatPower {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatHoover(Thermostat * thermostat);
|
||||
|
||||
~ThermostatHoover();
|
||||
|
||||
/** reset number of local atoms, as well as atomic data */
|
||||
virtual void reset_nlocal();
|
||||
|
||||
/** applies thermostat to atoms in the predictor phase */
|
||||
virtual void apply_pre_predictor(double dt);
|
||||
|
||||
/** applies thermostat to atoms in the pre-corrector phase */
|
||||
virtual void apply_pre_corrector(double dt);
|
||||
|
||||
/** applies thermostat to atoms in the post-corrector phase */
|
||||
virtual void apply_post_corrector(double dt);
|
||||
|
||||
protected:
|
||||
|
||||
// methods
|
||||
/** compute boundary flux, requires thermostat input since it is part of the coupling scheme */
|
||||
virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;};
|
||||
|
||||
/** adds Hoover power terms to nodal variables after the predictor phase */
|
||||
void add_to_lambda_power_predictor(double dt);
|
||||
|
||||
/** adds Hoover power terms to nodal variables after the pre-corrector phase */
|
||||
void add_to_lambda_power_pre_corrector(double dt);
|
||||
|
||||
/** adds Hoover power terms to nodal variables after the post-corrector phase */
|
||||
void add_to_lambda_power_post_corrector(double dt);
|
||||
|
||||
/** sets up appropriate rhs for thermostat equations */
|
||||
virtual void set_hoover_rhs(DENS_MAT & rhs_nodes,
|
||||
double dt);
|
||||
|
||||
/** add Hoover contributions to lambda power */
|
||||
void add_to_lambda_power(DENS_MAT & myLambdaForce);
|
||||
|
||||
// data
|
||||
/** force coming from Hoover contribution */
|
||||
DENS_MAT lambdaForceHoover_;
|
||||
|
||||
/** reference to ATC map from global nodes to overlap nodes */
|
||||
Array<int> & nodeToOverlapMap_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatHoover();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatPowerFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatPowerFiltered : public ThermostatPower {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatPowerFiltered(Thermostat * thermostat);
|
||||
|
||||
~ThermostatPowerFiltered(){};
|
||||
|
||||
protected:
|
||||
|
||||
/** update the nodal quantities after predictor step */
|
||||
virtual void update_nodal_quantities_predictor(double dt);
|
||||
|
||||
/** compute the change in nodal atomic temperature */
|
||||
virtual void compute_delta_nodal_atomic_temperature(double dt);
|
||||
|
||||
/** update the nodal quantities after pre-corrector step */
|
||||
virtual void update_nodal_quantities_pre_corrector(double dt);
|
||||
|
||||
/** update the nodal quantities after post-corrector step */
|
||||
virtual void update_nodal_quantities_post_corrector(double dt);
|
||||
|
||||
/** sets up appropriate rhs for thermostat equations */
|
||||
virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes,
|
||||
double dt);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatPowerFiltered();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatPowerVerlet
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatPowerVerlet : public ThermostatGlc {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatPowerVerlet(Thermostat * thermostat);
|
||||
|
||||
~ThermostatPowerVerlet(){};
|
||||
|
||||
/** applies thermostat to atoms in the predictor phase */
|
||||
virtual void apply_pre_predictor(double dt);
|
||||
|
||||
/** applies thermostat to atoms in the pre-corrector phase */
|
||||
virtual void apply_pre_corrector(double dt);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
/** nodal temperature rate of change */
|
||||
DENS_MAT & nodalTemperatureRoc_;
|
||||
|
||||
/** reference to ATC sources coming from prescribed data, AtC coupling, and extrinsic coupling */
|
||||
DENS_MAT & heatSource_;
|
||||
|
||||
/** pointer to lammps atomic forces */
|
||||
double ** f_;
|
||||
|
||||
/** sets up and solves thermostat equations */
|
||||
virtual void compute_thermostat(double dt);
|
||||
|
||||
/** sets up appropriate rhs for thermostat equations */
|
||||
virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes);
|
||||
|
||||
/** computes the nodal FE power applied by the thermostat */
|
||||
virtual void compute_nodal_lambda_power(double dt);
|
||||
|
||||
/** add contributions (if any) to the finite element right-hand side */
|
||||
virtual void add_to_rhs(FIELDS & rhs);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatPowerVerlet();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatHooverVerlet
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatHooverVerlet : public ThermostatPowerVerlet {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatHooverVerlet(Thermostat * thermostat);
|
||||
|
||||
~ThermostatHooverVerlet(){};
|
||||
|
||||
protected:
|
||||
|
||||
/** reference to ATC map from global nodes to overlap nodes */
|
||||
Array<int> & nodeToOverlapMap_;
|
||||
|
||||
/** sets up and solves thermostat equations */
|
||||
virtual void compute_thermostat(double dt);
|
||||
|
||||
/** compute boundary flux, requires thermostat input since it is part of the coupling scheme */
|
||||
virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;};
|
||||
|
||||
/** sets up Hoover component of the thermostat */
|
||||
void set_hoover_rhs(DENS_MAT & rhs_nodes);
|
||||
|
||||
/** add Hoover contributions to lambda power */
|
||||
void add_to_lambda_power(DENS_MAT & myLambdaForce,
|
||||
double dt);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT implement this
|
||||
ThermostatHooverVerlet();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatPowerVerletFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatPowerVerletFiltered : public ThermostatPowerVerlet {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatPowerVerletFiltered(Thermostat * thermostat);
|
||||
|
||||
~ThermostatPowerVerletFiltered(){};
|
||||
|
||||
/** compute boundary flux, requires thermostat input since it is part of the coupling scheme */
|
||||
virtual void compute_boundary_flux(FIELDS & fields);
|
||||
|
||||
/** get data for output */
|
||||
virtual void output(double dt, OUTPUT_LIST & outputData);
|
||||
|
||||
protected:
|
||||
|
||||
/** sets up appropriate rhs for thermostat equations */
|
||||
virtual void set_thermostat_rhs(DENS_MAT & rhs_nodes);
|
||||
|
||||
/** add contributions (if any) to the finite element right-hand side */
|
||||
virtual void add_to_rhs(FIELDS & rhs);
|
||||
|
||||
/** nodal temperature 2nd rate of change (i.e. second time derivative) */
|
||||
DENS_MAT & nodalTemperature2Roc_;
|
||||
|
||||
/** reference to ATC rate of change sources coming from prescribed data, AtC coupling, and extrinsic coupling */
|
||||
DENS_MAT heatSourceRoc_;
|
||||
|
||||
/** references to ATC field rates of changing for inverting the filtered heat sources */
|
||||
FIELDS & fieldsRoc_;
|
||||
|
||||
/** flux rate of changes for inverting filtered fluxes */
|
||||
FIELDS fluxRoc_;
|
||||
|
||||
/** time scale for the time filter */
|
||||
double filterScale_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
ThermostatPowerVerletFiltered();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class ThermostatHooverVerletFiltered
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class ThermostatHooverVerletFiltered : public ThermostatPowerVerletFiltered {
|
||||
|
||||
public:
|
||||
|
||||
ThermostatHooverVerletFiltered(Thermostat * thermostat);
|
||||
|
||||
~ThermostatHooverVerletFiltered(){};
|
||||
|
||||
protected:
|
||||
|
||||
/** reference to ATC map from global nodes to overlap nodes */
|
||||
Array<int> & nodeToOverlapMap_;
|
||||
|
||||
/** sets up and solves thermostat equations */
|
||||
virtual void compute_thermostat(double dt);
|
||||
|
||||
/** compute boundary flux, requires thermostat input since it is part of the coupling scheme */
|
||||
virtual void compute_boundary_flux(FIELDS & fields) {boundaryFlux_[TEMPERATURE] = 0.;};
|
||||
|
||||
/** sets up Hoover component of the thermostat */
|
||||
void set_hoover_rhs(DENS_MAT & rhs_nodes);
|
||||
|
||||
/** add Hoover contributions to lambda power */
|
||||
void add_to_lambda_power(DENS_MAT & myLambdaForce,
|
||||
double dt);
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT implement this
|
||||
ThermostatHooverVerletFiltered();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,345 +0,0 @@
|
|||
// ATC_Transfer headers
|
||||
#include "ATC_Transfer.h"
|
||||
#include "TimeFilter.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterManager
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterManager::TimeFilterManager(ATC_Transfer * atcTransfer) :
|
||||
atcTransfer_(atcTransfer),
|
||||
filterType_(NO_FILTER),
|
||||
filterScale_(0.),
|
||||
useFilter_(false),
|
||||
equilibrateFilter_(false),
|
||||
endEquilibrate_(false),
|
||||
needReset_(true)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// modify
|
||||
// parses input commands
|
||||
//--------------------------------------------------------
|
||||
bool TimeFilterManager::modify(int narg, char ** arg)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
|
||||
// filter scale size
|
||||
/*! \page man_filter_scale fix_modify AtC transfer filter scale
|
||||
\section syntax
|
||||
fix_modify AtC transfer filter scale <scale> \n
|
||||
- scale (real) = characteristic time scale of the filter \n
|
||||
|
||||
\section examples
|
||||
<TT> fix_modify AtC transfer filter scale 10.0 </TT> \n
|
||||
|
||||
\section description
|
||||
Filters the MD dynamics to construct a more appropriate continuous field. Equilibrating first filters the time derivatives without changing the dynamics to provide a better initial condition to the filtered dynamics
|
||||
\section restrictions
|
||||
only for be used with specific transfers:
|
||||
thermal, two_temperature
|
||||
|
||||
\section related
|
||||
\ref man_time_filter
|
||||
|
||||
\section default
|
||||
0.
|
||||
*/
|
||||
if (strcmp(arg[0],"scale")==0) {
|
||||
filterScale_ = atof(arg[1]);
|
||||
if (filterScale_<=0.)
|
||||
throw ATC_Error(0,"Bad filtering time scale");
|
||||
foundMatch = true;
|
||||
}
|
||||
|
||||
// time filtering activation switch
|
||||
/*! \page man_time_filter fix_modify AtC transfer filter
|
||||
\section syntax
|
||||
fix_modify AtC transfer filter <on | off | equilibrate> \n
|
||||
- on | off (keyword) = turns filter on or off\n
|
||||
- equilibrate = runs dynamics without filtering but initializes filtered quantities
|
||||
\section examples
|
||||
<TT> fix_modify atc transfer filter on </TT> \n
|
||||
|
||||
\section description
|
||||
Filters the MD dynamics to construct a more appropriate continuous field. Equilibrating first filters the time derivatives without changing the dynamics to provide a better initial condition to the filtered dynamics
|
||||
|
||||
\section restrictions
|
||||
only for be used with specific transfers:
|
||||
thermal, two_temperature
|
||||
|
||||
\section related
|
||||
\ref man_filter_scale \n
|
||||
\ref man_equilibrium_start
|
||||
|
||||
\section default
|
||||
off
|
||||
*/
|
||||
else if (strcmp(arg[0],"on")==0) {
|
||||
if (filterScale_<=0.)
|
||||
throw ATC_Error(0,"Filtering time scale not initialized");
|
||||
useFilter_ = true;
|
||||
if (!equilibrateFilter_) {
|
||||
needReset_ = true;
|
||||
endEquilibrate_ = false;
|
||||
}
|
||||
else {
|
||||
endEquilibrate_ = true;
|
||||
}
|
||||
equilibrateFilter_ = false;
|
||||
foundMatch = true;
|
||||
}
|
||||
else if (strcmp(arg[0],"off")==0) {
|
||||
useFilter_ = false;
|
||||
equilibrateFilter_ = false;
|
||||
endEquilibrate_ = false;
|
||||
needReset_ = true;
|
||||
foundMatch = true;
|
||||
}
|
||||
else if (strcmp(arg[0],"equilibrate")==0) {
|
||||
if (filterScale_<=0.)
|
||||
throw ATC_Error(0,"Filtering time scale not initialized");
|
||||
equilibrateFilter_ = true;
|
||||
endEquilibrate_ = false;
|
||||
useFilter_ = false;
|
||||
needReset_ = true;
|
||||
foundMatch = true;
|
||||
}
|
||||
|
||||
/** Example command for to set time filter scale:
|
||||
fix_modify atc transfer filter type step*/
|
||||
else if (strcmp(arg[0],"type")==0) {
|
||||
if (strcmp(arg[1],"exponential")==0) {
|
||||
filterType_ = EXPONENTIAL_FILTER;
|
||||
}
|
||||
else if (strcmp(arg[1],"no_filter")==0) {
|
||||
filterType_ = NO_FILTER;
|
||||
}
|
||||
else throw ATC_Error(0,"Not a supported time filter type");
|
||||
foundMatch = true;
|
||||
}
|
||||
|
||||
|
||||
return foundMatch;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
// filter set up before a run
|
||||
//--------------------------------------------------------
|
||||
void TimeFilterManager::initialize()
|
||||
{
|
||||
needReset_ = false;
|
||||
endEquilibrate_ = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// construct
|
||||
// instantiates the filter
|
||||
//--------------------------------------------------------
|
||||
// NOTE currently the caller is responsible for deletion
|
||||
TimeFilter * TimeFilterManager::construct(const FilterIntegrationType intType)
|
||||
{
|
||||
if (useFilter_ || equilibrateFilter_) {
|
||||
if (filterType_ == EXPONENTIAL_FILTER) {
|
||||
if (intType == IMPLICIT_EXPLICIT) {
|
||||
return new TimeFilterImplicitExplicit(*this);
|
||||
}
|
||||
else if (intType == EXPLICIT_IMPLICIT) {
|
||||
return new TimeFilterExplicitImplicit(*this);
|
||||
}
|
||||
else if (intType == EXPLICIT) {
|
||||
return new TimeFilterExplicit(*this);
|
||||
}
|
||||
else if (intType == IMPLICIT) {
|
||||
return new TimeFilterImplicit(*this);
|
||||
}
|
||||
else if (intType == IMPLICIT_UPDATE) {
|
||||
return new TimeFilterImplicitUpdate(*this);
|
||||
}
|
||||
else {
|
||||
return new TimeFilterCrankNicolson(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default to return base class
|
||||
return new TimeFilter(*this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilter
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilter::TimeFilter(TimeFilterManager & timeFilterManager) :
|
||||
atcTransfer_(timeFilterManager.get_atc_transfer()),
|
||||
filterScale_(timeFilterManager.get_filter_scale())
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExponential
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterExponential::TimeFilterExponential(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilter(timeFilterManager)
|
||||
{
|
||||
TimeFilter::filterType_ = TimeFilterManager::EXPONENTIAL_FILTER;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
// resets memory as needed
|
||||
//--------------------------------------------------------
|
||||
void TimeFilterExponential::initialize(const MATRIX & target)
|
||||
{
|
||||
TimeFilter::initialize(target);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterCrankNicoslon
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterCrankNicolson::TimeFilterCrankNicolson(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
// resets memory as needed
|
||||
//--------------------------------------------------------
|
||||
void TimeFilterCrankNicolson::initialize(const MATRIX & target)
|
||||
{
|
||||
TimeFilterExponential::initialize(target);
|
||||
unFilteredQuantityOld_.reset(target.nRows(),target.nCols());
|
||||
unFilteredQuantityOld_ = target;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterExplicit::TimeFilterExplicit(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterImplicit::TimeFilterImplicit(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicitExplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterImplicitExplicit::TimeFilterImplicitExplicit(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExplicitImplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterExplicitImplicit::TimeFilterExplicitImplicit(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicitUpdate
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterImplicitUpdate::TimeFilterImplicitUpdate(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilterExponential(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterStep
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeFilterStep::TimeFilterStep(TimeFilterManager & timeFilterManager) :
|
||||
TimeFilter(timeFilterManager)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// initialize
|
||||
// resets memory as needed
|
||||
//--------------------------------------------------------
|
||||
void TimeFilterStep::initialize(const MATRIX & target)
|
||||
{
|
||||
TimeFilter::initialize(target);
|
||||
}
|
||||
|
||||
|
||||
};
|
|
@ -1,696 +0,0 @@
|
|||
// The type of filter used should be determined by the
|
||||
// integrator since filtering much match the time integration scheme
|
||||
|
||||
#ifndef TIME_FILTER_H
|
||||
#define TIME_FILTER_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "MatrixLibrary.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
using namespace std;
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class ATC_Transfer;
|
||||
class TimeFilter;
|
||||
|
||||
/**
|
||||
* @class TimeFilterManager
|
||||
* @brief Handles parsing and parameter storage for time filters
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterManager
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class TimeFilterManager {
|
||||
|
||||
public:
|
||||
|
||||
/** enumeration for the functional form underlying the filter */
|
||||
enum TimeFilterType {
|
||||
NO_FILTER=0, // default
|
||||
EXPONENTIAL_FILTER,
|
||||
STEP_FILTER
|
||||
};
|
||||
|
||||
/** enumeration for the functional form underlying the filter */
|
||||
enum FilterIntegrationType {
|
||||
CRANK_NICHOLSON=0, // default
|
||||
IMPLICIT_EXPLICIT,
|
||||
EXPLICIT_IMPLICIT,
|
||||
EXPLICIT,
|
||||
IMPLICIT,
|
||||
IMPLICIT_UPDATE
|
||||
};
|
||||
|
||||
// constructor
|
||||
TimeFilterManager(ATC_Transfer * atcTransfer);
|
||||
|
||||
// destructor
|
||||
~TimeFilterManager(){};
|
||||
|
||||
/** parser/modifier */
|
||||
bool modify(int narg, char **arg);
|
||||
|
||||
/** pre time integration */
|
||||
void initialize();
|
||||
|
||||
/** get filter base function */
|
||||
TimeFilterType get_filter_type() const {return filterType_;};
|
||||
|
||||
/** return filtering time scale */
|
||||
double get_filter_scale() const {return filterScale_;};
|
||||
|
||||
/** check if dynamics should be filtering */
|
||||
bool filter_dynamics() const {return useFilter_;};
|
||||
|
||||
/** check if variables should be filtered */
|
||||
bool filter_variables() const {return (useFilter_ || equilibrateFilter_);};
|
||||
|
||||
/** flag for if reset is needed */
|
||||
bool need_reset() const {return needReset_;};
|
||||
|
||||
/** flag if ending equilibration */
|
||||
bool end_equilibrate() const {return endEquilibrate_;};
|
||||
|
||||
/** get pointer to ATC transfer methods */
|
||||
ATC_Transfer * get_atc_transfer() {return atcTransfer_;};
|
||||
|
||||
/** construct the appropriate time filter */
|
||||
TimeFilter * construct(const FilterIntegrationType type = CRANK_NICHOLSON);
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterManager(){};
|
||||
|
||||
/** pointer to access ATC methods */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** description of underlying function form of filter */
|
||||
TimeFilterType filterType_;
|
||||
|
||||
/** filtering time scale */
|
||||
double filterScale_;
|
||||
|
||||
/** flag to see if filtering is active */
|
||||
bool useFilter_;
|
||||
|
||||
/** flag to see if we are equilibrating the filtered variables */
|
||||
bool equilibrateFilter_;
|
||||
|
||||
/** flag to reset data */
|
||||
bool needReset_;
|
||||
|
||||
/** flag to denote switch from equilibration to integration */
|
||||
bool endEquilibrate_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilter
|
||||
* @brief Base class for various temporal filters of atomistic quantities
|
||||
* default behavior is no filter
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilter
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
|
||||
class TimeFilter {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilter(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilter(){};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(const MATRIX & target){};
|
||||
|
||||
/** Step 1:
|
||||
apply first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt)
|
||||
{ TimeFilter::unFilteredQuantityOld_ = unFilteredQuantity;}
|
||||
|
||||
/** Step 2:
|
||||
apply second step in a time filter update in pre integration phase */
|
||||
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** Step 3:
|
||||
apply first step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** Step 4:
|
||||
apply second step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt)
|
||||
{ filteredQuantity = unFilteredQuantity;}
|
||||
|
||||
/** coefficient multipling unfiltered terms in apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return 0.;};
|
||||
|
||||
/** coefficient multipling unfiltered terms in apply_post_step1 method */
|
||||
virtual double get_unfiltered_coefficient_post_s1(double dt){return 0.;};
|
||||
|
||||
/** coefficient multipling unfiltered terms in apply_pre_step2 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s2(double dt){return 0.;};
|
||||
|
||||
/** coefficient multipling unfiltered terms in apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s2(double dt){return 0.;};
|
||||
|
||||
/** rate of filtered quantity to be called in post integration phase */
|
||||
virtual void rate(MATRIX & rate,
|
||||
const MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt = 0.0)
|
||||
{ rate = 1/dt*(unFilteredQuantity - TimeFilter::unFilteredQuantityOld_);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilter(){};
|
||||
|
||||
/** pointer to access ATC methods */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** filtering time scale */
|
||||
double filterScale_;
|
||||
|
||||
/** filter type */
|
||||
TimeFilterManager::TimeFilterType filterType_;
|
||||
|
||||
/** member data to track old unfiltered values */
|
||||
DENS_MAT unFilteredQuantityOld_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterExponential
|
||||
* @brief Base class for filters using an exponential kernel,
|
||||
* derived classes implement specific integration schemes
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExponential
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class TimeFilterExponential : public TimeFilter {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterExponential(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterExponential(){};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(const MATRIX & target);
|
||||
|
||||
/** apply first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply second step in a time filter update in pre integration phase */
|
||||
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply first step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply second step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** time rate of filtered quantity */
|
||||
virtual void rate(MATRIX & rate,
|
||||
const MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double dt = 0)
|
||||
{ double tau = TimeFilter::filterScale_;
|
||||
rate = 1/tau*(unfilteredQuantity - filteredQuantity); };
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterExponential(){};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// filter integration functions not associated
|
||||
// with any particular class
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
void update_filter(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
MATRIX & unfilteredQuantityOld,
|
||||
double tau,
|
||||
double dt)
|
||||
{
|
||||
filteredQuantity = 1./(1./dt+1./(2*tau))*( 1./(2*tau)*
|
||||
(unfilteredQuantity+unfilteredQuantityOld) +
|
||||
(1./dt-1./(2*tau))*filteredQuantity);
|
||||
unfilteredQuantityOld = unfilteredQuantity;
|
||||
};
|
||||
|
||||
void add_to_filter(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
MATRIX & unfilteredQuantityOld,
|
||||
double tau,
|
||||
double dt)
|
||||
{
|
||||
filteredQuantity += 1./(1./dt+1./(2.*tau))*( 1./(2.*tau))*unfilteredQuantity;
|
||||
unfilteredQuantityOld += unfilteredQuantity;
|
||||
};
|
||||
|
||||
double get_unfiltered_coef(double tau, double dt)
|
||||
{ return 1./(1./dt+1./(2.*tau))*( 1./(2.*tau)); };
|
||||
|
||||
void update_filter_implicit(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double tau,
|
||||
double dt)
|
||||
// TODO: replace the rest of these like below:
|
||||
{ filteredQuantity = (1./(1.+dt/tau))*((dt/tau)*unfilteredQuantity + filteredQuantity); };
|
||||
// {
|
||||
// filteredQuantity /= 1.0 + dt/tau;
|
||||
// filteredQuantity += (dt)/(tau+dt)*unfilteredQuantity;
|
||||
// }
|
||||
|
||||
void add_to_filter_implicit(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double tau,
|
||||
double dt)
|
||||
{ filteredQuantity += (1./(1.+dt/tau))*(dt/tau)*unfilteredQuantity; };
|
||||
|
||||
double get_unfiltered_coef_implicit(double tau, double dt)
|
||||
{ return (1./(1.+dt/tau))*(dt/tau); };
|
||||
|
||||
void update_filter_explicit(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double tau,
|
||||
double dt)
|
||||
{ filteredQuantity = (dt/tau)*unfilteredQuantity + (1.-dt/tau)*filteredQuantity; };
|
||||
|
||||
void add_to_filter_explicit(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double tau,
|
||||
double dt)
|
||||
{ filteredQuantity += (dt/tau)*unfilteredQuantity; };
|
||||
|
||||
double get_unfiltered_coef_explicit(double dt, double tau)
|
||||
{ return (dt/tau); };
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterCrankNicolson
|
||||
* @brief Time Filter using Crank-Nicolson advancement of filtered quantity ODE's
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterCrankNicolson
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterCrankNicolson : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterCrankNicolson(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterCrankNicolson(){};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(const MATRIX & target);
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies first step in a time filter update after the pre integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ add_to_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter(filteredQuantity,unFilteredQuantity,unFilteredQuantityOld_,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s2(double dt){return get_unfiltered_coef(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterCrankNicolson();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterExplicit
|
||||
* @brief Time Filter using explicit advancement of filtered quantity ODE's
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterExplicit : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterExplicit(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterExplicit(){};
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies first step in a time filter update after the pre integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ add_to_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s2(double dt){return get_unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterExplicit();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterImplicit
|
||||
* @brief Time Filter using implicit advancement of filtered quantity ODE's
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterImplicit : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterImplicit(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterImplicit(){};
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s2(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterImplicit();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterImplicitExplicit
|
||||
* @brief Time Filter using two-step implicit/explicit advancement of filtered quantity ODE's
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicitExplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterImplicitExplicit : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterImplicitExplicit(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterImplicitExplicit(){};
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s2(double dt){return get_unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterImplicitExplicit();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterExplicitImplicit
|
||||
* @brief Time Filter using two-step explicit/implicit advancement of filtered quantity ODE's
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterExplicitImplicit
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterExplicitImplicit : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterExplicitImplicit(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterExplicitImplicit(){};
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ add_to_filter_explicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ add_to_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef_explicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s1(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterExplicitImplicit();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeFilterImplicitUpdate
|
||||
* @brief Time Filter using implicit advancement of filtered quantity ODE's but adds on contribution at the end of the second step
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterImplicitUpdate
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
class TimeFilterImplicitUpdate : public TimeFilterExponential {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterImplicitUpdate(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterImplicitUpdate(){};
|
||||
|
||||
/** applies first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** applies second step in a time filter update in the post integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
MATRIX const & unFilteredQuantity,
|
||||
double dt)
|
||||
{ add_to_filter_implicit(filteredQuantity,unFilteredQuantity,TimeFilter::filterScale_,dt); };
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_pre_step1 method */
|
||||
virtual double get_unfiltered_coefficient_pre_s1(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
/** return coefficient multipling unfiltered terms in the apply_post_step2 method */
|
||||
virtual double get_unfiltered_coefficient_post_s1(double dt){return get_unfiltered_coef_implicit(TimeFilter::filterScale_,dt);};
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterImplicitUpdate();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeFilterStep
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class TimeFilterStep : public TimeFilter {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeFilterStep(TimeFilterManager & timeFilterManager);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeFilterStep(){};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(const MATRIX & target);
|
||||
|
||||
/** apply first step in a time filter update in the pre integration phase */
|
||||
virtual void apply_pre_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply second step in a time filter update in pre integration phase */
|
||||
virtual void apply_pre_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply first step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step1(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt) {};
|
||||
|
||||
/** apply second step in a time filter update in post integration phase */
|
||||
virtual void apply_post_step2(MATRIX & filteredQuantity,
|
||||
const MATRIX & unFilteredQuantity,
|
||||
double dt)
|
||||
{ update_filter(filteredQuantity, unFilteredQuantity,
|
||||
TimeFilter::unFilteredQuantityOld_, TimeFilter::filterScale_, dt);
|
||||
}
|
||||
|
||||
/** time rate of filtered quantity */
|
||||
virtual void rate(MATRIX & rate,
|
||||
const MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
double dt = 0)
|
||||
{ rate = 1/elapsedTime_*(unfilteredQuantity - filteredQuantity); }
|
||||
|
||||
protected:
|
||||
|
||||
TimeFilterStep(){};
|
||||
|
||||
double elapsedTime_;
|
||||
|
||||
void update_filter(MATRIX & filteredQuantity,
|
||||
const MATRIX & unfilteredQuantity,
|
||||
MATRIX & unfilteredQuantitySum,
|
||||
double tau,
|
||||
double dt)
|
||||
{
|
||||
elapsedTime_ += dt;
|
||||
if (elapsedTime_ > tau) {
|
||||
elapsedTime_ = dt;
|
||||
unfilteredQuantitySum = unfilteredQuantity*dt;
|
||||
filteredQuantity = unfilteredQuantity;
|
||||
}
|
||||
else {
|
||||
unfilteredQuantitySum += unfilteredQuantity*dt;
|
||||
filteredQuantity = unfilteredQuantitySum;
|
||||
filteredQuantity /= elapsedTime_;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,176 +0,0 @@
|
|||
// ATC transfer headers
|
||||
#include "TimeIntegrator.h"
|
||||
#include "ATC_Transfer.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeIntegrator
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------
|
||||
TimeIntegrator::TimeIntegrator(ATC_Transfer * atcTransfer,
|
||||
TimeIntegrationType timeIntegrationType) :
|
||||
atcTransfer_(atcTransfer),
|
||||
timeIntegrationMethod_(NULL),
|
||||
timeFilter_(NULL),
|
||||
timeFilterManager_(atcTransfer_->get_time_filter_manager()),
|
||||
timeIntegrationType_(timeIntegrationType),
|
||||
needReset_(true)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Destructor
|
||||
//--------------------------------------------------------
|
||||
TimeIntegrator::~TimeIntegrator()
|
||||
{
|
||||
if (timeFilter_)
|
||||
delete timeFilter_;
|
||||
|
||||
if (timeIntegrationMethod_)
|
||||
delete timeIntegrationMethod_;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_initial_integrate1
|
||||
// first time integration computations
|
||||
// before Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::pre_initial_integrate1(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->pre_initial_integrate1(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_initial_integrate2
|
||||
// second time integration computations
|
||||
// before Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::pre_initial_integrate2(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->pre_initial_integrate2(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// mid_initial_integrate1
|
||||
// first time integration computations
|
||||
// at the mid-point of Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::mid_initial_integrate1(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->mid_initial_integrate1(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// mid_initial_integrate2
|
||||
// second time integration computations
|
||||
// at the mid-point of Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::mid_initial_integrate2(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->mid_initial_integrate2(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_initial_integrate1
|
||||
// first time integration computations
|
||||
// after Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::post_initial_integrate1(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->post_initial_integrate1(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_initial_integrate2
|
||||
// second time integration computations
|
||||
// after Verlet step 1
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::post_initial_integrate2(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->post_initial_integrate2(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_final_integrate1
|
||||
// first time integration computations
|
||||
// before Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::pre_final_integrate1(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->pre_final_integrate1(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// pre_final_integrate2
|
||||
// second time integration computations
|
||||
// before Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::pre_final_integrate2(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->pre_final_integrate2(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_final_integrate1
|
||||
// first time integration computations
|
||||
// after Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::post_final_integrate1(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->post_final_integrate1(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_final_integrate2
|
||||
// second time integration computations
|
||||
// after Verlet step 2
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::post_final_integrate2(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->post_final_integrate2(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// post_process
|
||||
// perform any post processing calculations
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::post_process(double dt)
|
||||
{
|
||||
timeIntegrationMethod_->post_process(dt);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// output
|
||||
// add variables to output list
|
||||
//--------------------------------------------------------
|
||||
void TimeIntegrator::output(OUTPUT_LIST & outputData)
|
||||
{
|
||||
timeIntegrationMethod_->output(outputData);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeIntegrationMethod
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Constructor
|
||||
// Grab data from ATC
|
||||
//--------------------------------------------------------
|
||||
TimeIntegrationMethod::TimeIntegrationMethod(TimeIntegrator * timeIntegrator) :
|
||||
timeIntegrator_(timeIntegrator),
|
||||
atcTransfer_(timeIntegrator_->get_atc_transfer())
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
};
|
|
@ -1,280 +0,0 @@
|
|||
#ifndef TIME_INTEGRATOR_H
|
||||
#define TIME_INTEGRATOR_H
|
||||
|
||||
// ATC_Transfer headers
|
||||
#include "MatrixLibrary.h"
|
||||
#include "TimeFilter.h"
|
||||
#include "ATC_TypeDefs.h"
|
||||
|
||||
using namespace std;
|
||||
namespace ATC {
|
||||
|
||||
// forward declarations
|
||||
class ATC_Transfer;
|
||||
class TimeIntegrationMethod;
|
||||
|
||||
/**
|
||||
* @class TimeIntegrator
|
||||
* @brief Base class fo various time integrators for FE quantities
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeIntegrator
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class TimeIntegrator {
|
||||
|
||||
public:
|
||||
|
||||
/** types of time integration */
|
||||
enum TimeIntegrationType {
|
||||
STEADY,
|
||||
VERLET,
|
||||
GEAR,
|
||||
FRACTIONAL_STEP,
|
||||
EXPLICIT,
|
||||
IMPLICIT,
|
||||
CRANK_NICOLSON
|
||||
};
|
||||
|
||||
// constructor
|
||||
TimeIntegrator(ATC_Transfer * atcTransfer,
|
||||
TimeIntegrationType timeIntegrationType = STEADY);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeIntegrator();
|
||||
|
||||
/** parser/modifier */
|
||||
virtual bool modify(int narg, char **arg){return false;};
|
||||
|
||||
/** pre time integration */
|
||||
virtual void initialize(){needReset_ = false;};
|
||||
|
||||
/** flag if reset is needed */
|
||||
bool need_reset() {return needReset_;};
|
||||
|
||||
// time step methods, corresponding to ATC_Transfer
|
||||
/** first part of pre_initial_integrate */
|
||||
virtual void pre_initial_integrate1(double dt);
|
||||
/** second part of pre_initial_integrate */
|
||||
virtual void pre_initial_integrate2(double dt);
|
||||
|
||||
/** first part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate1(double dt);
|
||||
/** second part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate2(double dt);
|
||||
|
||||
/** first part of post_initial_integrate */
|
||||
virtual void post_initial_integrate1(double dt);
|
||||
/** second part of post_initial_integrate */
|
||||
virtual void post_initial_integrate2(double dt);
|
||||
|
||||
/** first part of pre_final_integrate */
|
||||
virtual void pre_final_integrate1(double dt);
|
||||
/** second part of pre_final_integrate */
|
||||
virtual void pre_final_integrate2(double dt);
|
||||
|
||||
/** first part of post_final_integrate */
|
||||
virtual void post_final_integrate1(double dt);
|
||||
/** second part of post_final_integrate */
|
||||
virtual void post_final_integrate2(double dt);
|
||||
|
||||
/** post processing step */
|
||||
virtual void post_process(double dt);
|
||||
/** add output data */
|
||||
virtual void output(OUTPUT_LIST & outputData);
|
||||
|
||||
// Member data access
|
||||
/** access to time integration type */
|
||||
TimeIntegrationType get_time_integration_type() const
|
||||
{ return timeIntegrationType_; };
|
||||
|
||||
/** access to ATC Transfer object */
|
||||
ATC_Transfer * get_atc_transfer() {return atcTransfer_;};
|
||||
|
||||
/** access to time filter object */
|
||||
TimeFilter * get_time_filter() {return timeFilter_;};
|
||||
|
||||
/** access to time filter manager object */
|
||||
TimeFilterManager * get_time_filter_manager() {return timeFilterManager_;};
|
||||
|
||||
/** force the integrator to be reset */
|
||||
void force_reset() {needReset_ = true;};
|
||||
|
||||
/** force the integrator not to be reset */
|
||||
void force_no_reset() {needReset_ = false;};
|
||||
|
||||
protected:
|
||||
|
||||
/** pointer to time integrator method */
|
||||
TimeIntegrationMethod * timeIntegrationMethod_;
|
||||
|
||||
/** pointer to access ATC methods */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
/** time filter for specific updates */
|
||||
TimeFilter * timeFilter_;
|
||||
|
||||
/** time filter manager for getting time filtering info */
|
||||
TimeFilterManager * timeFilterManager_;
|
||||
|
||||
/** type of integration scheme being used */
|
||||
TimeIntegrationType timeIntegrationType_;
|
||||
|
||||
/** flat to reset data */
|
||||
bool needReset_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
TimeIntegrator();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class TimeIntegrationMethod
|
||||
* @brief Base class fo various time integration methods
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Class TimeIntegrationMethod
|
||||
// Base class for time integration methods which
|
||||
// update the FE quantities
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
class TimeIntegrationMethod {
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
TimeIntegrationMethod(TimeIntegrator * timeIntegrator);
|
||||
|
||||
// destructor
|
||||
virtual ~TimeIntegrationMethod(){};
|
||||
|
||||
// time step methods, corresponding to ATC_Transfer and TimeIntegrator
|
||||
/** first part of pre_initial_integrate */
|
||||
virtual void pre_initial_integrate1(double dt){};
|
||||
/** second part of pre_initial_integrate */
|
||||
virtual void pre_initial_integrate2(double dt){};
|
||||
|
||||
/** first part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate1(double dt){};
|
||||
/** second part of mid_initial_integrate */
|
||||
virtual void mid_initial_integrate2(double dt){};
|
||||
|
||||
/** first part of post_initial_integrate */
|
||||
virtual void post_initial_integrate1(double dt){};
|
||||
/** second part of post_initial_integrate */
|
||||
virtual void post_initial_integrate2(double dt){};
|
||||
|
||||
/** first part of pre_final_integrate */
|
||||
virtual void pre_final_integrate1(double dt){};
|
||||
/** second part of pre_final_integrate */
|
||||
virtual void pre_final_integrate2(double dt){};
|
||||
|
||||
/** first part of post_final_integrate */
|
||||
virtual void post_final_integrate1(double dt){};
|
||||
/** second part of post_final_integrate */
|
||||
virtual void post_final_integrate2(double dt){};
|
||||
|
||||
/** post processing step */
|
||||
virtual void post_process(double dt){};
|
||||
/** add output data */
|
||||
virtual void output(OUTPUT_LIST & outputData){};
|
||||
|
||||
protected:
|
||||
|
||||
/** owning time integrator */
|
||||
TimeIntegrator * timeIntegrator_;
|
||||
|
||||
/** associated ATC transfer object */
|
||||
ATC_Transfer * atcTransfer_;
|
||||
|
||||
private:
|
||||
|
||||
// DO NOT define this
|
||||
TimeIntegrationMethod();
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// time integration functions not associated
|
||||
// with any particular class
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
||||
static void gear1_4_predict(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
MATRIX & ddot_f,
|
||||
MATRIX & dddot_f,
|
||||
double dt)
|
||||
// 4th order Gear integrator for 1rst order ODE predictor step
|
||||
{
|
||||
f = f + dot_f*dt + ddot_f*(1./2.*dt*dt) + dddot_f*(1./6.*dt*dt*dt);
|
||||
dot_f = dot_f + ddot_f*dt+dddot_f*(1./2.*dt*dt);
|
||||
ddot_f = ddot_f + dddot_f*dt;
|
||||
};
|
||||
|
||||
static void gear1_3_predict(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
MATRIX & ddot_f,
|
||||
double dt)
|
||||
// 3rd order Gear integrator for 1rst order ODE predictor step
|
||||
{
|
||||
f = f + dot_f*dt + ddot_f*(1./2.*dt*dt);
|
||||
dot_f = dot_f + ddot_f*dt;
|
||||
};
|
||||
|
||||
static void gear1_4_correct(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
MATRIX & ddot_f,
|
||||
MATRIX & dddot_f,
|
||||
const MATRIX & R_f,
|
||||
double dt)
|
||||
// 4th order Gear integrator for 1rst order ODE corrector step
|
||||
{
|
||||
f = f + (3./8.)*R_f;
|
||||
dot_f = dot_f + (1./dt)*R_f;
|
||||
ddot_f = ddot_f + (3./2./dt/dt)*R_f;
|
||||
dddot_f = dddot_f + (1./dt/dt/dt)*R_f;
|
||||
};
|
||||
|
||||
static void gear1_3_correct(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
MATRIX & ddot_f,
|
||||
const MATRIX & R_f,
|
||||
double dt)
|
||||
// 3rd order Gear integrator for 1rst order ODE corrector step
|
||||
{
|
||||
f = f + (5./12.)*R_f;
|
||||
dot_f = dot_f + (1./dt)*R_f;
|
||||
ddot_f = ddot_f + (1./dt/dt)*R_f;
|
||||
};
|
||||
|
||||
static void explicit_1(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
double dt)
|
||||
// 1rst order explict ODE update
|
||||
{
|
||||
f = f + dt*dot_f;
|
||||
};
|
||||
|
||||
static void explicit_2(MATRIX & f,
|
||||
MATRIX & dot_f,
|
||||
MATRIX & ddot_f,
|
||||
double dt)
|
||||
// 2nd order explict ODE update
|
||||
{
|
||||
f = f + dt*dot_f + .5*dt*dt*ddot_f;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
#ifndef UTILITY_H
|
||||
#define UTILITY_H
|
||||
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#undef near
|
||||
|
||||
using std::vector;
|
||||
|
||||
namespace Utility
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns true if the value v is between min and max
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline bool InRange(const T &v, const T &min, const T &max)
|
||||
{
|
||||
return v >= min && v <= max;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns true if the value v is between min and max within the tolerance TOL
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline bool InRange(const T &v, const T &min, const T &max, const T &TOL)
|
||||
{
|
||||
return InRange(v, min-TOL, max+TOL);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the value with the larger absolute value
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline T MaxAbs(const T &a, const T &b)
|
||||
{
|
||||
return (a*a > b*b) ? a : b;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the value with the smaller absolute value
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline T MinAbs(const T &a, const T &b)
|
||||
{
|
||||
return (a*a < b*b) ? a : b;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A simple Matlab like timing function
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double tictoc()
|
||||
{
|
||||
double t_new = clock() / (double) CLOCKS_PER_SEC;
|
||||
static double t = t_new;
|
||||
double dt = t_new - t;
|
||||
t = t_new;
|
||||
return dt;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Binary search between low and high for value (assumes array is sorted)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline int SearchSorted(const T* A, T value, unsigned low, unsigned high)
|
||||
{
|
||||
unsigned mid;
|
||||
while ((low+1)<=(high+1))
|
||||
{
|
||||
mid = (low + high) >> 1; // set mid to mean of high and low
|
||||
if (A[mid] > value) high = mid-1; // mid was too high, reduce high
|
||||
else if (A[mid] < value) low = mid+1; // mid was too low, increase low
|
||||
else return mid;
|
||||
}
|
||||
return -1; // value not found in array, return -1
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Flat search between low and high for value (assumes array is NOT sorted)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline int SearchUnsorted(const T* A, T value, unsigned low, unsigned high)
|
||||
{
|
||||
for (low; low<=high; low++) if (A[low] == value) return low;
|
||||
return -1;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Regular swap
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline void Swap(T &a, T &b)
|
||||
{
|
||||
T temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the sign of a double precision number
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double Sign(double x) { return (x >= 0.0) ? 1.0 : -1.0; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the sign of a single precision number
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline float Sign(float x) { return (x >= 0.0f) ? 1.0f : -1.0f; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns the pythagorean distance with the two lengths
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double Norm(double x, double y) { return sqrt(x*x+y*y); }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns square of a value
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline T Square(T x) { return x*x; }
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
#include "DenseVector.h"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* performs a matrix-vector multiply with optional transposes BLAS version
|
||||
void MultMv(const Matrix<double> &A, const Vector<double> &v, DenseVector<double> &c,
|
||||
const bool At, double a, double b)
|
||||
{
|
||||
static char t[2] = {'N','T'};
|
||||
char *ta=t+At;
|
||||
int sA[2] = {A.nRows(), A.nCols()}; // sizes of A
|
||||
int sV[2] = {v.size(), 1}; // sizes of v
|
||||
|
||||
GCK(A, v, sA[!At]!=sV[0], "MultAB<double>: matrix-vector multiply");
|
||||
if (c.size() != sA[At])
|
||||
{
|
||||
c.resize(sA[At]); // set size of C to final size
|
||||
c.zero();
|
||||
}
|
||||
// get pointers to the matrix sizes needed by BLAS
|
||||
int *M = sA+At; // # of rows in op[A] (op[A] = A' if At='T' else A)
|
||||
int *N = sV+1; // # of cols in op[B]
|
||||
int *K = sA+!At; // # of cols in op[A] or # of rows in op[B]
|
||||
|
||||
double *pa=A.get_ptr(), *pv=v.get_ptr(), *pc=c.get_ptr();
|
||||
|
||||
#ifdef COL_STORAGE
|
||||
dgemm_(ta, t, M, N, K, &a, pa, sA, pv, sV, &b, pc, M);
|
||||
#else
|
||||
dgemm_(t, ta, N, M, K, &a, pv, sV+1, pa, sA+1, &b, pc, N);
|
||||
#endif
|
||||
}
|
195
lib/atc/Vector.h
195
lib/atc/Vector.h
|
@ -1,195 +0,0 @@
|
|||
#ifndef VECTOR_H
|
||||
#define VECTOR_H
|
||||
|
||||
#include "Matrix.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// forward declarations ///////////////////////////////////////////////////////
|
||||
|
||||
//* Matrix-vector product
|
||||
//template<typename T>
|
||||
//void MultMv(const Matrix<T> &A, const Vector<T> &v, DenseVector<T> &c,
|
||||
// const bool At=0, T a=1, T b=0);
|
||||
|
||||
/******************************************************************************
|
||||
* abstract class Vector
|
||||
******************************************************************************/
|
||||
template<typename T>
|
||||
class Vector : public Matrix<T>
|
||||
{
|
||||
public:
|
||||
Vector() {}
|
||||
Vector(const Vector<T> &c); // do not implement!
|
||||
virtual ~Vector() {}
|
||||
|
||||
string tostring() const;
|
||||
|
||||
// pure virtual functions
|
||||
virtual T operator()(INDEX i, INDEX j=0) const=0;
|
||||
virtual T& operator()(INDEX i, INDEX j=0) =0;
|
||||
virtual T operator[](INDEX i) const=0;
|
||||
virtual T& operator[](INDEX i) =0;
|
||||
virtual INDEX nRows() const=0;
|
||||
virtual T* get_ptr() const=0;
|
||||
virtual void resize(INDEX nRows, INDEX nCols=1, bool copy=0)=0;
|
||||
virtual void reset(INDEX nRows, INDEX nCols=1, bool zero=0)=0;
|
||||
virtual void copy(const T * ptr, INDEX nRows, INDEX nCols=1)=0;
|
||||
void write_restart(FILE *f) const; // will be virtual
|
||||
|
||||
|
||||
// output to matlab
|
||||
using Matrix<T>::matlab;
|
||||
void matlab(ostream &o, const string &s="v") const;
|
||||
|
||||
INDEX nCols() const;
|
||||
bool in_range(INDEX i) const;
|
||||
bool same_size(const Vector &m) const;
|
||||
static bool same_size(const Vector &a, const Vector &b);
|
||||
|
||||
protected:
|
||||
//* don't allow this
|
||||
Vector& operator=(const Vector &r);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* performs a matrix-vector multiply with default naive implementation
|
||||
template<typename T>
|
||||
void MultMv(const Matrix<T> &A, const Vector<T> &v, DenseVector<T> &c,
|
||||
const bool At, T a, T b)
|
||||
{
|
||||
const INDEX sA[2] = {A.nRows(), A.nCols()}; // m is sA[At] k is sA[!At]
|
||||
const INDEX M=sA[At], K=sA[!At];
|
||||
GCK(A, v, v.size()!=K, "MultAb<T>: matrix-vector multiply");
|
||||
if (c.size() != M)
|
||||
{
|
||||
c.resize(M); // set size of C
|
||||
c.zero(); // do not add result to C
|
||||
}
|
||||
else c *= b;
|
||||
for (INDEX p=0; p<M; p++)
|
||||
for (INDEX r=0; r<K; r++)
|
||||
c[p] += A(p*!At+r*At, p*At+r*!At) * v[r];
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Operator for Matrix-vector product
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const Matrix<T> &A, const Vector<T> &b)
|
||||
{
|
||||
DenseVector<T> c;
|
||||
MultMv(A, b, c, 0, 1.0, 0.0);
|
||||
return c;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Operator for Vector-matrix product
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const Vector<T> &a, const Matrix<T> &B)
|
||||
{
|
||||
DenseVector<T> c;
|
||||
MultMv(B, a, c, 1, 1.0, 0.0);
|
||||
return c;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Multiply a vector by a scalar
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const Vector<T> &v, const T s)
|
||||
{
|
||||
DenseVector<T> r(v);
|
||||
r*=s;
|
||||
return r;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Multiply a vector by a scalar - communitive
|
||||
template<typename T>
|
||||
DenseVector<T> operator*(const T s, const Vector<T> &v)
|
||||
{
|
||||
DenseVector<T> r(v);
|
||||
r*=s;
|
||||
return r;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* inverse scaling operator - must always create memory
|
||||
template<typename T>
|
||||
DenseMatrix<T> operator/(const Vector<T> &v, const T s)
|
||||
{
|
||||
DenseVector<T> r(v);
|
||||
r*=(1.0/s); // for integer types this may be worthless
|
||||
return ;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Operator for Vector-Vector sum
|
||||
template<typename T>
|
||||
DenseVector<T> operator+(const Vector<T> &a, const Vector<T> &b)
|
||||
{
|
||||
DenseVector<T> c(a);
|
||||
c+=b;
|
||||
return c;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Operator for Vector-Vector subtraction
|
||||
template<typename T>
|
||||
DenseVector<T> operator-(const Vector<T> &a, const Vector<T> &b)
|
||||
{
|
||||
DenseVector<T> c(a);
|
||||
c-=b;
|
||||
return c;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Template definitions ///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* output operator
|
||||
template<typename T>
|
||||
string Vector<T>::tostring() const
|
||||
{
|
||||
string s;
|
||||
FORi s += string(i?"\t":"") + ATC_STRING::tostring(VIDX(i),5);
|
||||
return s;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* Writes a matlab script defining the vector to the stream
|
||||
template<typename T>
|
||||
void Vector<T>::matlab(ostream &o, const string &s) const
|
||||
{
|
||||
o << s <<"=zeros(" << this->size() << ",1);\n";
|
||||
FORi o << s << "("<<i+1<<") = " << VIDX(i) << ";\n";
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* writes the vector data to a file
|
||||
template <typename T>
|
||||
void Vector<T>::write_restart(FILE *f) const
|
||||
{
|
||||
INDEX size = this->size();
|
||||
fwrite(&size, sizeof(INDEX),1,f);
|
||||
if (size) fwrite(this->get_ptr(), sizeof(T), this->size(), f);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* returns the number of columns; always 1
|
||||
template<typename T>
|
||||
inline INDEX Vector<T>::nCols() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* returns true if INDEX i is within the range of the vector
|
||||
template<typename T>
|
||||
bool Vector<T>::in_range(INDEX i) const
|
||||
{
|
||||
return i<this->size();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* returns true if m has the same number of elements this vector
|
||||
template<typename T>
|
||||
bool Vector<T>::same_size(const Vector &m) const
|
||||
{
|
||||
return this->size() == m.size();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//* returns true if a and b have the same number of elements
|
||||
template<typename T>
|
||||
inline bool Vector<T>::same_size(const Vector &a, const Vector &b)
|
||||
{
|
||||
return a.same_size(b);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,257 +0,0 @@
|
|||
#include "XT_Function.h"
|
||||
#include "ATC_Error.h"
|
||||
|
||||
namespace ATC {
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// XT_Function
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
XT_Function::XT_Function(int narg, double* args)
|
||||
{
|
||||
// NOTE need to adjust scaling to match input nodal coordinates
|
||||
if (narg > 5 ) { // NOTE kludge for temporal only functions
|
||||
x0[0] = args[0];
|
||||
x0[1] = args[1];
|
||||
x0[2] = args[2];
|
||||
mask[0] = args[3];
|
||||
mask[1] = args[4];
|
||||
mask[2] = args[5];
|
||||
}
|
||||
else {
|
||||
x0[0] = 0.0;
|
||||
x0[1] = 0.0;
|
||||
x0[2] = 0.0;
|
||||
mask[0] = 0.0;
|
||||
mask[1] = 0.0;
|
||||
mask[2] = 0.0;
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// XT_Function_Mgr
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
XT_Function_Mgr * XT_Function_Mgr::myInstance_ = NULL;
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// instance()
|
||||
// -----------------------------------------------------------------
|
||||
XT_Function_Mgr * XT_Function_Mgr::instance()
|
||||
{
|
||||
if (myInstance_ == NULL) {
|
||||
myInstance_ = new XT_Function_Mgr();
|
||||
}
|
||||
return myInstance_;
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
XT_Function_Mgr::~XT_Function_Mgr()
|
||||
{
|
||||
// Delete all functions created using "new"
|
||||
for (int i = 0; i < xtFunctionVec_.size(); i++) {
|
||||
delete xtFunctionVec_[i];
|
||||
}
|
||||
}
|
||||
|
||||
// add user function into the if statement and assign returnFunction to it
|
||||
XT_Function* XT_Function_Mgr::get_function(string & type, int nargs, double * args)
|
||||
{
|
||||
XT_Function * returnFunction;
|
||||
if (type=="constant") {
|
||||
returnFunction = new ConstantFunction(nargs,args);
|
||||
}
|
||||
else if (type=="temporal_ramp") {
|
||||
returnFunction = new TemporalRamp(nargs,args);
|
||||
}
|
||||
else if (type=="linear")
|
||||
returnFunction = new LinearFunction(nargs,args);
|
||||
else if (type=="quadratic")
|
||||
returnFunction = new QuadraticFunction(nargs,args);
|
||||
else if (type=="sine")
|
||||
returnFunction = new SineFunction(nargs,args);
|
||||
else if (type=="gaussian")
|
||||
returnFunction = new GaussianFunction(nargs,args);
|
||||
else if (type=="gaussian_temporal_ramp")
|
||||
returnFunction = new GaussianTemporalRamp(nargs,args);
|
||||
else
|
||||
throw ATC_Error(0,"Bad user function name");
|
||||
|
||||
xtFunctionVec_.push_back(returnFunction);
|
||||
|
||||
return returnFunction;
|
||||
}
|
||||
|
||||
// add user function into the if statement and assign returnFunction to it
|
||||
XT_Function* XT_Function_Mgr::get_function(char ** args, int nargs)
|
||||
{
|
||||
string type = args[0];
|
||||
int narg = nargs -1;
|
||||
double dargs[narg];
|
||||
for (int i = 0; i < narg; ++i) dargs[i] = atof(args[i+1]);
|
||||
|
||||
return get_function(type, narg, dargs);
|
||||
}
|
||||
|
||||
// add constant function
|
||||
XT_Function* XT_Function_Mgr::get_constant_function(double c)
|
||||
{
|
||||
double args[1] = {c}; // NOTE kludge
|
||||
XT_Function * returnFunction = new ConstantFunction(1,args);
|
||||
xtFunctionVec_.push_back(returnFunction);
|
||||
return (returnFunction);
|
||||
}
|
||||
|
||||
XT_Function* XT_Function_Mgr::copy_XT_function(XT_Function* other)
|
||||
{
|
||||
string tag = other->get_tag();
|
||||
|
||||
XT_Function * returnFunction = NULL;
|
||||
if (tag=="linear") {
|
||||
LinearFunction * other_cast = (LinearFunction*) other;
|
||||
returnFunction = new LinearFunction(*other_cast);
|
||||
}
|
||||
if (tag=="quadratic") {
|
||||
QuadraticFunction * other_cast = (QuadraticFunction*) other;
|
||||
returnFunction = new QuadraticFunction(*other_cast);
|
||||
}
|
||||
else if (tag=="sine") {
|
||||
SineFunction * other_cast = (SineFunction*) other;
|
||||
returnFunction = new SineFunction(*other_cast);
|
||||
}
|
||||
else if (tag=="gaussian") {
|
||||
GaussianFunction * other_cast = (GaussianFunction*) other;
|
||||
returnFunction = new GaussianFunction(*other_cast);
|
||||
}
|
||||
else if (tag=="gaussian_temporal_ramp") {
|
||||
GaussianTemporalRamp * other_cast = (GaussianTemporalRamp*) other;
|
||||
returnFunction = new GaussianTemporalRamp(*other_cast);
|
||||
}
|
||||
else if (tag=="temporal_ramp") {
|
||||
TemporalRamp * other_cast = (TemporalRamp*) other;
|
||||
returnFunction = new TemporalRamp(*other_cast);
|
||||
}
|
||||
return returnFunction;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// ConstantFunction
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
ConstantFunction::ConstantFunction(int narg, double* args)
|
||||
: XT_Function(narg,args),
|
||||
C0(args[0])
|
||||
{
|
||||
tag = "constant";
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// LinearFunction
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
LinearFunction::LinearFunction(int narg, double* args)
|
||||
: XT_Function(narg,args)
|
||||
{
|
||||
C0 = args[6];
|
||||
tag = "linear";
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// QuadraticFunction
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
QuadraticFunction::QuadraticFunction(int narg, double* args)
|
||||
: XT_Function(narg,args)
|
||||
{
|
||||
C0 = args[6];
|
||||
C2[0] = args[7];
|
||||
C2[1] = args[8];
|
||||
C2[2] = args[9];
|
||||
C2[3] = args[10];
|
||||
C2[4] = args[11];
|
||||
C2[5] = args[12];
|
||||
tag = "quadratic";
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// SineFunction
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
SineFunction::SineFunction(int narg, double* args)
|
||||
: XT_Function(narg,args)
|
||||
{
|
||||
C = args[6];
|
||||
w = args[7];
|
||||
tag = "sine";
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// GaussianFunction
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
GaussianFunction::GaussianFunction(int narg, double* args)
|
||||
: XT_Function(narg,args)
|
||||
{
|
||||
tau = args[6];
|
||||
C = args[7];
|
||||
C0 = args[8];
|
||||
tag = "gaussian";
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// GaussianTemporalRamp
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
GaussianTemporalRamp::GaussianTemporalRamp(int narg, double* args)
|
||||
: GaussianFunction(narg,args)
|
||||
{
|
||||
tau_initial = args[9];
|
||||
C_initial = args[10];
|
||||
C0_initial = args[11];
|
||||
double delta_t = args[12];
|
||||
|
||||
tau_slope = (tau - tau_initial)/delta_t;
|
||||
C_slope = (C - C_initial)/delta_t;
|
||||
C0_slope = (C0 - C0_initial)/delta_t;
|
||||
|
||||
tag = "gaussian_temporal_ramp";
|
||||
}
|
||||
double GaussianTemporalRamp::f(double* x, double t) {
|
||||
tau = tau_initial + tau_slope*t;
|
||||
C = C_initial + C_slope*t;
|
||||
C0 = C0_initial + C0_slope*t;
|
||||
return GaussianFunction::f(x,t);
|
||||
}
|
||||
double GaussianTemporalRamp::dfdt(double* x, double t) {
|
||||
tau = tau_initial + tau_slope*t;
|
||||
C = C_initial + C_slope*t;
|
||||
C0 = C0_initial + C0_slope*t;
|
||||
double dfdt = 0.;
|
||||
dfdt += C_slope*exp(-(mask[0]*(x[0]-x0[0])*(x[0]-x0[0])
|
||||
+mask[1]*(x[1]-x0[1])*(x[1]-x0[1])
|
||||
+mask[2]*(x[2]-x0[2])*(x[2]-x0[2]))
|
||||
/tau/tau);
|
||||
dfdt += C*exp(2.*tau_slope*(mask[0]*(x[0]-x0[0])*(x[0]-x0[0])
|
||||
+mask[1]*(x[1]-x0[1])*(x[1]-x0[1])
|
||||
+mask[2]*(x[2]-x0[2])*(x[2]-x0[2]))
|
||||
/tau/tau/tau);
|
||||
dfdt += C0_slope;
|
||||
return dfdt;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// TemporalRamp
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
TemporalRamp::TemporalRamp(int narg, double* args)
|
||||
: XT_Function(narg,args)
|
||||
{
|
||||
f_initial = args[0];
|
||||
double f_final = args[1];
|
||||
double delta_t = args[2];
|
||||
slope = (f_final - f_initial)/delta_t;
|
||||
tag = "temporal_ramp";
|
||||
}
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
#ifndef XT_FUNCTION_H
|
||||
#define XT_FUNCTION_H
|
||||
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ATC {
|
||||
//------------------------------------------------------------------------
|
||||
// base class
|
||||
//------------------------------------------------------------------------
|
||||
class XT_Function {
|
||||
public:
|
||||
XT_Function(int nargs, double* args);
|
||||
~XT_Function(void) {};
|
||||
|
||||
const string & get_tag() { return tag;}
|
||||
|
||||
/** function value */
|
||||
virtual inline double f(double* x, double t) {return 0.0;};
|
||||
/** time derivative of function */
|
||||
virtual inline double dfdt(double* x, double t) {return 0.0;};
|
||||
/** 2nd time derivative of funtion */
|
||||
virtual inline double ddfdt(double* x, double t) {return 0.0;};
|
||||
/** 3rd time derivative of funtion */
|
||||
virtual inline double dddfdt(double* x, double t) {return 0.0;};
|
||||
|
||||
protected:
|
||||
/** mask : masks x,y,z dependence, x0 : origin */
|
||||
double mask[3], x0[3];
|
||||
/** tag : name of function */
|
||||
string tag;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// manager
|
||||
//------------------------------------------------------------------------
|
||||
class XT_Function_Mgr {
|
||||
public:
|
||||
/** Static instance of this class */
|
||||
static XT_Function_Mgr * instance();
|
||||
|
||||
XT_Function* get_function(string & type, int nargs, double * arg);
|
||||
XT_Function* get_function(char ** arg, int nargs);
|
||||
XT_Function* get_constant_function(double c);
|
||||
XT_Function* copy_XT_function(XT_Function* other);
|
||||
protected:
|
||||
XT_Function_Mgr() {};
|
||||
~XT_Function_Mgr();
|
||||
/** Vector of ptrs to functions created thus far */
|
||||
std::vector<XT_Function *> xtFunctionVec_;
|
||||
private:
|
||||
static XT_Function_Mgr * myInstance_;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// derived classes
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/** a constant */
|
||||
class ConstantFunction : public XT_Function {
|
||||
public:
|
||||
ConstantFunction(int nargs, double* args);
|
||||
~ConstantFunction(void) {};
|
||||
|
||||
inline double f(double* x, double t)
|
||||
{return C0;};
|
||||
|
||||
private :
|
||||
double C0;
|
||||
};
|
||||
|
||||
/** a linear in x-y-z */
|
||||
class LinearFunction : public XT_Function {
|
||||
public:
|
||||
LinearFunction(int nargs, double* args);
|
||||
~LinearFunction(void) {};
|
||||
|
||||
inline double f(double* x, double t)
|
||||
{return mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;};
|
||||
|
||||
private :
|
||||
double C0;
|
||||
};
|
||||
|
||||
/** a quadratic in x-y-z */
|
||||
class QuadraticFunction : public XT_Function {
|
||||
public:
|
||||
QuadraticFunction(int nargs, double* args);
|
||||
~QuadraticFunction(void) {};
|
||||
|
||||
inline double f(double* x, double t)
|
||||
{return
|
||||
C2[0]*(x[0]-x0[0])*(x[0]-x0[0])+
|
||||
C2[1]*(x[1]-x0[1])*(x[1]-x0[1])+
|
||||
C2[2]*(x[2]-x0[2])*(x[2]-x0[2])+
|
||||
2.0*C2[3]*(x[0]-x0[0])*(x[1]-x0[1]) +
|
||||
2.0*C2[4]*(x[0]-x0[0])*(x[2]-x0[2]) +
|
||||
2.0*C2[5]*(x[1]-x0[1])*(x[2]-x0[2]) +
|
||||
mask[0]*(x[0]-x0[0])+mask[1]*(x[1]-x0[1])+mask[2]*(x[2]-x0[2]) + C0;};
|
||||
|
||||
private :
|
||||
double C0, C2[6]; // C2 1:xx 2:yy 3:zz 4:xy|yx 5:xz|zx 6:yz|zy
|
||||
};
|
||||
|
||||
class SineFunction : public XT_Function {
|
||||
public:
|
||||
SineFunction(int nargs, double* args);
|
||||
~SineFunction(void);
|
||||
|
||||
inline double f(double* x, double t)
|
||||
{return C*sin( mask[0]*(x[0]-x0[0])
|
||||
+mask[1]*(x[1]-x0[1])
|
||||
+mask[2]*(x[2]-x0[2]) - w*t);};
|
||||
|
||||
private :
|
||||
double C, w;
|
||||
};
|
||||
|
||||
/** a spatial gaussian function */
|
||||
class GaussianFunction : public XT_Function {
|
||||
public:
|
||||
GaussianFunction(int nargs, double* args);
|
||||
~GaussianFunction(void){};
|
||||
|
||||
// 1/(2 pi \sigma)^(n/2) exp(-1/2 x.x/\sigma^2 ) for n = dimension
|
||||
inline double f(double* x, double t)
|
||||
{return C*exp(-(mask[0]*(x[0]-x0[0])*(x[0]-x0[0])
|
||||
+mask[1]*(x[1]-x0[1])*(x[1]-x0[1])
|
||||
+mask[2]*(x[2]-x0[2])*(x[2]-x0[2]))/tau/tau) + C0;};
|
||||
|
||||
protected:
|
||||
double tau, C, C0;
|
||||
};
|
||||
|
||||
/** a spatial gaussian function that has variables ramp up in time */
|
||||
class GaussianTemporalRamp : public GaussianFunction {
|
||||
public:
|
||||
GaussianTemporalRamp(int nargs, double* args);
|
||||
~GaussianTemporalRamp(void){};
|
||||
|
||||
double f(double* x, double t);
|
||||
double dfdt(double* x, double t);
|
||||
|
||||
protected:
|
||||
double tau_initial, tau_slope;
|
||||
double C_initial, C_slope;
|
||||
double C0_initial, C0_slope;
|
||||
};
|
||||
|
||||
/** a ramp in time */
|
||||
class TemporalRamp : public XT_Function {
|
||||
public:
|
||||
TemporalRamp(int nargs, double* args);
|
||||
~TemporalRamp(void) {};
|
||||
|
||||
inline double f(double* x, double t)
|
||||
{return f_initial + slope*t;};
|
||||
|
||||
inline double dfdt(double* x, double t)
|
||||
{return slope;};
|
||||
|
||||
private :
|
||||
double f_initial, slope;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,88 @@
|
|||
Deleting atc/ATC_Error.h
|
||||
Deleting atc/ATC_HardyKernel.cpp
|
||||
Deleting atc/ATC_HardyKernel.h
|
||||
Deleting atc/ATC_Transfer.cpp
|
||||
Deleting atc/ATC_Transfer.h
|
||||
Deleting atc/ATC_TransferHardy.cpp
|
||||
Deleting atc/ATC_TransferHardy.h
|
||||
Deleting atc/ATC_TransferThermal.cpp
|
||||
Deleting atc/ATC_TransferThermal.h
|
||||
Deleting atc/ATC_TransferUtility.cpp
|
||||
Deleting atc/ATC_TypeDefs.h
|
||||
Deleting atc/Array.h
|
||||
Deleting atc/Array2D.h
|
||||
Deleting atc/AtomicRegulator.cpp
|
||||
Deleting atc/AtomicRegulator.h
|
||||
Deleting atc/CG.h
|
||||
Deleting atc/CloneVector.h
|
||||
Deleting atc/DenseMatrix.h
|
||||
Deleting atc/DenseVector.h
|
||||
Deleting atc/DiagonalMatrix.h
|
||||
Deleting atc/ElasticTimeIntegrator.cpp
|
||||
Deleting atc/ElasticTimeIntegrator.h
|
||||
Deleting atc/ElectronFlux.cpp
|
||||
Deleting atc/ElectronFlux.h
|
||||
Deleting atc/ElectronHeatCapacity.cpp
|
||||
Deleting atc/ElectronHeatCapacity.h
|
||||
Deleting atc/ElectronHeatFlux.cpp
|
||||
Deleting atc/ElectronHeatFlux.h
|
||||
Deleting atc/ElectronPhononExchange.cpp
|
||||
Deleting atc/ElectronPhononExchange.h
|
||||
Deleting atc/ExtrinsicModel.cpp
|
||||
Deleting atc/ExtrinsicModel.h
|
||||
Deleting atc/ExtrinsicModelTwoTemperature.cpp
|
||||
Deleting atc/ExtrinsicModelTwoTemperature.h
|
||||
Deleting atc/FE_Element.cpp
|
||||
Deleting atc/FE_Element.h
|
||||
Deleting atc/FE_Engine.cpp
|
||||
Deleting atc/FE_Engine.h
|
||||
Deleting atc/FE_Mesh.cpp
|
||||
Deleting atc/FE_Mesh.h
|
||||
Deleting atc/FieldEulerIntegrator.cpp
|
||||
Deleting atc/FieldEulerIntegrator.h
|
||||
Deleting atc/GMRES.h
|
||||
Deleting atc/ImplicitSolveOperator.cpp
|
||||
Deleting atc/ImplicitSolveOperator.h
|
||||
Deleting atc/Kinetostat.cpp
|
||||
Deleting atc/Kinetostat.h
|
||||
Deleting atc/LammpsInterface.cpp
|
||||
Deleting atc/LammpsInterface.h
|
||||
Adding atc/Makefile.lammps
|
||||
Adding atc/Makefile.mpic++
|
||||
Deleting atc/Material.cpp
|
||||
Deleting atc/Material.h
|
||||
Deleting atc/Matrix.cpp
|
||||
Deleting atc/Matrix.h
|
||||
Deleting atc/MatrixDef.h
|
||||
Deleting atc/MatrixLibrary.h
|
||||
Deleting atc/OutputManager.cpp
|
||||
Deleting atc/OutputManager.h
|
||||
Deleting atc/PhysicsModel.h
|
||||
Deleting atc/PhysicsModelThermal.cpp
|
||||
Deleting atc/PhysicsModelThermal.h
|
||||
Deleting atc/PhysicsModelTwoTemperature.cpp
|
||||
Deleting atc/PhysicsModelTwoTemperature.h
|
||||
Deleting atc/PrescribedDataManager.cpp
|
||||
Deleting atc/PrescribedDataManager.h
|
||||
Deleting atc/Quadrature.h
|
||||
Deleting atc/Solver.cpp
|
||||
Deleting atc/Solver.h
|
||||
Deleting atc/SparseMatrix-inl.h
|
||||
Deleting atc/SparseMatrix.h
|
||||
Deleting atc/SparseVector-inl.h
|
||||
Deleting atc/SparseVector.h
|
||||
Deleting atc/StringManip.h
|
||||
Deleting atc/Thermostat.cpp
|
||||
Deleting atc/Thermostat.h
|
||||
Deleting atc/TimeFilter.cpp
|
||||
Deleting atc/TimeFilter.h
|
||||
Deleting atc/TimeIntegrator.cpp
|
||||
Deleting atc/TimeIntegrator.h
|
||||
Deleting atc/Utility.h
|
||||
Deleting atc/Vector.cpp
|
||||
Deleting atc/Vector.h
|
||||
Deleting atc/XT_Function.cpp
|
||||
Deleting atc/XT_Function.h
|
||||
Adding atc/build.log
|
||||
Adding atc/svn.stdout
|
||||
Transmitting file data ...
|
Loading…
Reference in New Issue