Commit ff13277f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

correction of MeshManipulation

parent d2ebd11b
......@@ -46,9 +46,9 @@ public:
~CouplingBaseProblem() { }
virtual void initialize(Flag initFlag,
ProblemStat *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING)
void initialize(Flag initFlag,
ProblemStatSeq *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING) _OVERRIDE_
{
for (size_t i = 0; i < baseProblems.size(); i++) {
for (size_t j = 0; j < baseProblems[i]->getNumProblems(); j++)
......
......@@ -83,6 +83,8 @@ public:
#define BASEPROBLEM_ARGS(z, n, text) BOOST_PP_COMMA_IF(n) _BaseProblemType ## n &prob ## n
#define BASEPROBLEM_TYPES(z, n, text) class _BaseProblemType ## n
// constructors created by C-Macros for each number of arguments, using BOOST_PP-Macros
#define COUPLED_BASEPROBLEM_CONSTRUCTOR(z, n, text) \
template<BOOST_PP_ENUM(BOOST_PP_INC(n), BASEPROBLEM_TYPES, BaseProblemType)> \
......@@ -110,7 +112,7 @@ public:
~CouplingBaseProblem() { }
void initialize(Flag initFlag,
ProblemStat *adoptProblem = NULL,
ProblemStatSeq *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING) _OVERRIDE_
{
tools::FOR_EACH< detail::AddProblem >::loop2(*this, baseProblems);
......
......@@ -88,9 +88,18 @@ public:
}
~CouplingBaseProblem() { }
/**
* Add the problems to the iterationInterface, timeInterface and couplingProblemStat.
* As a consequence all problem can be initialized one after another and in the
* adaption loop they are solved in rotation.
*
* In the adaption loop the problems are solved the same order as they are added to the
* iterationInterface in this method. This order can be changed manually in the oneIteration
* method.
**/
void initialize(Flag initFlag,
ProblemStat *adoptProblem = NULL,
ProblemStatSeq *adoptProblem = NULL,
Flag adoptFlag = INIT_NOTHING) _OVERRIDE_
{
tools::FOR_EACH< detail::AddProblem >::loop2(*this, baseProblems);
......@@ -106,6 +115,12 @@ public:
virtual void initData() {}
/**
* At first the initData method is called for all baseProblems, then
* the problems are filled with operators and coupling operators as well as
* boundary conditions are added.
**/
virtual void initTimeInterface()
{
tools::FOR_EACH< detail::InitData >::loop(baseProblems);
......
......@@ -28,7 +28,7 @@ public:
typedef BaseProblem_RB BaseProblemType;
typedef CouplingProblemStatImpl<ExtendedRosenbrockStationary> CProblemStat;
CoupledBaseProblem_RB(std::string name_,
CouplingBaseProblem_RB(std::string name_,
BaseProblemType *prob0_,
BaseProblemType *prob1_=NULL,
BaseProblemType *prob2_=NULL,
......@@ -43,11 +43,11 @@ public:
}
}
~CoupledBaseProblem_RB() { }
~CouplingBaseProblem_RB() { }
/// get the j-th stage-solution-vector of the i-th problem
DOFVector<double> *getStageSolution(int i, int j)
{ FUNCNAME("CoupledBaseProblem::getStageSolution(i,j)");
{ FUNCNAME("CouplingBaseProblem_RB::getStageSolution(i,j)");
TEST_EXIT(0<=i && 0<=j && i<baseProblems.size() && j<=baseProblems[i]->getNumComponents())
("Indices out of range!\n");
......@@ -56,7 +56,7 @@ public:
/// get the j-th unVec-vector of the i-th problem
DOFVector<double> *getUnVec(int i, int j=0)
{ FUNCNAME("CoupledBaseProblem::getUnVec(i,j)");
{ FUNCNAME("CouplingBaseProblem_RB::getUnVec(i,j)");
TEST_EXIT(0<=i && 0<=j && i<baseProblems.size() && j<=baseProblems[i]->getNumComponents())
("Indices out of range!\n");
......
......@@ -31,6 +31,7 @@ ch->space->dim: 2
% ================== SOLVER ======================================
ch->space->solver: petsc-ch % umfpack %petsc-ch
ch->space->solver->backend: no
ch->space->solver->use old initial guess: 1
ch->space->solver->symmetric strategy: 0
ch->space->solver->store symbolic: 0
......
......@@ -48,6 +48,7 @@ ns->space->dim: 2
% ================== SOLVER ======================================
ns->space->solver: petsc-navierstokes %umfpack % petsc-navierstokes
ns->space->solver->backend: no
ns->space->solver->navierstokes->use old initial guess: 1
parallel->use zero start vector: 0
ns->space->solver->navierstokes->pressure component: 2
......
......@@ -18,10 +18,14 @@
#ifndef CAHN_HILLIARD_NAVIER_STOKES_H
#define CAHN_HILLIARD_NAVIER_STOKES_H
#include "AMDiS.h"
// coupling structures
#include "CouplingIterationInterface.h"
#include "CouplingTimeInterface.h"
#include "CouplingProblemStat.h"
#if __cplusplus > 199711L
#include "CouplingBaseProblem2_cxx11.h"
#else
#include "CouplingBaseProblem2.h"
#endif
#include "CahnHilliard_.h"
......@@ -33,38 +37,6 @@
using namespace AMDiS;
class ID : public AbstractFunction<double, double>
{
public:
ID()
: AbstractFunction<double, double>(2) {};
double operator()(const double& x) const {
return x;
}
};
class Y : public AbstractFunction<double, WorldVector<double> >
{
public:
Y()
: AbstractFunction<double, WorldVector<double> >(1) {};
double operator()(const WorldVector<double>& x) const {
return x[1];
}
};
/**
* \ingroup Problem
*
......@@ -72,90 +44,87 @@ public:
*/
template<typename CH_Type = CahnHilliard_,
typename NS_Type = NavierStokes_TaylorHood>
class CahnHilliardNavierStokes_ : public CouplingIterationInterface,
public CouplingTimeInterface,
public CouplingProblemStat
class CahnHilliardNavierStokes_ : public CouplingBaseProblem<ProblemStat, CH_Type, NS_Type>
{
public:
typedef CouplingBaseProblem<ProblemStat, CH_Type, NS_Type> super;
public:
CahnHilliardNavierStokes_(std::string name_, CH_Type *chProb_, NS_Type *nsProb_)
: CouplingProblemStat(name_),
: super(name_, *chProb_, *nsProb_),
chProb(chProb_),
nsProb(nsProb_),
refFunction(NULL),
refinement(NULL),
sigma(0.0),
surfaceTension(0.0)
surfaceTension(0.0),
y(NULL),
yc1(NULL),
yc2(NULL)
{
dow = Global::getGeo(WORLD);
Parameters::get(name + "->sigma", sigma);
Parameters::get(super::name + "->sigma", sigma);
surfaceTension = sigma/chProb->getEpsilon() * 3.0/2.0/sqrt(2.0);
}
~CahnHilliardNavierStokes_() {
if (refFunction != NULL)
~CahnHilliardNavierStokes_()
{
if (refFunction) {
delete refFunction;
if (refinement != NULL)
refFunction = NULL;
}
if (refinement) {
delete refinement;
refinement = NULL;
}
if (y) {
delete y;
y = NULL;
}
if (yc1) {
delete yc1;
yc1 = NULL;
}
if (yc2) {
delete yc2;
yc2 = NULL;
}
}
/**
* Add the problems to the iterationInterface, timeInterface and couplingProblemStat.
* As a consequence all problem can be initialized one after another and in the
* adaption loop they are solved in rotation.
* At the end the problems are filled with operators and coupling operators as well as
* boundary conditions are added.
*
* In the adaption loop the problems are solved the same order as they are added to the
* iterationInterface in this method. This order can be changed manually in the oneIteration
* method.
* All needed DOFVectors are initialized so that they can be used inside
* of the operators.
**/
void initialize(AdaptInfo *adaptInfo)
void initData()
{
for (size_t i = 0; i < chProb->getNumProblems(); i++)
addProblem(chProb->getProblem(i));
for (size_t i = 0; i < nsProb->getNumProblems(); i++)
addProblem(nsProb->getProblem(i));
addIterationInterface(chProb);
addIterationInterface(nsProb);
// setSolveProblem("ch",false);
addTimeInterface(chProb);
addTimeInterface(nsProb);
CouplingProblemStat::initialize(INIT_ALL);
dim = getMesh()->getDim();
fillCouplingOperators();
// fillOperators and fillBoundaryConditions for chProb and nsProb
nsProb->initTimeInterface();
chProb->initTimeInterface();
y = new DOFVector<double>(chProb->getFeSpace(0), "volume");
yc1 = new DOFVector<double>(chProb->getFeSpace(0), "volume");
yc2 = new DOFVector<double>(chProb->getFeSpace(0), "volume");
output = fopen( "output_data", "w" );
fprintf(output, "time u_b center_old\n");
fclose(output);
u_b=0;
// fillCouplingBoundaryConditions();
}
Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo)
{ FUNCNAME("CouplingIterationInterface::oneIteration()");
Flag flag = CouplingIterationInterface::oneIteration(adaptInfo, toDo);
u_b = 0;
//chProb->solveInitialProblem(adaptInfo);
return flag;
};
// meshFunction for k local refinement around the interface of the phasefield-DOFVector
refFunction = new PhaseFieldRefinement(chProb->getMesh());
if (chProb->getDoubleWellType() == 0) {
refinement = new RefinementLevelDOF(
chProb->getFeSpace(),
refFunction,
chProb->getSolution()->getDOFVector(1)); // phaseField-DOFVector in [0,1]
} else {
refinement = new RefinementLevelDOF(
chProb->getFeSpace(),
refFunction,
new PhaseDOFView<double>(chProb->getSolution()->getDOFVector(1))); // phaseField-DOFVector in [-1,1]
}
}
/**
......@@ -166,18 +135,21 @@ public:
void fillCouplingOperators()
{ FUNCNAME("CahnHilliardNavierStokes::fillCouplingOperators()");
MSG("CahnHilliardNavierStokes::fillCouplingOperators()");
int degree = nsProb->getFeSpace(0)->getBasisFcts()->getDegree();
for (size_t i = 0; i < dow; i++) {
for (size_t i = 0; i < super::dow; i++) {
// < nu * d_i(c) , theta >
Operator *opNuGradC = new Operator(nsProb->getFeSpace(i), chProb->getFeSpace(0));
opNuGradC->addTerm(new VecAndPartialDerivative_ZOT(chProb->getSolution()->getDOFVector(0), chProb->getSolution()->getDOFVector(1), i));
opNuGradC->addTerm(new VecAndPartialDerivative_ZOT(chProb->getSolution()->getDOFVector(0),
chProb->getSolution()->getDOFVector(1), i));
nsProb->getProblem(0)->addVectorOperator(opNuGradC, i, &surfaceTension, &surfaceTension);
}
for (size_t i = 0; i < dow; i++) {
for (size_t i = 0; i < super::dow; i++) {
// < v * grad(c) , theta >
Operator *opVGradC = new Operator(chProb->getFeSpace(0), chProb->getFeSpace(1));
opVGradC->addTerm(new VecAtQP_FOT(nsProb->getSolution()->getDOFVector(i), new ID(), i), GRD_PHI);
opVGradC->addTerm(new VecAndPartialDerivative_FOT(nsProb->getSolution()->getDOFVector(i), i), GRD_PHI);
chProb->getProblem()->addMatrixOperator(opVGradC, 1, 1, chProb->getTau());
}
/**/
......@@ -191,27 +163,12 @@ public:
**/
void solveInitialProblem(AdaptInfo *adaptInfo)
{
// meshFunction for klocal refinement around the interface of the phasefield-DOFVector
refFunction = new PhaseFieldRefinement(chProb->getMesh());
if (chProb->getDoubleWellType() == 0) {
refinement = new RefinementLevelDOF(
chProb->getFeSpace(),
refFunction,
chProb->getSolution()->getDOFVector(1)); // phaseField-DOFVector in [0,1]
} else {
refinement = new RefinementLevelDOF(
chProb->getFeSpace(),
refFunction,
new PhaseDOFView<double>(chProb->getSolution()->getDOFVector(1))); // phaseField-DOFVector in [-1,1]
}
// initial refinement
refinement->refine(0);
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 5; i++) {
chProb->solveInitialProblem(adaptInfo); // update phaseField-DOFVector
refinement->refine((i < 4 ? 4 : 10)); // do k steps of local refinement
refinement->refine(5); // do k steps of local refinement
}
// solve all initial problems of the problems added to the CouplingTimeInterface
......@@ -226,16 +183,14 @@ public:
void closeTimestep(AdaptInfo *adaptInfo)
{
CouplingTimeInterface::closeTimestep(adaptInfo);
Y yFun;
AMDiS::Component<1> yFun(y->getFeSpace()->getBasisFcts()->getDegree());
y->interpol(&yFun);
DOFVector<double>::Iterator phiIt(dynamic_cast<DOFIndexed<double>*>(const_cast<DOFVector<double>*>(chProb->getSolution()->getDOFVector(1))), USED_DOFS);
DOFVector<double>::Iterator yIt(dynamic_cast<DOFIndexed<double>*>(y), USED_DOFS);
DOFVector<double>::Iterator yc1It(dynamic_cast<DOFIndexed<double>*>(yc1), USED_DOFS);
DOFVector<double>::Iterator yc2It(dynamic_cast<DOFIndexed<double>*>(yc2), USED_DOFS);
DOFIterator<double> phiIt(chProb->getSolution()->getDOFVector(1), USED_DOFS);
DOFIterator<double> yIt(y, USED_DOFS);
DOFIterator<double> yc1It(yc1, USED_DOFS);
DOFIterator<double> yc2It(yc2, USED_DOFS);
for (phiIt.reset(), yIt.reset(),yc1It.reset(),yc2It.reset();
!phiIt.end();
......@@ -244,25 +199,18 @@ public:
*yc1It = *yc2It * *yIt;
}
if (adaptInfo->getTimestepNumber() <= 1) center_old = (yc1->Int())/(yc2->Int());
u_b = - (center_old - (yc1->Int())/(yc2->Int()) ) / adaptInfo->getTimestep();
center_old = (yc1->Int())/(yc2->Int());
if (adaptInfo->getTimestepNumber() <= 1)
center_old = (yc1->Int()) / (yc2->Int());
u_b = - (center_old - (yc1->Int()) / (yc2->Int()) ) / adaptInfo->getTimestep();
center_old = (yc1->Int()) / (yc2->Int());
// append values to file
output = fopen( "output_data", "a" );
fprintf(output, "%f, %f, %f\n",
adaptInfo->getTime(),
u_b,
center_old);
fprintf(output, "%f, %f, %f\n", adaptInfo->getTime(), u_b, center_old);
fclose(output);
//chProb->solveInitialProblem(adaptInfo);
refinement->refine(2);
}
protected:
......@@ -272,9 +220,6 @@ protected:
PhaseFieldRefinement* refFunction;
RefinementLevelDOF *refinement;
unsigned dim; // dimension of the mesh
unsigned dow; // dimension of the world
double sigma; // coupling parameter to calculate the surface tension
double surfaceTension;// := sigma/epsilon
double u_b, center_old;
......
......@@ -115,11 +115,11 @@ void CahnHilliard_::solveInitialProblem(AdaptInfo *adaptInfo)
/// create phase-field from signed-dist-function
if (doubleWell == 0) {
transformDOF(prob->getSolution()->getDOFVector(1),
new SignedDistToPhaseField(initialEps));
forEachDOF(prob->getSolution()->getDOFVector(1),
new SignedDistToPhaseField(initialEps, 1.0/(2.0*sqrt(2.0))));
} else {
transformDOF(prob->getSolution()->getDOFVector(1),
new SignedDistToCh(initialEps));
forEachDOF(prob->getSolution()->getDOFVector(1),
new SignedDistToCh(initialEps, 1.0/sqrt(2.0)));
}
}
}
......@@ -130,6 +130,7 @@ void CahnHilliard_::fillOperators()
MSG("CahnHilliard_::fillOperators()\n");
const FiniteElemSpace* feSpace = prob->getFeSpace(0);
int degree = feSpace->getBasisFcts()->getDegree();
// c
Operator *opChMnew = new Operator(feSpace,feSpace);
......@@ -148,22 +149,22 @@ void CahnHilliard_::fillOperators()
Operator *opChMPowExpl = new Operator(feSpace,feSpace);
opChMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(
prob->getSolution()->getDOFVector(1),
new Pow3Functor(-2.0)));
new AMDiS::Pow<3>(-2.0,3*degree)));
if (doubleWell == 0) {
opChMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(
prob->getSolution()->getDOFVector(1),
new Pow2Functor(3.0/2.0)));
new AMDiS::Pow<2>(3.0/2.0,2*degree)));
}
// -3*c_old^2 * c
Operator *opChMPowImpl = new Operator(feSpace,feSpace);
opChMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(
prob->getSolution()->getDOFVector(1),
new Pow2Functor(-3.0)));
new AMDiS::Pow<2>(-3.0,2*degree)));
if (doubleWell == 0) {
opChMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(
prob->getSolution()->getDOFVector(1),
new AMDiS::Factor<double>(3.0)));
new AMDiS::Factor<double>(3.0,degree)));
opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(-0.5));
} else {
opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(1.0));
......
......@@ -42,8 +42,6 @@ public: // public methods
double getEpsilon() { return eps; }
int getDoubleWellType() { return doubleWell; }
protected: // protected methods
virtual void fillOperators();
virtual void fillBoundaryConditions() {}
......
......@@ -20,7 +20,6 @@
#include "CahnHilliardNavierStokes_.h"
#include "SignedDistFunctors.h"
#include "PhaseFieldConvert.h"
//#include "CahnHilliard_.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "parallel/PetscSolverCahnHilliard.h"
......@@ -28,12 +27,7 @@
#include "parallel/PetscSolverNavierStokes.h"
#endif
#include "boost/date_time/posix_time/posix_time.hpp"
using namespace AMDiS;
using namespace boost::posix_time;
class CahnHilliardPC : public CahnHilliard_
{
......@@ -47,11 +41,11 @@ public:
string initFileStr = name + "->space->solver", solverType = "";
Parameters::get(initFileStr, solverType);
if (solverType == "petsc-ch") {
PetscSolverCahnHilliard* solver = dynamic_cast<PetscSolverCahnHilliard*>(prob->getSolver());
Parallel::PetscSolverCahnHilliard* solver = dynamic_cast<Parallel::PetscSolverCahnHilliard*>(prob->getSolver());
if (solver)
solver->setChData(&eps, &delta, prob->getSolution());
} else if (solverType == "petsc-ch2") {
PetscSolverCahnHilliard2* solver = dynamic_cast<PetscSolverCahnHilliard2*>(prob->getSolver());
Parallel::PetscSolverCahnHilliard2* solver = dynamic_cast<Parallel::PetscSolverCahnHilliard2*>(prob->getSolver());
if (solver)
solver->setChData(&eps, &delta);
}
......@@ -74,38 +68,41 @@ public:
class NavierStokes_TaylorHoodPC : public NavierStokes_TH_MultiPhase
{
public:
NavierStokes_TaylorHoodPC(std::string name) : NavierStokes_TH_MultiPhase(name)
typedef NavierStokes_TH_MultiPhase super;
public:
NavierStokes_TaylorHoodPC(std::string name) : super(name)
{ }
void initData()
{
NavierStokes_TH_MultiPhase::initData(); /// warum geht super::initData() nicht ?
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
super::initData();
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string initFileStr = name + "->space->solver", solverType = "";
Parameters::get(initFileStr, solverType);
if (solverType == "petsc-navierstokes") {
PetscSolverNavierStokes *s = dynamic_cast<PetscSolverNavierStokes*>(prob->getPetscSolver());
Parallel::PetscSolverNavierStokes *s = dynamic_cast<Parallel::PetscSolverNavierStokes*>(prob->getSolver());
if (s) {
s->setStokesData( getInvTau(), prob->getSolution(), &viscosity1, &viscosity2, &density1, &density2);
s->setPhase(multiPhase);
}
}
#endif
#endif
}
void initPhasefield()
{
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
string initFileStr = name + "->space->solver", solverType = "";
Parameters::get(initFileStr, solverType);
if (solverType == "petsc-navierstokes") {
PetscSolverNavierStokes *s = dynamic_cast<PetscSolverNavierStokes*>(prob->getPetscSolver());
Parallel::PetscSolverNavierStokes *s = dynamic_cast<Parallel::PetscSolverNavierStokes*>(prob->getSolver());
if (s) {
s->setPhase(multiPhase);
}
}
#endif
#endif
}
};
......@@ -118,7 +115,6 @@ class MyNavierStokes_PC : public NavierStokes_TaylorHoodPC
public:
MyNavierStokes_PC(std::string name_) : NavierStokes_TaylorHoodPC(name_) {}
protected: