Commit fa2d47d7 authored by Dmitry Bagaev's avatar Dmitry Bagaev Committed by GitHub
Browse files

Merge pull request #23 from bvdmitri/fixfc2

Solver class refactoring
parents 1abd80ae f16a9d90
.svn
Tests/solver_test001/matrices
SyncToy*
build*/
*build*/
*.iml
*.xml
Source/Solver/solver_fcbiilu2/fcbiilu2.cpp
Source/Solver/solver_k3biilu2/k3d.cpp
Source/Solver/solver_k3biilu2/k3d.h
......@@ -73,9 +73,7 @@ int main(int argc,char ** argv)
if( m->GetProcessorRank() == 0 )
m->Load(argv[1]); // Load mesh from the serial file format
}
BARRIER;
if( m->GetProcessorRank() == 0 ) std::cout << "Processors: " << m->GetProcessorsNumber() << std::endl;
if( m->GetProcessorRank() == 0 ) std::cout << "Load(MPI_File): " << Timer()-ttt << std::endl;
......@@ -117,8 +115,6 @@ int main(int argc,char ** argv)
phi = m->CreateTag("Solution",DATA_REAL,CELL,NONE,1); // Create a new tag for the solution phi
tensor_K = m->CreateTag("K",DATA_REAL,CELL,NONE,1); // Create a new tag for K tensor
//m->Save("solution_check_1.vtk");
for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) // Loop over mesh cells
if( cell->GetStatus() != Element::Ghost ) // If the cell is an own one
cell->Real(tensor_K) = 1.0; // Store the tensor K value into the tag
......@@ -132,9 +128,9 @@ int main(int argc,char ** argv)
ttt = Timer();
Solver S(Solver::INNER_ILU2); // Specify the linear solver to ASM+ILU2+BiCGStab one
S.SetParameterReal("absolute_tolerance",1e-8);
S.SetParameterEnum("schwartz_overlap",2);
Solver S("inner_ilu2"); // Specify the linear solver to ASM+ILU2+BiCGStab one
S.SetParameter("absolute_tolerance", "1e-8");
S.SetParameter("schwartz_overlap", "2");
Residual R; // Residual vector
Sparse::LockService Locks;
Sparse::Vector Update; // Declare the solution and the right-hand side vectors
......@@ -149,7 +145,6 @@ int main(int argc,char ** argv)
m->PrepareGeometricData(table);
//~ BARRIER
//~ if( m->GetProcessorRank() == 0 ) std::cout << "Prepare geometric data: " << Timer()-ttt << std::endl;
{
Automatizator aut;
Automatizator::MakeCurrent(&aut);
......@@ -257,7 +252,7 @@ int main(int argc,char ** argv)
BARRIER;
if( m->GetProcessorRank() == 0 )
{
std::cout << S.Residual() << " " << S.Iterations() << " " << S.GetReason() << std::endl;
std::cout << S.Residual() << " " << S.Iterations() << " " << S.ReturnReason() << std::endl;
std::cout << "Solve system: " << Timer()-ttt << std::endl;
}
......
......@@ -84,7 +84,6 @@ int main(int argc,char ** argv)
else
std::cout << "Running MFD" << std::endl;
#if defined(USE_PARTITIONER)
if (m->GetProcessorsNumber() > 1 )//&& !repartition) // Currently only non-distributed meshes are supported by Inner_RCM partitioner
{
......@@ -198,6 +197,7 @@ int main(int argc,char ** argv)
Mesh * mesh = m;
Cell cell = m->CellByLocalID(q);
ElementArray<Face> faces = cell->getFaces(); //obtain faces of the cell
int NF = (int)faces.size(); //number of faces;
rMatrix W(NF,NF);
......@@ -219,9 +219,9 @@ int main(int argc,char ** argv)
int i, j,k,Z;
double w,l,m, J_det,x,y,z;
rMatrix K = rMatrix::FromTensor(cell->RealArrayDF(tag_K).data(),cell->RealArrayDF(tag_K).size()); //get permeability for the cell
rMatrix K_inverse (3,3); // inverse of permeability
K_inverse= K.Invert(true).first;
// gauss points for intgration
gauss_pt_xyz[0]=(5.0+3.0*(sqrt(5.0)))/20.0;
......@@ -260,10 +260,10 @@ int main(int argc,char ** argv)
dN[8]=0;
dN[9]=0;
dN[10]=0;
dN[11]=1;
// local to reference tranformation
ElementArray<Node> node(mesh);
for(j = 0; j < 4; ++j)
......@@ -275,7 +275,6 @@ int main(int argc,char ** argv)
for ( j = 0; j < 4; j++ )
{
for ( i = 0; i < 3; i++ )
tetra[i+j*3]= node[j].Coords()[i]; // <-- X
}
......@@ -338,7 +337,6 @@ int main(int argc,char ** argv)
for ( j = 0; j < 4; j++) { // column number of output
for ( Z = 0; Z < 4; Z++) { // GAUSS POINT IN Z DIRECTION
x=gauss_pt_xyz[Z*3];
y=gauss_pt_xyz[Z*3+1];
......@@ -352,6 +350,7 @@ int main(int argc,char ** argv)
W_RT0[3]= 2*(-1+x);
W_RT0[4]= 2*y;
W_RT0[5]= 2*z;
W_RT0[6]= (2*x);///(sqrt(3.0));
......@@ -359,7 +358,9 @@ int main(int argc,char ** argv)
W_RT0[8]= (2*z);///(sqrt(3.0));
W_RT0[9]= 2*x;
W_RT0[10]= 2*y;
W_RT0[11]= 2*(-1+z);
......@@ -384,6 +385,7 @@ int main(int argc,char ** argv)
}
}
for ( j = 0; j < 4; j++) { // row number of output
double sum = 0;
for ( i = 0; i < 4; i++) { // column number of output
......@@ -414,8 +416,6 @@ int main(int argc,char ** argv)
//W.Print();
//scanf("%*c");
}
......@@ -551,10 +551,8 @@ int main(int argc,char ** argv)
Automatizator::MakeCurrent(&aut);
dynamic_variable P(aut,aut.RegisterTag(tag_P,CELL|FACE)); //register pressure as primary unknown
aut.EnumerateTags(); //enumerate all primary variables
std::cout << "Enumeration done, size " << aut.GetLastIndex() - aut.GetFirstIndex() << std::endl;
Residual R("",aut.GetFirstIndex(),aut.GetLastIndex());
Sparse::LockService Locks(aut.GetFirstIndex(),aut.GetLastIndex());
Sparse::AnnotationService Text(aut.GetFirstIndex(),aut.GetLastIndex());
......@@ -604,16 +602,17 @@ int main(int argc,char ** argv)
for(int k = 0; k < NF; ++k)
{
if (faces[k]->FrontCell().isValid())
{
Cell cell_n = cell.Neighbour(faces[k]);
ElementArray<Face> faces_n = cell_n->getFaces(); //obtain faces of the cell neighoubr
rMatrix nKGRAD_n(cell_n->RealArrayDV(tag_W).data(),NF,NF); //Matrix for gradient
double B_1, B_2, L_1, L_2;
int face_n_k;
L_1 =0.0;
B_1= nKGRAD(k,k) ;
for(int j = 0; j < NF; ++j)
L_1 +=nKGRAD(k,j) ;
......@@ -621,7 +620,9 @@ int main(int argc,char ** argv)
{
face_n_k= j ;
}
L_2 =0.0;
for(int j = 0; j < NF; ++j)
L_2 +=nKGRAD_n(face_n_k,j) ;
......@@ -648,7 +649,6 @@ int main(int argc,char ** argv)
}
}
// for(int k = 0; k < NF; ++k)
// {
// FLUX_MASS(k,0)=0.0;
......@@ -717,11 +717,12 @@ int main(int argc,char ** argv)
//Solver S(Solver::INNER_ILU2);
//Solver S(Solver::INNER_MPTILUC);
Solver S(Solver::SUPERLU);
S.SetParameterReal("relative_tolerance", 1.0e-14);
S.SetParameterReal("absolute_tolerance", 1.0e-12);
S.SetParameterReal("drop_tolerance", 1.0e-1);
S.SetParameterReal("reuse_tolerance", 1.0e-2);
Solver S("superlu");
S.SetParameter("relative_tolerance", "1.0e-14");
S.SetParameter("absolute_tolerance", "1.0e-12");
S.SetParameter("drop_tolerance", "1.0e-1");
S.SetParameter("reuse_tolerance", "1.0e-2");
S.SetMatrix(R.GetJacobian());
//std::fill(Update.Begin(),Update.End(),0.0);
if( S.Solve(R.GetResidual(),Update) )
......@@ -755,7 +756,7 @@ int main(int argc,char ** argv)
}
else
{
std::cout << "Unable to solve: " << S.GetReason() << std::endl;
std::cout << "Unable to solve: " << S.ReturnReason() << std::endl;
break;
}
++nit;
......
......@@ -26,4 +26,3 @@ if(OPENGL_FOUND)
else(OPENGL_FOUND)
message("OpenGL not found, not building DrawGrid")
endif(OPENGL_FOUND)
......@@ -598,12 +598,10 @@ void draw()
//glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5);
int pacef = std::max(1,mesh->FaceLastLocalID()/10000);
std::vector<face2gl> polygons;
if( badfaces )
{
for(INMOST_DATA_INTEGER_TYPE it = 0; it < mesh->FaceLastLocalID(); it += (interactive ? pacef : 1)) if( mesh->isValidFace(it) )
{
Face f = mesh->FaceByLocalID(it);
......@@ -746,7 +744,6 @@ void draw()
ElementArray<Node> nodes = edges[k].getNodes();
if( matfilter == 0 || (mats_tag.isValid() && std::binary_search(mats.begin(),mats.end(),matfilter-1)) )
{
if( mats_tag.isValid() ) fill_mat_str(edges[k].LocalID(), mats,str);
......@@ -1048,7 +1045,6 @@ void draw()
ElementArray<Node> nodes = edges[k].getNodes();
if( matfilter == 0 || std::binary_search(mats.begin(),mats.end(),matfilter-1) )
{
fill_mat_str(edges[k].LocalID(), mats,str);
......@@ -1538,6 +1534,7 @@ void draw()
if( show_cell != -1 )
{
it = mesh->ElementByLocalID(CELL,show_cell);
if( !it.isValid() )
{
std::cout << "cell " << show_cell << " not accepted " << std::endl;
......@@ -1553,6 +1550,7 @@ void draw()
if( show_face != -1 )
{
it = mesh->ElementByLocalID(FACE,show_face);
if( !it.isValid() )
{
std::cout << "face " << show_face << " not accepted " << std::endl;
......
......@@ -128,8 +128,8 @@ int main(int argc,char ** argv)
if( m->GetProcessorRank() == 0 ) std::cout << "Exchange ghost: " << Timer()-ttt << std::endl;
ttt = Timer();
Solver S(Solver::INNER_ILU2); // Specify the linear solver to ASM+ILU2+BiCGStab one
S.SetParameterReal("absolute_tolerance",1e-8);
Solver S("inner_ilu2"); // Specify the linear solver to ASM+ILU2+BiCGStab one
S.SetParameter("absolute_tolerance", "1e-8");
Sparse::LockService L;
Sparse::Matrix A; // Declare the matrix of the linear system to be solved
Sparse::Vector x,b; // Declare the solution and the right-hand side vectors
......
project(MatSolve)
set(SOURCE main.cpp inner_parser.cpp inner_parser.h)
set(SOURCE main.cpp)
add_executable(MatSolve ${SOURCE})
......
......@@ -5,3 +5,4 @@ Trilinos_Aztec:
Trilinos_Belos:
FCBIILU2: ctrl_dat
K3BIILU2: ctrl_dat
inner_ilu2: inner_options.txt
enum maximum_iterations 300
enum gmres_substeps 4
real relative_tolerance 1.0e-5
real absolute_tolerance 1.0e-10
real divergence_tolerance 1e+200
maximum_iterations 300
gmres_substeps 4
relative_tolerance 1.0e-5
absolute_tolerance 1.0e-10
divergence_tolerance 1e+200
enum reorder_nonzeros 0
enum rescale_iterations 8
enum adapt_ddpq_tolerance 0
reorder_nonzeros 0
rescale_iterations 8
adapt_ddpq_tolerance 0
real drop_tolerance 3.0e-5
real reuse_tolerance 1.0e-5
real ddpq_tolerance 0.0
drop_tolerance 3.0e-5
reuse_tolerance 1.0e-5
ddpq_tolerance 0.0
enum condition_estimation 1
enum schwartz_overlap 6
condition_estimation 1
schwartz_overlap 6
#include "inner_parser.h"
void removeSpaces(char* source) {
char* i = source;
char* j = source;
while(*j != 0)
{
*i = *j++;
if(*i != ' ')
i++;
}
*i = 0;
}
InnerOptions *parseInnerDatabaseOptions(char *optionsFile) {
FILE *databaseFile = fopen(optionsFile, "r");
if (!databaseFile) {
std::cout << "Inner options file not found" << std::endl;
return NULL;
}
InnerOptions *options = new InnerOptions();
char *tmp = (char *) calloc(256, sizeof(char));
char *parameterName = (char *) calloc(128, sizeof(char));
char *parameterValue = (char *) calloc(128, sizeof(char));
char *type = (char *) calloc(36, sizeof(char));
while (!feof(databaseFile) && fgets(tmp, 256, databaseFile)) {
//removeSpaces(tmp);
char *line = tmp;
//Comment str
if (line[0] == '#') continue;
//First 4 chars is 'real' or 'enum'
bool isReal = false, isEnum = false;
sscanf(line, "%s %s %s", type, parameterName, parameterValue);
if (strncmp(type, "real", 4) == 0) {
//fprintf(stdout, "Real parameter:");
isReal = true;
} else if (strncmp(type, "enum", 4) == 0) {
//fprintf(stdout, "Enum parameter:");
isEnum = true;
} else {
fprintf(stderr, "Skipping bad line: %s", line);
continue;
}
options->options.push_back(new InnerOption(std::string(parameterName), std::string(parameterValue), isReal ? REAL : ENUM));
}
free(parameterValue);
free(parameterName);
free(tmp);
free(type);
return options;
}
char *findInnerOptions(const char *databaseFilePath) {
FILE *databaseFile = fopen(databaseFilePath, "r");
if (databaseFile == NULL) {
fprintf(stderr, "Database file not found\n");
#if defined(USE_MPI)
MPI_Finalize();
#endif
exit(1);
}
char *tmp = (char *) calloc(256, sizeof(char));
char *parameterName = (char *) calloc(64, sizeof(char));
char *parameterValue = (char *) calloc(64, sizeof(char));
char *fileName = NULL;
while (!feof(databaseFile) && fgets(tmp, 256, databaseFile)) {
removeSpaces(tmp);
char *line = tmp;
if (strncmp(line, "inner", 5) != 0) continue;
line += 6;
size_t fileNameLength = 0;
while (!isspace(*(line + fileNameLength))) fileNameLength += 1;
fileName = (char *) calloc(fileNameLength + 1, sizeof(char));
memcpy(fileName, line, fileNameLength);
fileName[fileNameLength] = 0;
}
free(tmp);
return fileName;
}
#ifndef INMOST_INNER_PARSER_H_H
#define INMOST_INNER_PARSER_H_H
#include <string>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cstdio>
enum OptionType {
REAL,
ENUM
};
class InnerOption {
public:
InnerOption(const std::string &name, const std::string &value, OptionType type) : name(name), value(value),
type(type) { }
std::string name;
std::string value;
OptionType type;
};
class InnerOptions {
public:
std::vector<InnerOption *> options;
};
char *findInnerOptions(const char *databaseFilePath);
InnerOptions *parseInnerDatabaseOptions(char *optionsFile);
#endif //INMOST_INNER_PARSER_H_H
......@@ -2,9 +2,10 @@
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include "inmost.h"
#include "inner_parser.h"
using namespace INMOST;
#if defined(USE_MPI)
......@@ -13,31 +14,173 @@ using namespace INMOST;
#define BARRIER
#endif
int main(int argc, char ** argv) {
// developed by Igor Konshin
#define NMAX 1024 //1024 // maximal pixel field dimension
static int f[NMAX][NMAX]; // pixel field
static int nm; // actual matrix dimention
static int nf; // actual field dimention
static double sc; // scaling indices from matrix to pixel field
// Initialize print of matrix portrait into PS file
void ps_init (int n)
{
nm = n;
nf = (n <= NMAX) ? n : NMAX;
sc = 1;
if (nm > 1 && nm > nf) sc = (double)(nf-1)/(double)(nm-1);
std::cout<<"::: nm="<<nm<<" nf="<<nf<<" sc="<<sc<<std::endl;//db!
for (int i=0; i<nf; i++)
for (int j=0; j<nf; j++)
f[i][j] = 0;
}
// Save 1 nonzero into some pixel (j and j are started from 0 like in C)
inline void ps_ij (int i, int j)
{
if (i >= 0 && i < nm && j >= 0 && j < nm)
f[(int)(j*sc)][nf-1-(int)(i*sc)] = 1;
}
// Write the collected matrix portrait into PS file
void ps_file (std::string file, int nbl = 1, int * ibl = NULL)
{
double s1 = 50.0;
double s = 500.0 / nf;
std::fstream output(file.c_str(),std::ios::out);
output << "%%BoundingBox: 0 0 600 600" << std::endl;
output << "/m {moveto} def % x y" << std::endl;
output << "/l {lineto} def % x y" << std::endl;
output << "/s {stroke} def % x y" << std::endl;
output << "/n {newpath} def % x y" << std::endl;
output << "/c {closepath} def % x y" << std::endl;
output << 0.1 << " setlinewidth" << std::endl;
output << "n " << s1+s*.5 << " " << s1+s*.5 << " m "
<< s1+s*(nf+.5) << " " << s1+s*.5 << " l "
<< s1+s*(nf+.5) << " " << s1+s*(nf+.5) << " l "
<< s1+s*.5 << " " << s1+s*(nf+.5) << " l "
<< s1+s*.5 << " " << s1+s*.5 << " l s c" << std::endl;
if (nbl > 1) {
for (int i=1; i<nbl; i++) {
double x = sc*ibl[i] + .5;
double y = nf - (sc*ibl[i] + .5) + 1.0;
output << "n " << s1+s*.5 << " " << s1+s*y << " m "
<< s1+s*(nf+.5) << " " << s1+s*y << " l s c" << std::endl;
output << "n " << s1+s*x << " " << s1+s*.5 << " m "
<< s1+s*x << " " << s1+s*(nf+.5) << " l s c" << std::endl;
}
}
double r = (log10(1.0*nf) + 1.0) / 4.0;
r = s * ((r < 1.0) ? r : 1.0) / 2.0;
r = (r > 1.0) ? r : 1.0;
//r = .2;
output << 2*r << " setlinewidth" << std::endl;
output << "/d {moveto currentpoint" << r << " 0 360 arc fill} def % x y" << std::endl;
output << "n" << std::endl;
std::stringstream ps(std::ios::in | std::ios::out);
//ps << std::scientific;
//ps.precision(2);
for (int i=0; i<nf; i++)
for (int j=0; j<nf; j++)
if (f[i][j] != 0)
ps << s1+s*(i+1)-r << " " << s1+s*(j+1) << " m "
<< s1+s*(i+1)+r << " " << s1+s*(j+1) << " l" << std::endl;
output << ps.rdbuf();
output << "s c" << std::endl;
output << "showpage" << std::endl;
}
// Print of matrix portrait into PS file
void ps_crs (int n, int nbl, int * ibl, int * ia, int *ja, const std::string file)
{
int ia0 = ia[0];
int ja0 = n;
for (int k=0; k<ia[nbl]-ia0; k++) ja0 = (ja0 < ja[k]) ? ja0 : ja[k];
ps_init (n);
for (int i=0; i<n; i++)
for (int k=ia[i]-ia0; k<ia[i+1]-ia0; k++)
ps_ij (i, ja[k]-ja0);
ps_file (file, nbl, ibl);
}
#define USE_INMOST
#if defined(USE_INMOST)
// Print of INMOST matrix portrait into PS file
void ps_inmost (Sparse::Matrix & A, const std::string file)
{
int n = A.Size();
int row = A.GetFirstIndex();
ps_init (n);
for (Sparse::Matrix::iterator it = A.Begin(); it != A.End(); ++it) {
for (Sparse::Row::iterator jt = it->Begin(); jt != it->End(); ++jt)
ps_ij (row,jt->first);
row++;
}
ps_file (file, NULL, NULL);
}
#endif
//#define PS_MATR_SELFTEST_CRS
#if defined (PS_MATR_SELFTEST_CRS)
int main ()
{
// [ 3 -1 -1 0 ]
// A = [ -1 3 0 -1 ]
// [ -1 0 3 -1 ]
// [ 0 -1 -1 3 ]
static int n=4; // nza=12;
int ia[5] = { 0, 3, 6, 9, 12 }; //ia[n+1]
int ja[12] = { 1,2,3, 1,2,4, 1,3,4, 2,3,4 }; //ja[nza]
int nbl=2, ibl[3]={0,2,4};
ps_crs (n,nbl,ibl,ia,ja,"z.ps");
}
#endif
//#define PS_MATR_SELFTEST_0
#if defined (PS_MATR_SELFTEST_0)
int main ()
{
int nbl=3, ibl[4]={0,30,60,100};
ps_init (100);
ps_ij (0,0);
ps_ij (1,1);
ps_ij (2,2);
ps_ij (12,17);
ps_ij (79,89);
ps_ij (99,99);
ps_file ("z.ps",nbl,ibl);
}
#endif