Commit ee87f25a authored by Sebastian Aland's avatar Sebastian Aland

added a coupled NavierStokesCahnHilliard preconditioner and demo

parent 31d900f7
......@@ -509,7 +509,28 @@ namespace AMDiS {
PCFieldSplitSetIS(pc, splitName, is);
ISDestroy(&is);
}
void PetscSolverGlobalMatrix::extractVectorComponent(Vec input, int i, Vec *output, int numberOfComponents)
{
FUNCNAME("PetscSolverGlobalMatrix::extractVectorComponent()");
IS is;
interiorMap->createIndexSet(is, i, numberOfComponents);
VecGetSubVector(input, is, output);
ISDestroy(&is);
}
void PetscSolverGlobalMatrix::extractMatrixComponent(Mat input, int startRow, int numberOfRows, int startCol, int numberOfCols, Mat *output)
{
FUNCNAME("PetscSolverGlobalMatrix::extractMatrixComponent()");
IS isrow, iscol;
interiorMap->createIndexSet(isrow, startRow, numberOfRows);
interiorMap->createIndexSet(iscol, startCol, numberOfCols);
MatGetSubMatrix(input, isrow, iscol, MAT_INITIAL_MATRIX, output);
ISDestroy(&iscol);
ISDestroy(&isrow);
}
void PetscSolverGlobalMatrix::initSolver(KSP &ksp)
{
......
......@@ -62,6 +62,10 @@ namespace AMDiS {
void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo);
void solveGlobal(Vec &rhs, Vec &sol);
void extractVectorComponent(Vec input, int i, Vec *output, int numberOfComponents=1);
void extractMatrixComponent(Mat input, int startRow, int numberOfRows, int startCol, int numberOfCols, Mat *output);
void destroyMatrixData();
......@@ -96,6 +100,8 @@ namespace AMDiS {
components.push_back(component);
createFieldSplit(pc, splitName, components);
}
virtual void initSolver(KSP &ksp);
......
This diff is collapsed.
/** \file NavierStokesCahnHilliard.h */
#include "AMDiS.h"
#include "BaseProblem.h"
#include "POperators.h"
#include "ExtendedProblemStat.h"
#include "chns.h"
#include "Refinement.h"
#include "MeshFunction_Level.h"
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "parallel/PetscSolverNSCH.h"
#endif
using namespace AMDiS;
class NavierStokesCahnHilliard : public BaseProblem<ProblemStat>
{
public: // definition of types
typedef BaseProblem<ProblemStat> super;
public: // public methods
NavierStokesCahnHilliard(const std::string &name_, bool createProblem = true);
~NavierStokesCahnHilliard();
virtual void initData();
/** initTimestep of super and
* initialization of densityPhase and viscosityPhase
**/
virtual void initTimestep(AdaptInfo *adaptInfo);
virtual void closeTimestep(AdaptInfo *adaptInfo);
virtual void setTime(AdaptInfo* adaptInfo);
/* * indicates the different phases. Will be initialized
* in \ref initTimeInterface with const 1
**/
void setMultiPhase(DOFVector<double>* p) { multiPhase=p; }
virtual void solveInitialProblem(AdaptInfo *adaptInfo);
virtual void solveInitialProblem2(AdaptInfo *adaptInfo);
double getEpsilon() { return eps; }
int getDoubleWellType() { return doubleWell; }
protected: // protected methods
virtual void fillOperators();
virtual void addLaplaceTerm(int i);
protected: // protected variables
///viscosity of phase 1
double viscosity1;
///viscosity of phase 2
double viscosity2;
///density of phase 1
double density1;
///density of phase 2
double density2;
double a, b, ab;
double tau;
/// phase dependent density
DOFVector<double> *densityPhase;
/// phase dependent viscosity
DOFVector<double> *viscosityPhase;
double delta;
/// phase inticator
DOFVector<double> *multiPhase;
DOFVector<WorldVector<double> >* velocity;
void calcVelocity()
{
if (dow == 1)
transformDOF(prob->getSolution()->getDOFVector(0), velocity, new AMDiS::Vec1WorldVec<double>);
else if (dow == 2)
transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), velocity, new AMDiS::Vec2WorldVec<double>);
else if (dow == 3)
transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), velocity, new AMDiS::Vec3WorldVec<double>);
}
FileVectorWriter* fileWriter;
bool useMobility;
unsigned dow; // dimension of the world
unsigned dim;
PhaseFieldRefinement* refFunction;
RefinementLevelDOF *refinement;
double sigma, minus1; // coupling parameter to calculate the surface tension
double surfaceTension;// := sigma/epsilon
int doubleWell;
double gamma;
double eps;
double minusEps;
double epsInv;
double minusEpsInv;
double epsSqr;
double minusEpsSqr;
int nonLinTerm;
double theta;
double theta1;
double minusTheta1;
WorldVector<double> force;
};
class Force : public AbstractFunction<double, double>
{
public:
Force(double c_) :
AbstractFunction<double, double>(2), c(c_) {};
double operator()(const double &x) const {
return x*c;
}
private:
double c;
};
class LinearInterpolation1 : public AbstractFunction<double, double>
{
public:
LinearInterpolation1(double c1, double c2) :
AbstractFunction<double, double>(1)
{ a = (c1-c2)/2.0; b = (c1+c2)/2.0; cmin=std::min(c1,c2); cmax=std::max(c1,c2);}
double operator()(const double &phase) const {
double result = b+a*phase;
if (result<cmin) result = cmin;
if (result>cmax) result = cmax;
return result;
}
private:
double a,b,cmin,cmax;
};
/** linear interpolation between two values (like density, viscosity)
* using a phase-field variable in [0,1]
**/
class LinearInterpolation0 : public AbstractFunction<double, double>
{
public:
LinearInterpolation0(double val1_, double val2_) :
AbstractFunction<double, double>(1),
val1(val1_), val2(val2_) {}
double operator()(const double &phase) const {
return phase*val1 + (1.0-phase)*val2;
}
private:
double val1;
double val2;
};
project("preconditioner")
cmake_minimum_required(VERSION 2.6)
unset(ENV{LIBRARY_PATH})
find_package(AMDIS REQUIRED)
if(AMDIS_FOUND)
message("AMDIS was found\n")
include(${AMDIS_USE_FILE})
SET(BASIS_LIBS ${AMDIS_LIBRARIES})
endif(AMDIS_FOUND)
# set(base_dir /home/spraetor/projects)
#
# file(GLOB common ${base_dir}/src/common/*.cc)
# file(GLOB alglib ${base_dir}/src/extensions/alglib/cpp/src/*.cpp)
#
# include_directories(${base_dir}/src/common/)
# include_directories(${meshconv_dir})
set(drivenCavity #src/NavierStokesCahnHilliard.cc
#src/PetscSolverNSCH.cc
src/benchmark.cc)
add_executable("benchmark" ${drivenCavity})
target_link_libraries("benchmark" ${BASIS_LIBS})
dimension of world: 2
output_folder: .
mesh_name: mesh
% ====================== INCLUDES =========================
#include "../init/reinit.inc.2d"
% ============== USER-PARAMETER ==========================
nsch->viscosity1: 1 % 1 0.1
nsch->viscosity2: 10
nsch->density1: 100 % 100 1
nsch->density2: 1000
nsch->sigma: 24.500 % 24.5 1.96
nsch->a_factor: 1
nsch->theta: 1
nsch->force: [0.0, -0.98] % gravitational force [m/s^2]
nsch->epsilon: 0.01
nsch->initial epsilon: ${nsch->epsilon}
nsch->gamma: 0.05
nsch->transport term: 1.0
nsch->initial interface: 4 % 0 für linie
nsch->line->direction: 1
nsch->line->pos: 1.0
nsch->circle->radius: 0.25
nsch->circle->center_x: 0.5
nsch->circle->center_y: 0.5
nsch->double-well type: 1
nsch->use mobility: 0
nsch->use conservation form: 0
mesh->refinement->epsilon: ${nsch->epsilon}
% ====================== TIMESTEPS ========================
adapt->max iteration: 1
adapt->max timestep iteration: 1
adapt->max time iteration: 1
adapt->timestep: 1.0e-3
adapt->max timestep: 1e+10
adapt->min timestep: 1e-6
adapt->start time: 0.0
adapt->end time: 3.0e0
% ====================== MESH =============================
mesh->refinement->initial level: 6 % 4 10
mesh->refinement->level in inner domain: 6 % 4 10
mesh->refinement->level in outer domain: 6 % 4 10
mesh->refinement->level on interface: 13 % 8 14
mesh->refinement->min inner interface value: 0.05
mesh->refinement->max outer interface value: 0.95
mesh->refinement->max inner interface value: 0.95
mesh->refinement->min outer interface value: 0.05
${mesh_name}->macro file name: ../macro/ns_ch.macro
${mesh_name}->global refinements: 0
${mesh_name}->check: 0
nsch->space->mesh: ${mesh_name}
% =========== OUTPUT ==============================================
nsch->space->output[0]->filename: ${output_folder}/u1_
nsch->space->output[1]->filename: ${output_folder}/u2_
nsch->space->output[2]->filename: ${output_folder}/p_
nsch->space->output[4]->filename: ${output_folder}/ch_
% ============= PROBLEM-SPACES ==================================
nsch->space->components: 5
nsch->space->polynomial degree[0]: 2
nsch->space->polynomial degree[1]: 2
nsch->space->polynomial degree[2]: 1
nsch->space->polynomial degree[3]: 2
nsch->space->polynomial degree[4]: 2
nsch->space->dim: 2
% ================== SOLVER ======================================
nsch->space->solver: petsc-nsch
nsch->space->solver->navierstokes->regularize laplace: 1
nsch->space->solver->use old initial guess: 1
nsch->space->solver->navierstokes->velocity solver: 0
nsch->space->solver->navierstokes->mass solver: 0
nsch->space->solver->navierstokes->laplace solver: 0
nsch->space->solver->use old initial guess: 1
nsch->space->solver->symmetric strategy: 0
nsch->space->solver->store symbolic: 0
nsch->space->solver->ell: 8
nsch->space->solver->max iteration: 200
nsch->space->solver->tolerance: 1.e-10
nsch->space->solver->info: 1
nsch->space->solver->left precon: ilu
%nsch->space->solver: umfpack
%nsch->space->solver->symmetric strategy: 0
%nsch->space->solver->store symbolic: 0
%nsch->space->solver->ell: 8
%nsch->space->solver->max iteration: 200
%nsch->space->solver->tolerance: 1.e-8
%nsch->space->solver->info: 1
%nsch->space->solver->left precon: ilu
% =================== OUTPUT =========================================
nsch->space->output[0]->ParaView animation: 1
nsch->space->output[0]->ParaView format: 1
nsch->space->output[0]->write every i-th timestep: 1
%nsch->space->output->compression: gzip
nsch->space->output[0]->append index: 1
nsch->space->output[0]->index length: 9
nsch->space->output[0]->index decimals: 7
nsch->space->output[1]->ParaView animation: 1
nsch->space->output[1]->ParaView format: 1
nsch->space->output[1]->write every i-th timestep: 1
%nsch->space->output->compression: gzip
nsch->space->output[1]->append index: 1
nsch->space->output[1]->index length: 9
nsch->space->output[1]->index decimals: 7
nsch->space->output[2]->ParaView animation: 1
nsch->space->output[2]->ParaView format: 1
nsch->space->output[2]->write every i-th timestep: 1
%nsch->space->output->compression: gzip
nsch->space->output[2]->append index: 1
nsch->space->output[2]->index length: 9
nsch->space->output[2]->index decimals: 7
nsch->space->output[4]->ParaView animation: 1
nsch->space->output[4]->ParaView format: 1
nsch->space->output[4]->write every i-th timestep: 1
%nsch->space->output->compression: gzip
nsch->space->output[4]->append index: 1
nsch->space->output[4]->index length: 9
nsch->space->output[4]->index decimals: 7
nsch->space->output->write serialization: 0
nsch->space->output->serialization filename: serial_ch
nsch->space->input->read serialization: 0
nsch->space->input->serialization filename: serial_ch
% ====================== MAIN INITFILE ====================
% helper problem to initialize all FeSpaces
nsch->mesh: ${mesh_name}
nsch->dim: 2
% ====================== ESTIMATORS =======================
adapt->strategy: 0 % 0=explicit, 1=implicit
WAIT: 1
reinit->tolerance: 1.e-4
reinit->maximal number of iteration steps: 100
reinit->Gauss-Seidel iteration: 1
reinit->infinity value: 1.e8
reinit->boundary initialization: 3
DIM: 2
DIM_OF_WORLD: 2
number of elements: 8
number of vertices: 8
element vertices:
0 1 6
1 2 7
2 3 7
3 4 7
4 5 6
5 0 6
1 4 6
4 1 7
element boundaries:
0 0 1
0 0 1
0 0 2
0 0 1
0 0 1
0 0 2
0 0 0
0 0 0
vertex coordinates:
1.0 0.0
1.0 1.0
1.0 2.0
0.0 2.0
0.0 1.0
0.0 0.0
0.5 0.5
0.5 1.5
# This demo implements the Navier-Stokes-Cahn-Hilliard Benchmark from
# S. Aland, A. Voigt. Benchmark computations of diffuse-interface models for two-dimensional bubble dynamics. Int. J. Num. Meth. Fluids (2012)
output="output_parallel"
initfile="init/nsch.dat.2d"
mkdir $output
cd $output
mkdir serials
cp -r ../src .
cp ../$initfile .
mpiexec -n 2 ../benchmark ../$initfile -ns_ksp_atol 1e-7 -ns_ksp_rtol 0 -ch_ksp_atol 1e-8 -ch_ksp_rtol 0 -laplace_pc_type hypre -laplace_pc_hypre_boomeramg_relax_type_coarse symmetric-SOR/Jacobi
# sequentiell (solver noch auf umfpack stellen) -> #../nsch ../$initfile
###### zum parallel debugging
###### mpiexec -n 2 valgrind --tool=memcheck -q --num-callers=20 --log-file=valgrind.log.%p ../drivenCavity ../$initfile -malloc off -log_summary
#include "AMDiS.h"
#include "NavierStokesCahnHilliard.h"
//#include "NavierStokes_TH_MultiPhase.h"
//#include "CahnHilliardNavierStokes_.h"
#include "SignedDistFunctors.h"
#include "PhaseFieldConvert.h"
#include "boost/date_time/posix_time/posix_time.hpp"
using namespace AMDiS;
using namespace boost::posix_time;
class MyNavierStokesCahnHilliard : public NavierStokesCahnHilliard
{
public:
MyNavierStokesCahnHilliard(std::string name) : NavierStokesCahnHilliard(name)
{ }
void fillBoundaryConditions()
{ FUNCNAME("MyNavierStokes::fillBoundaryConditions()");
DOFVector<double> *zeroDOF = new DOFVector<double>(getFeSpace(0), "zero");
zeroDOF->set(0.0);
size_t dow = Global::getGeo(WORLD);
/// at rigid wall: no-slip boundary condition
// oben-unten
getProblem()->addDirichletBC(2, 0, 0, zeroDOF);
getProblem()->addDirichletBC(2, 1, 1, zeroDOF);
// links-rechts
getProblem()->addDirichletBC(1, 0, 0, zeroDOF);
//getProblem()->addDirichletBC(1, 1, 1, zeroDOF);
}
};
int main(int argc, char** argv)
{ FUNCNAME("main");
AMDiS::init(argc, argv);
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
CreatorMap<OEMSolver>::addCreator("petsc-nsch", new PetscSolverNSCH::Creator);
#endif
MyNavierStokesCahnHilliard prob("nsch");
// Adapt-Infos
AdaptInfo adaptInfo("adapt", prob.getNumComponents());
prob.initialize(INIT_ALL);
prob.initData();
prob.initTimeInterface();
AdaptInstationary adaptInstat("adapt", prob, adaptInfo, prob, adaptInfo);
ptime start_time = microsec_clock::local_time();
int error_code = adaptInstat.adapt();
time_duration td = microsec_clock::local_time()-start_time;
MSG("elapsed time= %d sec\n", td.total_seconds());
AMDiS::finalize();
return error_code;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment