Skip to content
Snippets Groups Projects
Commit 5695b4dd authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

correction of ellipt demo

parent 6374f084
No related branches found
No related tags found
No related merge requests found
#include "AMDiS.h" #include "AMDiS.h"
#include "ProblemStatDbg.h"
#include "Debug.h"
using namespace AMDiS; using namespace AMDiS;
using namespace std; using namespace std;
...@@ -9,284 +7,6 @@ using namespace std; ...@@ -9,284 +7,6 @@ using namespace std;
// ===== function definitions ================================================ // ===== function definitions ================================================
// =========================================================================== // ===========================================================================
class MyProblemVec : public ProblemStatDbg
{
public:
MyProblemVec(std::string nameStr, ProblemIterationInterface *problemIteration = NULL)
: ProblemStatDbg(nameStr,problemIteration) {}
SolverMatrix<Matrix<DOFMatrix*> >* getSolverMatrix() { return &solverMatrix; }
void setSolverMatrix(SolverMatrix<Matrix<DOFMatrix*> >& solverMatrix_) { solverMatrix= solverMatrix_; }
inline DOFVector<double>* getRhsVector(int i = 0)
{
return rhs->getDOFVector(i);
}
};
class MyIteration : public StandardProblemIteration
{
public:
MyIteration(MyProblemVec *prob_) : StandardProblemIteration(prob_), prob(prob_) {}
~MyIteration() {}
Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION)
{ FUNCNAME("PIteration::oneIteration()");
Flag flag, markFlag;
if (toDo.isSet(MARK))
markFlag = prob->markElements(adaptInfo);
else
markFlag = 3;
// refine
if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_REFINED))
flag= prob->refineMesh(adaptInfo);
// coarsen
if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_COARSENED))
flag|= prob->coarsenMesh(adaptInfo);
if (toDo.isSet(SOLVE)) {
prob->buildAfterCoarsen(adaptInfo, markFlag, true, true);
MSG("apply Dirichlet BC...\n");
bool inside= false;
WorldVector<double> p1;
p1[0]= 1.0;
p1[1]= -1.0;
for (int i= 0; i<prob->getSolution()->getSize(); ++i) {
DegreeOfFreedom idx1= getDOFidxAtCoords(prob->getSolution()->getDOFVector(i), p1, inside);
if(inside) {
MSG("set DBC to row %d...\n",idx1);
applyDbc(prob->getSystemMatrix(i,i)->getBaseMatrix(), *prob->getRhsVector(i), idx1, 0.0);
} else {
MSG("idx not found!!!\n");
}
}
// prob->writeDbgMatrix("ellipt_mat.dat");
// applySingularPertubation(prob->getSystemMatrix(0,0)->getBaseMatrix());
// applySingularDBC(prob->getSystemMatrix(0,0)->getBaseMatrix());
SolverMatrix<Matrix<DOFMatrix*> > solverMatrix;
solverMatrix.setMatrix(*prob->getSystemMatrix());
prob->setSolverMatrix(solverMatrix);
debug::writeMatlabMatrix(*(prob->getSystemMatrix()), "ellipt_mat.m");
prob->solve(adaptInfo, false);
}
if (toDo.isSet(ESTIMATE)) {
prob->estimate(adaptInfo);
}
return flag;
};
template <typename Matrix>
void applySingularPertubation(Matrix& m)
{
using namespace mtl;
// Type of m's elements
typedef typename mtl::Collection<Matrix>::value_type value_type;
int nnz= m.nnz_local(m.num_rows()-1);
// Create inserter for matrix m
// Existing values are not overwritten but inserted
matrix::inserter<Matrix, update_times<value_type> > ins(m, nnz);
ins[m.num_rows()-1][m.num_rows()-1] << 1.0+1.e-5;
}
template <typename Matrix>
void applySingularDBC(Matrix& m)
{
using namespace mtl;
typename traits::row<Matrix>::type r(m);
typename traits::col<Matrix>::type c(m);
typename traits::value<Matrix>::type v(m);
typedef typename traits::range_generator<tag::row, Matrix>::type c_type;
typedef typename traits::range_generator<tag::nz, c_type>::type ic_type;
// typedef typename Collection<Matrix>::value_type value_type;
for (c_type cursor(begin<tag::row>(m)), cend(end<tag::row>(m)); cursor != cend; ++cursor) {
for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
v(*icursor, (r(*icursor)==c(*icursor)?1.0:0.0));
}
break;
}
}
template <typename Matrix, typename Vector>
void applyDbc(Matrix& m, Vector& vec, DegreeOfFreedom idx, double value)
{
using namespace mtl;
typename Matrix::size_type idx_= idx;
typename traits::row<Matrix>::type r(m);
typename traits::col<Matrix>::type c(m);
typename traits::value<Matrix>::type v(m);
typedef typename traits::range_generator<tag::row, Matrix>::type c_type;
typedef typename traits::range_generator<tag::nz, c_type>::type ic_type;
// typedef typename Collection<Matrix>::value_type value_type;
for (c_type cursor(begin<tag::row>(m)+idx_), cend(begin<tag::row>(m)+idx_+1); cursor != cend; ++cursor) {
for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
v(*icursor, (r(*icursor)==c(*icursor)?1.0:0.0));
if(r(*icursor)==c(*icursor)) {
MSG("DBC set to (%d, %d)\n", r(*icursor), c(*icursor));
}
}
break;
}
vec[idx]= value;
}
DegreeOfFreedom getDOFidxAtCoords(DOFVector<double> *vec, WorldVector<double> &p, bool &inside, ElInfo *oldElInfo=NULL, bool useOldElInfo=false)
{
const FiniteElemSpace *feSpace = vec->getFeSpace();
Mesh *mesh = vec->getFeSpace()->getMesh();
const BasisFunction *basFcts = feSpace->getBasisFcts();
int dim = mesh->getDim();
int numBasFcts = basFcts->getNumber();
DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
DimVec<double> lambda(dim, NO_INIT);
ElInfo *elInfo = mesh->createNewElInfo();
int dofIdx=0;
inside=false;
if(oldElInfo && useOldElInfo && oldElInfo->getMacroElement()) {
inside=mesh->findElInfoAtPoint(p,elInfo,lambda,oldElInfo->getMacroElement(),NULL,NULL);
delete oldElInfo;
} else {
inside=mesh->findElInfoAtPoint(p,elInfo,lambda,NULL,NULL,NULL);
}
if(oldElInfo) oldElInfo=elInfo;
if(inside) {
basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices);
FixVec<WorldVector<double>, VERTEX> coords = elInfo->getMacroElement()->getCoord();
int minIdx=-1;
double minDist=1.e15;
for(int i=0;i<coords.size();++i) {
WorldVector<double> dist = coords[i]-p;
double newDist = AMDiS::norm(dist);
if(newDist<minDist) {
minIdx=i;
minDist=newDist;
}
}
if(minIdx>=0) {
dofIdx = localIndices[minIdx];
}
}
delete [] localIndices;
if(!oldElInfo) delete elInfo;
return dofIdx;
};
protected:
MyProblemVec *prob;
};
/// < factor*phase*grad(u) , grad(psi) >
class Phase_SOT : public SecondOrderTerm
{
public:
/// Constructor.
Phase_SOT(DOFVectorBase<double>* phaseDV_, double fac_=1.0) :
SecondOrderTerm(6), phaseDV(phaseDV_), fac(fac_)
{
TEST_EXIT(phaseDV_)("no vector phase!\n");
auxFeSpaces.insert(phaseDV_->getFeSpace());
};
void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
Quadrature *quad = NULL) {
getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
};
void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
SubAssembler* subAssembler,
Quadrature *quad = NULL) {
getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
};
inline void getLALt(const ElInfo *elInfo, std::vector<mtl::dense2D<double> > &LALt) const
{
const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
const int nPoints = static_cast<int>(LALt.size());
for (int iq = 0; iq < nPoints; iq++)
l1lt(Lambda, LALt[iq], f(iq) * phase[iq] * fac);
};
inline void eval(int nPoints,
const AMDiS::ElementVector&,
const WorldVector<double> *grdUhAtQP,
const WorldMatrix<double> *D2UhAtQP,
ElementVector& result,
double opFactor)
{
if (D2UhAtQP) {
for (int iq = 0; iq < nPoints; iq++) {
double feval = f(iq) * phase[iq] * opFactor * fac;
double resultQP = 0.0;
for (int i = 0; i < dimOfWorld; i++)
resultQP += D2UhAtQP[iq][i][i];
result[iq] += feval * resultQP;
}
}
};
void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
std::vector<WorldVector<double> > &result)
{
int nPoints = grdUhAtQP.size();
for (int iq = 0; iq < nPoints; iq++) {
double factor = f(iq) * phase[iq] * fac;
axpy(factor, grdUhAtQP[iq], result[iq]);
}
};
virtual double f(const int iq) const
{
return 1.0;
};
void setFactor(const double fac_) { fac=fac_; }
protected:
DOFVectorBase<double> *phaseDV;
mtl::dense_vector<double> phase;
double fac;
};
/// simple circle: phi_0(x,y) := sqrt(x^2+y^2)-r
class Circle : public AbstractFunction<double, WorldVector<double> >
{
public:
Circle(double radius_, WorldVector<double> midPoint_) :
radius(radius_), midPoint(midPoint_) {}
Circle(double radius_) :
radius(radius_) { midPoint.set(0.0); }
double operator()(const WorldVector<double>& x) const
{
double result = 0.0;
for(int k=0; k<x.getSize(); k++) {
result += sqr(x[k]-midPoint[k]);
}
result = sqrt(result)-radius;
return result;
};
private:
double radius;
WorldVector<double> midPoint;
};
/// Dirichlet boundary function /// Dirichlet boundary function
class G : public AbstractFunction<double, WorldVector<double> > class G : public AbstractFunction<double, WorldVector<double> >
{ {
...@@ -295,7 +15,7 @@ public: ...@@ -295,7 +15,7 @@ public:
/// Implementation of AbstractFunction::operator(). /// Implementation of AbstractFunction::operator().
double operator()(const WorldVector<double>& x) const double operator()(const WorldVector<double>& x) const
{ {
return 0.0; return exp(-10.0 * (x * x));
} }
}; };
...@@ -309,7 +29,10 @@ public: ...@@ -309,7 +29,10 @@ public:
/// Implementation of AbstractFunction::operator(). /// Implementation of AbstractFunction::operator().
double operator()(const WorldVector<double>& x) const double operator()(const WorldVector<double>& x) const
{ {
return sin(M_PI*x[0]); int dow = Global::getGeo(WORLD);
double r2 = (x * x);
double ux = exp(-10.0 * r2);
return -(400.0 * r2 - 20.0 * dow) * ux;
} }
}; };
...@@ -325,30 +48,27 @@ int main(int argc, char* argv[]) ...@@ -325,30 +48,27 @@ int main(int argc, char* argv[])
TEST_EXIT(argc >= 2)("usage: ellipt initfile\n"); TEST_EXIT(argc >= 2)("usage: ellipt initfile\n");
// ===== init parameters ===== // ===== init parameters =====
Parameters::init(argv[1]); Parameters::init(argv[1]);
// ===== create and init the scalar problem ===== // ===== create and init the scalar problem =====
MyProblemVec ellipt("ellipt"); ProblemStat ellipt("ellipt");
ellipt.initialize(INIT_ALL); ellipt.initialize(INIT_ALL);
MyIteration elIter(&ellipt);
// === create adapt info === // === create adapt info ===
AdaptInfo adaptInfo("ellipt->adapt", 2); AdaptInfo adaptInfo("ellipt->adapt");
// === create adapt === // === create adapt ===
AdaptStationary adapt("ellipt->adapt", elIter, adaptInfo); AdaptStationary adapt("ellipt->adapt", ellipt, adaptInfo);
// DOFVector<double> phase(ellipt.getFeSpace(), "phase");
// phase.interpol(new Circle(0.25));
// ===== create matrix operator ===== // ===== create matrix operator =====
Operator matrixOperator(ellipt.getFeSpace()); Operator matrixOperator(ellipt.getFeSpace());
matrixOperator.addSecondOrderTerm(new Simple_SOT); matrixOperator.addSecondOrderTerm(new Simple_SOT);
ellipt.addMatrixOperator(matrixOperator, 0, 0); ellipt.addMatrixOperator(matrixOperator, 0, 0);
ellipt.addMatrixOperator(matrixOperator, 1, 1);
// ===== create rhs operator ===== // ===== create rhs operator =====
...@@ -356,12 +76,10 @@ int main(int argc, char* argv[]) ...@@ -356,12 +76,10 @@ int main(int argc, char* argv[])
Operator rhsOperator(ellipt.getFeSpace()); Operator rhsOperator(ellipt.getFeSpace());
rhsOperator.addZeroOrderTerm(new CoordsAtQP_ZOT(new F(degree))); rhsOperator.addZeroOrderTerm(new CoordsAtQP_ZOT(new F(degree)));
ellipt.addVectorOperator(rhsOperator, 0); ellipt.addVectorOperator(rhsOperator, 0);
ellipt.addVectorOperator(rhsOperator, 1);
// ===== add boundary conditions ===== // ===== add boundary conditions =====
ellipt.addDirichletBC(3, 0, 0, new G); ellipt.addDirichletBC(1, 0, 0, new G);
ellipt.addDirichletBC(5, 1, 1, new G);
// ===== start adaption loop ===== // ===== start adaption loop =====
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment