Skip to content
Snippets Groups Projects
Commit d3947416 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

block linear solver for dg

parent 58e2ca83
Branches
Tags
No related merge requests found
...@@ -1100,7 +1100,8 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const ...@@ -1100,7 +1100,8 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const
for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){ for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
MVertex *v = *itv; MVertex *v = *itv;
double value = myAssembler.getDofValue(v, 0, 1); double value;
myAssembler.getDofValue(value, v, 0, 1);
std::map<MVertex*,SPoint3>::iterator itf = coordinates.find(v); std::map<MVertex*,SPoint3>::iterator itf = coordinates.find(v);
if(itf == coordinates.end()){ if(itf == coordinates.end()){
SPoint3 p(0, 0, 0); SPoint3 p(0, 0, 0);
...@@ -1348,8 +1349,9 @@ bool GFaceCompound::parametrize_conformal() const ...@@ -1348,8 +1349,9 @@ bool GFaceCompound::parametrize_conformal() const
for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){ for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
MVertex *v = *itv; MVertex *v = *itv;
double value1 = myAssembler.getDofValue(v,0,1); double value1, value2;
double value2 = myAssembler.getDofValue(v,0,2); myAssembler.getDofValue(value1, v,0,1);
myAssembler.getDofValue(value2, v,0,2);
coordinates[v] = SPoint3(value1,value2,0.0); coordinates[v] = SPoint3(value1,value2,0.0);
} }
......
...@@ -371,8 +371,7 @@ void backgroundMesh::propagate1dMesh(GFace *_gf) ...@@ -371,8 +371,7 @@ void backgroundMesh::propagate1dMesh(GFace *_gf)
for ( ; itv2 != _2Dto3D.end(); ++itv2){ for ( ; itv2 != _2Dto3D.end(); ++itv2){
MVertex *v_2D = itv2->first; MVertex *v_2D = itv2->first;
MVertex *v_3D = itv2->second; MVertex *v_3D = itv2->second;
double value = myAssembler.getDofValue(v_3D, 0, 1); myAssembler.getDofValue(_sizes[v_2D], v_3D, 0, 1);
_sizes[v_2D] = value;
} }
delete _lsys; delete _lsys;
#endif #endif
...@@ -473,8 +472,7 @@ void backgroundMesh::updateSizes(GFace *_gf) ...@@ -473,8 +472,7 @@ void backgroundMesh::updateSizes(GFace *_gf)
for ( ; itv2 != _2Dto3D.end(); ++itv2){ for ( ; itv2 != _2Dto3D.end(); ++itv2){
MVertex *v_2D = itv2->first; MVertex *v_2D = itv2->first;
MVertex *v_3D = itv2->second; MVertex *v_3D = itv2->second;
double value = myAssembler.getDofValue(v_3D, 0, 1); myAssembler.getDofValue(_sizes[v_2D], v_3D, 0, 1);
_sizes[v_2D] = value;
} }
delete _lsys; delete _lsys;
#endif #endif
......
...@@ -599,8 +599,9 @@ double highOrderSmoother::smooth_metric_(std::vector<MElement*> & v, ...@@ -599,8 +599,9 @@ double highOrderSmoother::smooth_metric_(std::vector<MElement*> & v,
if ((*it)->onWhat()->dim() == 2){ if ((*it)->onWhat()->dim() == 2){
SPoint2 param; SPoint2 param;
reparamMeshVertexOnFace((*it), gf, param); reparamMeshVertexOnFace((*it), gf, param);
SPoint2 dparam (myAssembler.getDofValue((*it), 0, getTag()), SPoint2 dparam;
myAssembler.getDofValue((*it), 1, getTag())); myAssembler.getDofValue(dparam[0], (*it), 0, getTag());
myAssembler.getDofValue(dparam[1], (*it), 1, getTag());
SPoint2 newp = param+dparam; SPoint2 newp = param+dparam;
dx += newp.x() * newp.x() + newp.y() * newp.y(); dx += newp.x() * newp.x() + newp.y() * newp.y();
(*it)->setParameter(0, newp.x()); (*it)->setParameter(0, newp.x());
...@@ -715,9 +716,13 @@ void highOrderSmoother::smooth(std::vector<MElement*> &all) ...@@ -715,9 +716,13 @@ void highOrderSmoother::smooth(std::vector<MElement*> &all)
} }
for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){ for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
it->first->x() += myAssembler.getDofValue(it->first, 0, getTag()); double ax, ay, az;
it->first->y() += myAssembler.getDofValue(it->first, 1, getTag()); myAssembler.getDofValue(ax, it->first, 0, getTag());
it->first->z() += myAssembler.getDofValue(it->first, 2, getTag()); myAssembler.getDofValue(ay, it->first, 1, getTag());
myAssembler.getDofValue(az, it->first, 2, getTag());
it->first->x() += ax;
it->first->y() += ay;
it->first->z() += az;
} }
// delete matrices and vectors // delete matrices and vectors
......
...@@ -63,6 +63,8 @@ class fullVector ...@@ -63,6 +63,8 @@ class fullVector
{ {
if(s == 0.) if(s == 0.)
for(int i = 0; i < _r; ++i) _data[i] = 0.; for(int i = 0; i < _r; ++i) _data[i] = 0.;
else if (s == -1.)
for(int i = 0; i < _r; ++i) _data[i] = -_data[i];
else else
for(int i = 0; i < _r; ++i) _data[i] *= s; for(int i = 0; i < _r; ++i) _data[i] *= s;
} }
......
...@@ -188,7 +188,9 @@ PView *GMSH_DistancePlugin::execute(PView *v) ...@@ -188,7 +188,9 @@ PView *GMSH_DistancePlugin::execute(PView *v)
for(std::map<MVertex*,double >::iterator itv = distance_map2.begin(); for(std::map<MVertex*,double >::iterator itv = distance_map2.begin();
itv !=distance_map2.end() ; ++itv){ itv !=distance_map2.end() ; ++itv){
MVertex *v = itv->first; MVertex *v = itv->first;
double value = std::min(0.9999, myAssembler.getDofValue(v, 0, 1)); double value;
myAssembler.getDofValue(value, v, 0, 1);
value = std::min(0.9999, value);
double dist = -mu * log(1. - value); double dist = -mu * log(1. - value);
itv->second = dist; itv->second = dist;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
set(SRC set(SRC
linearSystem.cpp linearSystem.cpp
linearSystemCSR.cpp linearSystemCSR.cpp
linearSystemPETSc.cpp
groupOfElements.cpp groupOfElements.cpp
elasticityTerm.cpp elasticityTerm.cpp
elasticitySolver.cpp elasticitySolver.cpp
......
...@@ -48,12 +48,18 @@ template<class T> struct dofTraits ...@@ -48,12 +48,18 @@ template<class T> struct dofTraits
{ {
typedef T VecType; typedef T VecType;
typedef T MatType; typedef T MatType;
inline static void mult (VecType &r, const MatType &m, const VecType &v) { r = m*v;}
inline static void neg (VecType &r) { r = -r;}
inline static void setToZero (VecType &r) { r = 0;}
}; };
template<class T> struct dofTraits<fullVector<T> > template<class T> struct dofTraits<fullMatrix<T> >
{ {
typedef fullVector<T> VecType; typedef fullMatrix<T> VecType;
typedef fullMatrix<T> MatType; typedef fullMatrix<T> MatType;
inline static void mult (VecType &r, const MatType &m, const VecType &v) { m.mult(v, r);}
inline static void neg (VecType &r) { r.scale(-1.);}
inline static void setToZero (VecType &r) { r.scale(0);}
}; };
/* /*
template<> struct dofTraits<fullVector<std::complex<double> > > template<> struct dofTraits<fullVector<std::complex<double> > >
...@@ -159,24 +165,30 @@ class dofManager{ ...@@ -159,24 +165,30 @@ class dofManager{
return dataVec(0.0); return dataVec(0.0);
} }
inline dataVec getDofValue(int ent, int type) const inline void getDofValue(dataVec &v, int ent, int type) const
{ {
Dof key(ent, type); Dof key(ent, type);
{ {
typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key); typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key);
if (it != fixed.end()) return it->second; if (it != fixed.end()){
v = it->second;
return;
}
} }
{ {
std::map<Dof, int>::const_iterator it = unknown.find(key); std::map<Dof, int>::const_iterator it = unknown.find(key);
if (it != unknown.end()) if (it != unknown.end()){
return _current->getFromSolution(it->second); v = _current->getFromSolution(it->second);
return;
} }
return dataVec(0.0);
} }
inline dataVec getDofValue(MVertex *v, int iComp, int iField) const dofTraits<T>::setToZero(v);
}
inline dataVec getDofValue(dataVec &value, MVertex *v, int iComp, int iField) const
{ {
return getDofValue(v->getNum(), Dof::createTypeWithTwoInts(iComp, iField)); getDofValue(value, v->getNum(), Dof::createTypeWithTwoInts(iComp, iField));
} }
inline void assemble(const Dof &R, const Dof &C, const dataMat &value) inline void assemble(const Dof &R, const Dof &C, const dataMat &value)
{ {
if (!_current->isAllocated()) _current->allocate(unknown.size()); if (!_current->isAllocated()) _current->allocate(unknown.size());
...@@ -190,7 +202,11 @@ class dofManager{ ...@@ -190,7 +202,11 @@ class dofManager{
else{ else{
typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C); typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C);
if (itFixed != fixed.end()) { if (itFixed != fixed.end()) {
_current->addToRightHandSide(itR->second, -value * itFixed->second); // tmp = -value * itFixed->second
dataVec tmp(itFixed->second);
dofTraits<T>::mult(tmp , value, itFixed->second);
dofTraits<T>::neg(tmp);
_current->addToRightHandSide(itR->second, tmp);
} }
} }
} }
...@@ -220,7 +236,11 @@ class dofManager{ ...@@ -220,7 +236,11 @@ class dofManager{
else{ else{
typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C[j]); typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C[j]);
if (itFixed != fixed.end()){ if (itFixed != fixed.end()){
_current->addToRightHandSide(NR[i], -m(i,j) * itFixed->second); // tmp = -m(i,j) * itFixed->second
dataVec tmp(itFixed->second);
dofTraits<T>::mult(tmp , m(i,j), itFixed->second);
dofTraits<T>::neg(tmp);
_current->addToRightHandSide(NR[i], tmp);
} }
} }
} }
...@@ -272,7 +292,11 @@ class dofManager{ ...@@ -272,7 +292,11 @@ class dofManager{
{ {
typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(R[j]); typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(R[j]);
if (itFixed != fixed.end()){ if (itFixed != fixed.end()){
_current->addToRightHandSide(NR[i], -m(i, j) * itFixed->second); // tmp = -m(i,j) * itFixed->second
dataVec tmp(itFixed->second);
dofTraits<T>::mult(tmp , m(i,j), itFixed->second);
dofTraits<T>::neg(tmp);
_current->addToRightHandSide(NR[i], tmp);
} }
} }
} }
...@@ -336,5 +360,4 @@ class dofManager{ ...@@ -336,5 +360,4 @@ class dofManager{
return 0; return 0;
} }
}; };
#endif #endif
...@@ -225,9 +225,9 @@ static double vonMises(dofManager<double> *a, MElement *e, ...@@ -225,9 +225,9 @@ static double vonMises(dofManager<double> *a, MElement *e,
double valy[256]; double valy[256];
double valz[256]; double valz[256];
for (int k = 0; k < e->getNumVertices(); k++){ for (int k = 0; k < e->getNumVertices(); k++){
valx[k] = a->getDofValue(e->getVertex(k), 0, _tag); a->getDofValue(valx[k], e->getVertex(k), 0, _tag);
valy[k] = a->getDofValue(e->getVertex(k), 1, _tag); a->getDofValue(valy[k], e->getVertex(k), 1, _tag);
valz[k] = a->getDofValue(e->getVertex(k), 2, _tag); a->getDofValue(valz[k], e->getVertex(k), 2, _tag);
} }
double gradux[3]; double gradux[3];
double graduy[3]; double graduy[3];
......
...@@ -447,7 +447,7 @@ void function::registerBindings(binding *b){ ...@@ -447,7 +447,7 @@ void function::registerBindings(binding *b){
mb->setDescription("return the unique instance of this class"); mb->setDescription("return the unique instance of this class");
cb->setParentClass<function>(); cb->setParentClass<function>();
cb = b->addClass<functionSolution>("functionNormals"); cb = b->addClass<functionNormals>("functionNormals");
cb->setDescription("A function to access the face normals. This is a single-instance class, use the 'get' member to access the instance."); cb->setDescription("A function to access the face normals. This is a single-instance class, use the 'get' member to access the instance.");
mb = cb->addMethod("get",&functionNormals::get); mb = cb->addMethod("get",&functionNormals::get);
mb->setDescription("return the unique instance of this class"); mb->setDescription("return the unique instance of this class");
......
...@@ -28,19 +28,13 @@ void linearSystem<double>::registerBindings(binding *b){ ...@@ -28,19 +28,13 @@ void linearSystem<double>::registerBindings(binding *b){
cb->setParentClass<linearSystem<double> >(); cb->setParentClass<linearSystem<double> >();
#endif #endif
#ifdef HAVE_PETSC
cb = b->addClass<linearSystemPETSc<double> >("linearSystemPETSc");
cb->setDescription("A linear system solver, based on PETSc");
cm = cb->setConstructor<linearSystemPETSc<double> >();
cm->setDescription ("A new PETSc<double> solver");
cm->setArgNames(NULL);
cb->setParentClass<linearSystem<double> >();
#endif
cb = b->addClass<linearSystemFull<double> >("linearSystemFull"); cb = b->addClass<linearSystemFull<double> >("linearSystemFull");
cb->setDescription("A linear system solver, based on LAPACK (full matrices)"); cb->setDescription("A linear system solver, based on LAPACK (full matrices)");
cm = cb->setConstructor<linearSystemFull<double> >(); cm = cb->setConstructor<linearSystemFull<double> >();
cm->setDescription ("A new Lapack based <double> solver"); cm->setDescription ("A new Lapack based <double> solver");
cm->setArgNames(NULL); cm->setArgNames(NULL);
cb->setParentClass<linearSystem<double> >(); cb->setParentClass<linearSystem<double> >();
#ifdef HAVE_PETSC
linearSystemPETScRegisterBindings (b);
#endif
} }
#include "GmshConfig.h"
#if defined HAVE_PETSC
#include "linearSystemPETSc.h"
#include "fullMatrix.h"
template <>
void linearSystemPETSc<fullMatrix<double> >::addToMatrix(int row, int col, fullMatrix<double> val)
{
for (int ii = 0; ii<val.size1(); ii++)
for (int jj = 0; jj < ii; jj ++) {
double buff = val(ii,jj);
val(ii,jj) = val (jj,ii);
val(jj,ii) = buff;
}
PetscInt i = row, j = col;
_try(MatSetValuesBlocked(_a, 1, &i, 1, &j, &val(0,0), ADD_VALUES));
}
template<>
void linearSystemPETSc<fullMatrix<double> >::addToRightHandSide(int row, fullMatrix<double> val)
{
for (int ii = 0; ii < _blockSize; ii ++) {
PetscInt i = row * _blockSize + ii;
_try(VecSetValues(_b, 1, &i, &val(ii,0), ADD_VALUES));
}
}
template<>
fullMatrix<double> linearSystemPETSc<fullMatrix<double> >::getFromMatrix(int row, int col) const
{
Msg::Error("getFromMatrix not implemented for PETSc");
return fullMatrix<double>(0,0);
}
template<>
fullMatrix<double> linearSystemPETSc<fullMatrix<double> >::getFromRightHandSide(int row) const
{
fullMatrix<double> val(_blockSize,1);
PetscScalar *tmp;
_try(VecGetArray(_b, &tmp));
for (int i=0; i<_blockSize; i++) {
PetscScalar s = tmp[row*_blockSize+i];
#if defined(PETSC_USE_COMPLEX)
val(i,0) = s.real();
#else
val(i,0) = s;
#endif
}
_try(VecRestoreArray(_b, &tmp));
return val;
}
template<>
fullMatrix<double> linearSystemPETSc<fullMatrix<double> >::getFromSolution(int row) const
{
fullMatrix<double> val(_blockSize,1);
PetscScalar *tmp;
_try(VecGetArray(_x, &tmp));
for (int i=0; i<_blockSize; i++) {
PetscScalar s = tmp[row*_blockSize+i];
#if defined(PETSC_USE_COMPLEX)
val(i,0) = s.real();
#else
val(i,0) = s;
#endif
}
_try(VecRestoreArray(_x, &tmp));
return val;
}
template<>
void linearSystemPETSc<fullMatrix<double> >::allocate(int nbRows) {
clear();
_try(MatCreate(PETSC_COMM_WORLD, &_a));
_try(MatSetSizes(_a, PETSC_DECIDE, PETSC_DECIDE, nbRows*_blockSize, nbRows*_blockSize));
_try(MatSetType(_a, MATSEQBAIJ));
// override the default options with the ones from the option
// database (if any)
_try(MatSetFromOptions(_a));
_try(MatSeqBAIJSetPreallocation(_a, _blockSize, 4, NULL)); //todo preAllocate off-diagonal part
//_try(MatMPIBAIJSetPreallocation(_a, _blockSize, 4, NULL, 0, NULL)); //todo preAllocate off-diagonal part
_try(VecCreate(PETSC_COMM_WORLD, &_x));
_try(VecSetSizes(_x, PETSC_DECIDE, nbRows*_blockSize));
// override the default options with the ones from the option
// database (if any)
_try(VecSetFromOptions(_x));
_try(VecDuplicate(_x, &_b));
_isAllocated = true;
}
#include "Bindings.h"
void linearSystemPETScRegisterBindings(binding *b) {
classBinding *cb;
methodBinding *cm;
cb = b->addClass<linearSystemPETSc<double> >("linearSystemPETSc");
cb->setDescription("A linear system solver, based on PETSc");
cm = cb->setConstructor<linearSystemPETSc<double> >();
cm->setDescription ("A new PETSc<double> solver");
cb->setParentClass<linearSystem<double> >();
cm->setArgNames(NULL);
cm = cb->addMethod("systemSolve", &linearSystem<fullMatrix<double> >::systemSolve);
cm->setDescription("compute x = A^{-1}b");
cb = b->addClass<linearSystemPETSc<fullMatrix<double> > >("linearSystemPETScBlock");
cb->setDescription("A linear system solver, based on PETSc");
cm = cb->setConstructor<linearSystemPETSc<fullMatrix<double> >, int>();
cm->setDescription ("A new PETScBlock<double> solver (we probably should get rid of the blockSize argument)");
cm->setArgNames("blockSize", NULL);
cm = cb->addMethod("systemSolve", &linearSystem<fullMatrix<double> >::systemSolve);
cm->setDescription("compute x = A^{-1}b");
}
#endif // HAVE_PETSC
...@@ -44,13 +44,13 @@ ...@@ -44,13 +44,13 @@
template <class scalar> template <class scalar>
class linearSystemPETSc : public linearSystem<scalar> { class linearSystemPETSc : public linearSystem<scalar> {
private: int _blockSize; // for block Matrix
bool _isAllocated; bool _isAllocated;
Mat _a; Mat _a;
Vec _b, _x; Vec _b, _x;
void _try(int ierr) const { CHKERRABORT(PETSC_COMM_WORLD, ierr); } void _try(int ierr) const { CHKERRABORT(PETSC_COMM_WORLD, ierr); }
public: public:
linearSystemPETSc() : _isAllocated(false) {} linearSystemPETSc(int blockSize = -1) : _isAllocated(false) {_blockSize = blockSize;}
virtual ~linearSystemPETSc(){ clear(); } virtual ~linearSystemPETSc(){ clear(); }
virtual bool isAllocated() const { return _isAllocated; } virtual bool isAllocated() const { return _isAllocated; }
virtual void allocate(int nbRows) virtual void allocate(int nbRows)
...@@ -83,12 +83,6 @@ class linearSystemPETSc : public linearSystem<scalar> { ...@@ -83,12 +83,6 @@ class linearSystemPETSc : public linearSystem<scalar> {
} }
_isAllocated = false; _isAllocated = false;
} }
virtual void addToMatrix(int row, int col, scalar val)
{
PetscInt i = row, j = col;
PetscScalar s = val;
_try(MatSetValues(_a, 1, &i, 1, &j, &s, ADD_VALUES));
}
virtual scalar getFromMatrix(int row, int col) const virtual scalar getFromMatrix(int row, int col) const
{ {
Msg::Error("getFromMatrix not implemented for PETSc"); Msg::Error("getFromMatrix not implemented for PETSc");
...@@ -113,6 +107,12 @@ class linearSystemPETSc : public linearSystem<scalar> { ...@@ -113,6 +107,12 @@ class linearSystemPETSc : public linearSystem<scalar> {
return s; return s;
#endif #endif
} }
virtual void addToMatrix(int row, int col, scalar val)
{
PetscInt i = row, j = col;
PetscScalar s = val;
_try(MatSetValues(_a, 1, &i, 1, &j, &s, ADD_VALUES));
}
virtual scalar getFromSolution(int row) const virtual scalar getFromSolution(int row) const
{ {
PetscScalar *tmp; PetscScalar *tmp;
...@@ -152,6 +152,9 @@ class linearSystemPETSc : public linearSystem<scalar> { ...@@ -152,6 +152,9 @@ class linearSystemPETSc : public linearSystem<scalar> {
// override the default options with the ones from the option // override the default options with the ones from the option
// database (if any) // database (if any)
_try(KSPSetFromOptions(ksp)); _try(KSPSetFromOptions(ksp));
PetscViewer view;
PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.out", &view);
_try(MatView(_a, view));
_try(KSPSolve(ksp, _b, _x)); _try(KSPSolve(ksp, _b, _x));
_try(KSPView(ksp, PETSC_VIEWER_STDOUT_SELF)); _try(KSPView(ksp, PETSC_VIEWER_STDOUT_SELF));
PetscInt its; PetscInt its;
...@@ -161,6 +164,10 @@ class linearSystemPETSc : public linearSystem<scalar> { ...@@ -161,6 +164,10 @@ class linearSystemPETSc : public linearSystem<scalar> {
Mat &getMatrix(){ return _a; } Mat &getMatrix(){ return _a; }
}; };
class binding;
void linearSystemPETScRegisterBindings(binding *b);
#else #else
template <class scalar> template <class scalar>
......
...@@ -1199,7 +1199,8 @@ void multiscaleLaplace::parametrize_method (multiscaleLaplaceLevel & level, ...@@ -1199,7 +1199,8 @@ void multiscaleLaplace::parametrize_method (multiscaleLaplaceLevel & level,
int count = 0; int count = 0;
for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){ for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
MVertex *v = *itv; MVertex *v = *itv;
double value = myAssembler.getDofValue(v, 0, 1); double value;
myAssembler.getDofValue(value, v, 0, 1);
if (step == 0)solution[v] = SPoint2(value,0); if (step == 0)solution[v] = SPoint2(value,0);
else solution[v] = SPoint2(solution[v][0],value); else solution[v] = SPoint2(solution[v][0],value);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment