Commit afa4d294 by Kirill Terekhov

Add Examples

Add Examples/ADVDIFF example for advection-diffusion

Add exotic grid generators to Examples/GridTools

Add Examples/TestSuits for tests of diffusion and advection-diffusion
problems
parent f4860bab
Pipeline #130 passed with stages
in 10 minutes 15 seconds
......@@ -145,7 +145,7 @@ int main(int argc,char ** argv)
tag_BC[*face][1] = 0; //neumann
tag_BC[*face][2] = func(x,0);//face->Mean(func, 0);
}
}`
}
if(m->HaveTag("REFERENCE_SOLUTION") )
phi_ref = m->GetTag("REFERENCE_SOLUTION");
......@@ -304,44 +304,47 @@ int main(int argc,char ** argv)
ttt = Timer();
Tag error = m->CreateTag("error",DATA_REAL,CELL,NONE,1);
double err_C = 0.0, err_L2 = 0.0;
if( phi_ref.isValid() )
{
Tag error = m->CreateTag("error",DATA_REAL,CELL,NONE,1);
double err_C = 0.0, err_L2 = 0.0;
#if defined(USE_OMP)
#pragma omp parallel
#endif
{
double local_err_C = 0;
{
double local_err_C = 0;
#if defined(USE_OMP)
#pragma omp for reduction(+:err_L2)
#endif
for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell )
{
Cell cell = Cell(m,ComposeCellHandle(icell));
if( cell->GetStatus() != Element::Ghost )
for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell )
{
double old = phi[cell];
double exact = phi_ref[cell];
double res = Update[Phi.Index(cell)];
double sol = old-res;
double err = fabs (sol - exact);
if (err > local_err_C) local_err_C = err;
err_L2 += err * err * cell->Volume();
cell->Real(error) = err;
phi[cell] = sol;
Cell cell = Cell(m,ComposeCellHandle(icell));
if( cell->GetStatus() != Element::Ghost )
{
double old = phi[cell];
double exact = phi_ref[cell];
double res = Update[Phi.Index(cell)];
double sol = old-res;
double err = fabs (sol - exact);
if (err > local_err_C) local_err_C = err;
err_L2 += err * err * cell->Volume();
cell->Real(error) = err;
phi[cell] = sol;
}
}
}
#if defined(USE_OMP)
#pragma omp critical
#endif
{
if( local_err_C > err_C ) err_C = local_err_C;
{
if( local_err_C > err_C ) err_C = local_err_C;
}
}
err_C = m->AggregateMax(err_C); // Compute the maximal C norm for the error
err_L2 = sqrt(m->Integrate(err_L2)); // Compute the global L2 norm for the error
if( m->GetProcessorRank() == 0 ) std::cout << "err_C = " << err_C << std::endl;
if( m->GetProcessorRank() == 0 ) std::cout << "err_L2 = " << err_L2 << std::endl;
}
err_C = m->AggregateMax(err_C); // Compute the maximal C norm for the error
err_L2 = sqrt(m->Integrate(err_L2)); // Compute the global L2 norm for the error
if( m->GetProcessorRank() == 0 ) std::cout << "err_C = " << err_C << std::endl;
if( m->GetProcessorRank() == 0 ) std::cout << "err_L2 = " << err_L2 << std::endl;
}
BARRIER;
if( m->GetProcessorRank() == 0 ) std::cout << "Compute true residual: " << Timer()-ttt << std::endl;
......
......@@ -165,7 +165,7 @@ int main(int argc,char ** argv)
#endif
{
rMatrix NK, R, Areas;
rMatrix x(1,3), xf(1,3), n(1,3)
rMatrix x(1,3), xf(1,3), n(1,3);
double area; //area of the face
double volume; //volume of the cell
Areas.Zero();
......@@ -193,14 +193,14 @@ int main(int argc,char ** argv)
faces[k].Centroid(xf.data());
faces[k].OrientedUnitNormal(cell->self(),n.data());
// assemble matrix of directions
R(k,k+1,0,3) = (yf-x)*area;
R(k,k+1,0,3) = (xf-x)*area;
// assemble matrix of co-normals
NK(k,k+1,0,3) = n*K;
Areas(k,k) = area;
} //end of loop over faces
W = NK*(NK.Transpose()*R).Invert(true).first*NK.Transpose(); //stability part
W+=(rMatrix::Unit(NF) - R*(R.Transpose()*R).Invert(true).first*R.Transpose())*
(2.0/(static_cast<real>(NF)*vP)*(NK*K.Invert(true).first*NK.Transpose()).Trace());
(2.0/(static_cast<real>(NF)*volume)*(NK*K.Invert(true).first*NK.Transpose()).Trace());
W = Areas*W*Areas;
//access data structure for gradient matrix in mesh
real_array store_W = cell->RealArrayDV(tag_W);
......
project(ADVDIFF)
set(SOURCE main.cpp stencil.cpp checks.cpp limited_average.cpp save_mesh.cpp conv_diff.cpp)
set(HEADER stencil.h checks.h limited_average.h save_mesh.h conv_diff.h)
add_executable(ADVDIFF ${SOURCE} ${HEADER})
target_link_libraries(ADVDIFF inmost)
if(USE_SOLVER)
if(USE_SOLVER_ANI)
message("linking ADVDIFF with ani3d and BLAS")
target_link_libraries(ADVDIFF ani3d ${BLAS_LIBRARIES})
if(BLAS_LINKER_FLAGS)
set_target_properties(ADVDIFF PROPERTIES LINK_FLAGS "${BLAS_LINKER_FLAGS}")
endif()
endif()
if(USE_SOLVER_PETSC)
message("linking ADVDIFF with PETSc")
target_link_libraries(ADVDIFF ${PETSC_LIBRARIES})
endif()
if(USE_SOLVER_TRILINOS)
message("linking ADVDIFF with Trilinos")
target_link_libraries(ADVDIFF ${Trilinos_LIBRARIES} ${Trilinos_TPL_LIBRARIES})
endif()
if(USE_SOLVER_METIS)
message("linking ADVDIFF with Metis")
target_link_libraries(ADVDIFF ${METIS_LIBRARIES})
endif()
if(USE_SOLVER_MONDRIAAN)
message("linking ADVDIFF with Mondriaan")
target_link_libraries(ADVDIFF ${MONDRIAAN_LIBRARIES})
endif()
if(USE_SOLVER_SUPERLU)
message("linking ADVDIFF with SuperLU")
target_link_libraries(ADVDIFF ${SUPERLU_LIBRARIES})
endif()
endif()
if(USE_PARTITIONER)
if(USE_PARTITIONER_ZOLTAN)
message("linking ADVDIFF with Zoltan")
target_link_libraries(ADVDIFF ${ZOLTAN_LIBRARIES})
endif()
if(USE_PARTITIONER_PARMETIS)
message("linking ADVDIFF with ParMETIS")
target_link_libraries(ADVDIFF ${PARMETIS_LIBRARIES})
endif()
endif()
if(USE_MPI)
message("linking ADVDIFF with MPI")
target_link_libraries(ADVDIFF ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(ADVDIFF PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
install(TARGETS ADVDIFF EXPORT inmost-targets RUNTIME DESTINATION bin)
\ No newline at end of file
#include "checks.h"
using namespace INMOST;
//shortcuts
typedef Storage::bulk bulk;
typedef Storage::enumerator enumerator;
typedef Storage::real real;
bool check_flux_properties(int i, const variable & flux, const std::string & name, bool print)
{
bool test = true;
const Sparse::Row & r = flux.GetRow();
for(int k = 0; k < (int)r.Size(); ++k)
{
if( r.GetIndex(k) == i ) //diagonal element
{
if( r.GetValue(k) < 0.0 )
{
if( print ) std::cout << "flux " << name << " gives negative diagonal contribution to " << i << "-th variable" << std::endl;
test = false;
}
}
else //off-diagonal element
{
if( r.GetValue(k) > 0.0 )
{
if( print ) std::cout << "flux " << name << " gives positive off-diagonal contribution to " << i << "-th variable" << std::endl;
test = false;
}
}
}
if( !test && print )
{
r.Print();
//scanf("%*c");
}
return test;
}
bool check_matrix_properties(const Sparse::Matrix & A, bool print)
{
bool is_m_matrix = true;
enumerator mbeg,mend;
A.GetInterval(mbeg,mend);
for(enumerator i = mbeg; i < mend; ++i)
{
const Sparse::Row & r = A[i];
real rowsum = 0.0;
for(enumerator k = 0; k < r.Size(); ++k)
{
rowsum += r.GetValue(k);
if( r.GetIndex(k) != i )
{
if( r.GetValue(k) > 0.0 )
{
if( print ) std::cout << "Off-diagonal element (" << i << "," << r.GetIndex(k) << ") is positive: " << r.GetValue(k) << std::endl;
is_m_matrix = false;
}
}
else
{
if( r.GetValue(k) < 0.0 )
{
if( print ) std::cout << "Diagonal element (" << i << "," << r.GetIndex(k) << ") is negative: " << r.GetValue(k) << std::endl;
is_m_matrix = false;
}
}
}
if( rowsum < -1.0e-9 )
{
std::cout << "Row-sum is " << rowsum << std::endl;
is_m_matrix = false;
}
}
if( !is_m_matrix ) std::cout << "Not an M-matrix" << std::endl;
return is_m_matrix;
}
\ No newline at end of file
#ifndef __CHECKS_H
#define __CHECKS_H
#include "inmost.h"
/// Check that this will give M-matrix for i-th unknown.
/// @param i Position of the diagonal unknown.
/// @param flux Computed flux expression with derivatives.
/// @param name Name of the flux to be printed out.
/// @param print Print out errors.
bool check_flux_properties(int i, const INMOST::variable & flux, const std::string & name, bool print = true);
///Check monotonicity of the matrix.
/// @param A Input matrix to be checked.
/// @param print Print out errors.
bool check_matrix_properties(const INMOST::Sparse::Matrix & A, bool print = true);
#endif
\ No newline at end of file
#ifndef __CONV_DIFF_H
#define __CONV_DIFF_H
#include "inmost.h"
#include "limited_average.h"
///Comment me
class ConvectionDiffusion
{
INMOST::Mesh * m;
//tags for convection
INMOST::Tag tag_CONV_CB; // Coefficients for upwind corrector at back cell
INMOST::Tag tag_CONV_EB; // Elements for upwind corrector at back cell
INMOST::Tag tag_CONV_RB; // Right hand side for upwind corrector at back cell
INMOST::Tag tag_CONV_CF; // Coefficients for upwind corrector at front cell
INMOST::Tag tag_CONV_EF; // Elements for upwind corrector at front cell
INMOST::Tag tag_CONV_RF; // Right hand side for upwind corrector at front cell
INMOST::Tag tag_CONV_CU; // Upwind coefficient
INMOST::Tag tag_CONV_RU; // Right hand side for upwind
INMOST::Tag tag_CONV_EU; // Upstream cell
INMOST::Tag tag_CONV_F; // A flag indicating is there
// a full nonlinear part (internal = 2),
// a one-sided correction (on outlet BC = 1),
// no correction (on inlet BC = 0)
INMOST::Tag tag_CONV_VU; // Two vectors for upwind correctors at back and front cells
//tags for diffusion
INMOST::Tag tag_DIFF_CB; // Coefficients for transversal correction at back cell
INMOST::Tag tag_DIFF_EB; // Elements for transversal correction at back cell
INMOST::Tag tag_DIFF_RB; // Right hand side for two transversal correction at back cell
INMOST::Tag tag_DIFF_CF; // Coefficients for transversal correction at front cell
INMOST::Tag tag_DIFF_EF; // Elements for transversal correction at front cell
INMOST::Tag tag_DIFF_RF; // Right hand side for two transversal correction at back cell
INMOST::Tag tag_DIFF_CT; // Two-point transmissibility
INMOST::Tag tag_DIFF_RT; // Two-point right hand side
INMOST::Tag tag_DIFF_F; // A flag indicating is there
// a full nonlinear part (internal = 3),
// no nonlinear part (internal = 2),
// a one-sided correction (on BC = 1),
// no one-sided correction (on BC = 0)
INMOST::Tag tag_DIFF_VT; // Vector for transversal correction to two-point part
INMOST::Tag tag_U; // Normal velocity vector on faces
INMOST::Tag tag_K; // Diffusion tensor
INMOST::Tag tag_BC; // Boundary conditions
INMOST::MarkerType build_flux; // defines wheather to build flux approximation on interface in parallel
INMOST::MarkerType boundary_face; //defines boundary faces in parallel
bool initialization_failure; //there is a failure during intialization
bool perform_correction_diffusion; //add nonlinear correction to two-point flux
bool perform_correction_convection; //add nonlinear correction to single point upstream
public:
ConvectionDiffusion(INMOST::Mesh * _m, INMOST::Tag _tag_U, INMOST::Tag _tag_K, INMOST::Tag _tag_BC, INMOST::MarkerType _boundary_face, bool correct_convection, bool correct_diffusion);
bool Failure() const;
~ConvectionDiffusion();
void DiffusionFluxes(INMOST::abstract_variable & param, INMOST::Face fKL, INMOST::variable & fluxT, INMOST::variable & corrK, INMOST::variable & corrL, INMOST::variable & corrK_cK, INMOST::variable & corrL_cL) const;
void AdvectionFluxes(INMOST::abstract_variable & param, INMOST::Face fKL, INMOST::variable & fluxT, INMOST::variable & corrK, INMOST::variable & corrL, INMOST::variable & corrK_cK, INMOST::variable & corrL_cL) const;
void Averaging(SchemeType scheme_type, INMOST_DATA_REAL_TYPE regularization, const INMOST::variable & fluxT, const INMOST::variable & corrK, const INMOST::variable & corrL, const INMOST::variable & corrK_cK, const INMOST::variable & corrL_cL, INMOST::variable & fluxK, INMOST::variable & fluxL, bool boundary) const;
bool BuildFlux(INMOST::Face f) const;
};
#endif //__CONV_DIFF_H
\ No newline at end of file
#ifndef __LIMITED_AVERAGE_H
#define __LIMITED_AVERAGE_H
#include "inmost.h"
/// Specification of scheme type.
enum SchemeType
{
MPFA, //< Linear scheme with algebraic mean.
NTPFA, //< With account for derivatives in convex combination. Fast but can violate positivity.
NTPFA_PICARD, //< Do not account for derivatives in convex combination. Always positive with good right hand side.
NMPFA_VAN_LEER, //< Satisfy discrete maximum principle on convergence, non-Lipschitz-continuous before regularization. With account for derivatives in convex combination.
NMPFA_VAN_LEER_PICARD, //< Satisfy discrete maximum principle on convergence, non-Lipschitz-continuous before regularization. No account for derivatives in convex combination.
NMPFA_VAN_LEER_DUALFLUX, //< Satisfy discrete maximum principle on each iteration, non-Lipschitz-continuous before regularization. No account for derivatives in convex combination.
NMPFA_VAN_ALBADA, //< Should satisfy TVD, continuous, single flux definition. With account for derivatives in convex combination.
NMPFA_VAN_ALBADA_PICARD, //< Should satisfy TVD, continuous, single flux definition. No account for derivatives in convex combination.
NMPFA_VAN_ALBADA_DUALFLUX, //< Should satisfy TVD, continuous, dual flux definition. No account for derivatives in convex combination.
NMPFA_VAN_ALBADA_CORRECTED, //< Should satisfy discrete maximum principle, non-Lipschitz-continuous before regularization. With account for derivatives in convex combination.
NMPFA_VAN_ALBADA_CORRECTED_PICARD, //< Should satisfy discrete maximum principle, non-Lipschitz-continuous before regularization. No account for derivatives in convex combination.
NMPFA_VAN_ALBADA_CORRECTED_DUALFLUX, //< Should satisfy discrete maximum principle, non-Lipschitz-continuous before regularization. No account for derivatives in convex combination.
NMPFA_QUADRATIC, //< Should satisfy TVD
NMPFA_QUADRATIC_CORRECTED //< Should satisfy discrete maximum principle
};
/// Limited averaging function, computes and returns the fluxes inside.
/// @param fluxK Flux for back cell.
/// @param fluxL Flux for front cell.
/// @param outK Flux for the back cell.
/// @param outL FLux for the front cell. May be different from outK.
/// @param regularization Regularization parameter in computation of expression
/// @param scheme_type Method for the flux computation, see SchemeType.
void LimitedAverageNonlinearMultiPoint(const INMOST::variable & fluxK,
const INMOST::variable & fluxL,
INMOST::variable & outK,
INMOST::variable & outL,
INMOST::Storage::real regularization,
SchemeType scheme_type);
/// Function that performs non-linear weighted convex combination of two fluxes in
/// a style of non-linear two-point flux approximation.
/// Non-linear two-point flux approximation has positivity-preserving property.
/// Depending on the template type it will account or not for derivatives in
/// convex combination, which may result in faster convergence but loss of
/// positivity-preserving property.
/// @param fluxK Flux for back cell.
/// @param fluxL Flux for front cell.
/// @param fluxK_cK Flux for back cell only with back cell.
/// @param fluxK_cL Flux for back cell only with front cell.
/// @param fluxL_cK Flux for front cell only with back cell.
/// @param fluxL_cL Flux for front cell only with front cell.
/// @param outK Flux for the back cell.
/// @param outL FLux for the front cell. May be different from outK.
/// @param regularization Regularization parameter in computation of expression.
void LimitedAverageNonlinearTwoPoint(const INMOST::variable & fluxK,
const INMOST::variable & fluxL,
const INMOST::variable & fluxK_cK,
const INMOST::variable & fluxL_cL,
INMOST::variable & outK,
INMOST::variable & outL,
INMOST::Storage::real regularization,
SchemeType scheme_type);
#endif
\ No newline at end of file
SET GRIDGEN=..\build64_2010_INMOST\Examples\GridGen\Release\GridGen.exe
SET GENERATORS_FOLDER= ..\build64_2010_DiscretizationToolkit\Grids\generators\Release
:: quad grid
%GRIDGEN% 4 %1 %1 1 grid.pmf
:: %GRIDGEN% 4 80 81 1 grid.pmf
:: triangular grid
:: %GRIDGEN% 3 %1 %1 1 grid.pmf
:: hex grid
:: %GENERATORS_FOLDER%\hex_grid.exe %1
:: acute grid
:: %GENERATORS_FOLDER%\acute_grid.exe %1
:: nonconvex grid
:: %GENERATORS_FOLDER%\nonconvex_grid.exe %1
:: (advection only) discontinuous dirichlet condition problem
:: %GENERATORS_FOLDER%\adv_test00.exe grid.pmf grid_out.pmf
:: (advection only) zalesak disc rotation
:: %GENERATORS_FOLDER%\adv_test01.exe grid.pmf grid_out.pmf 4
:: (advection only) enright disc
:: %GENERATORS_FOLDER%\adv_test02.exe grid.pmf grid_out.pmf 4
:: (diffusion only) oblique barrier problem, linear solution
:: %GENERATORS_FOLDER%\fvca5_test7.exe grid.pmf grid_out.pmf
:: (advection-diffusion) oblique barrier problem, linear solution
:: %GENERATORS_FOLDER%\fvca5_test7_adv.exe grid.pmf grid_out.pmf
:: (diffusion only) mild anisotropy test2
:: %GENERATORS_FOLDER%\fvca5_test1_2.exe grid.pmf grid_out.pmf
:: (advection-reaction-diffusion) discontinuous
%GENERATORS_FOLDER%\adv_test03.exe grid.pmf grid_out.pmf
:: (diffusion with unsymmetric tensor)
:: %GENERATORS_FOLDER%\wugao_test3.exe grid.pmf grid_out.pmf
:: (advection-diffusion with unsymmetric tensor)
:: %GENERATORS_FOLDER%\wugao_test3_adv.exe grid.pmf grid_out.pmf
:: (dmp test)
:: %GENERATORS_FOLDER%\dmp_grid.exe .\grid.pmf 0.6 0 1 1 1 1000
::mpiexec -np 4 .\Release\NFVADV.exe .\grid_out.pmf %2
.\Release\NFVADV.exe .\grid_out.pmf %2
GRIDGEN=../INMOST/Examples/GridGen/GridGen
GENERATORS_FOLDER=../DiscretizationToolkit/Grids/generators
# quad grid
#${GRIDGEN} 4 $1 $1 1 grid.pmf
# triangular grid
#${GRIDGEN} 3 $1 $1 1 grid.pmf
# hex grid
${GENERATORS_FOLDER}/hex_grid $1
# acute grid
#${GENERATORS_FOLDER}/acute_grid $1
# nonconvex grid
#${GENERATORS_FOLDER}/nonconvex_grid $1
# discontinuous dirichlet condition problem
#${GENERATORS_FOLDER}/adv_test00 grid.pmf grid_out.pmf
# zalesak disc rotation
${GENERATORS_FOLDER}/adv_test01 grid.pmf grid_out.pmf 4
./NFVADV grid_out.pmf $2
#include "save_mesh.h"
std::string SaveMesh(INMOST::Mesh * m, std::string prefix, OutputMeshFormat format)
{
std::string file = prefix;
switch(format)
{
case VTK:
if( m->GetProcessorsNumber() == 1 )
prefix += ".vtk";
else
prefix += ".pvtk";
break;
case GMV:
prefix += ".gmv";
break;
case PMF:
prefix += ".pmf";
break;
case XML:
prefix += ".xml";
break;
}
m->Save(prefix);
return prefix;
}
std::string SaveMesh(INMOST::Mesh * m, std::string prefix, int counter, OutputMeshFormat format)
{
std::stringstream prefix_counter;
prefix_counter << prefix << std::setw(5) << std::setfill('0') << counter;
return SaveMesh(m,prefix_counter.str(),format);
}
#ifndef _SAVE_MESH_H
#define _SAVE_MESH_H
#include "inmost.h"
/// Specification of output format.
enum OutputMeshFormat
{
PMF, //< Internal binary format.
GMV, //< Compatible with General Mesh Viewer and Visit.
VTK, //< Compatible with Paraview and Visit.
XML //< Internal user-friendly ascii format based on xml.
};
/// Save provided mesh in chosen format with provided prefix.
/// @param m Mesh to be saved.
/// @param prefix Name of the mesh without format specification.
/// @param format Format of the mesh.
std::string SaveMesh(INMOST::Mesh * m, std::string prefix, OutputMeshFormat format);
/// Save provided mesh in chosen format with provided prefix and counter.
/// @param m Mesh to be saved.
/// @param prefix Name of the mesh without counter and format specification.
/// @param counter The number will be attached to prefix.
/// @param format Format of the mesh.
std::string SaveMesh(INMOST::Mesh * m, std::string prefix, int counter, OutputMeshFormat format);
#endif //_SAVE_MESH_H
\ No newline at end of file
#ifndef __STENCIL_H
#define __STENCIL_H
#include "inmost.h"
enum StencilType
{
CONVECTION,
DIFFUSION
};
///Structure that helps to input information for stencil computation.
struct Stencil
{
INMOST::Storage::real v[3]; //< direction
INMOST::Storage::real_array coefs; //< stencil coefficients
INMOST::Storage::reference_array elems; //< stencil elements
INMOST::Storage::real * rhs; //< right hand side
INMOST::Storage::real sign; //< triplet sign
StencilType type; //< type of requested stencil
bool computed; //< indicates whether the stencil was found
bool nonnegative; //< indicates that all the coefficients are positive
};
/// Find triplet in current cell, currently uses nearest neighbours.
///TODO: allow for consideration of multiple directions of gradient.
/// @param cK Cell in which to seek the gradient.
/// @param compute A set of stencils to be computed.
/// @param tag_BC Tag for boundary conditions.
/// @param tag_K Tag for diffusion tensor.
/// @param tag_iT Tag for interpolation tensor (must be private to process in OpenMP).
/// @param tag_iC Tag for interpolation correction (must be private to process in OpenMP).
/// @param tag_U Tag for velocity value.
/// @param boundary_marker Marker for boundary faces.
/// @param bridge Type of elements to be used as bridge to cells in layers.
/// @param regularization Regularizer for degenerate diffusion.
/// @param max_layers Maximum number of layers to be considered.
bool find_stencils(INMOST::Cell cK,
std::vector<Stencil> & compute,
INMOST::Tag tag_BC,
INMOST::Tag tag_K,
INMOST::Tag tag_iT,
INMOST::Tag tag_iC,
//INMOST::Tag tag_U,
INMOST::MarkerType boundary_marker,
INMOST::ElementType bridge,
INMOST::Storage::real regularization,
int max_layers);
#endif //__STENCIL_H
\ No newline at end of file
......@@ -17,6 +17,7 @@ if(USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
add_subdirectory(ADFVDiscr)
add_subdirectory(ADMFD)
add_subdirectory(ADVDIFF)
add_subdirectory(TestSuite)
add_subdirectory(MFD-ES)
endif(USE_AUTODIFF AND USE_SOLVER AND USE_MESH)
#add_subdirectory(OctreeCutcell)
......
#include "inmost.h"
using namespace INMOST;
//const Storage::real pi = 3.1415926535897932384626433832795;
const Storage::real eps = 1.0e-6;
std::string problem_name = "discontinuous_4zones";
int main(int argc, char ** argv)
{
if( argc < 3 )
{
std::cout << "Usage: " << argv[0] << " mesh mesh_out [lambda=100]" << std::endl;
return 0;
}
Mesh * m = new Mesh;
m->SetFileOption("VERBOSITY","2");
try{m->Load(argv[1]);} catch(...) { std::cout << "Cannot load the mesh " << argv[1] << std::endl; return -1;}
Mesh::GeomParam t;
t[MEASURE] = FACE;
t[ORIENTATION] = FACE;
t[NORMAL] = FACE;
t[CENTROID] = CELL | FACE | EDGE | NODE;
m->PrepareGeometricData(t);
double max[3] = {-1.0e20, -1.0e20, -1.0e20}, min[3] = {1.0e20,1.0e20,1.0e20};
Storage::real c[3] = {0,0,0}, nrm[3] = {0,0,0};
for(Mesh::iteratorNode it = m->BeginNode(); it != m->EndNode(); ++it)
{
it->Centroid(c);
if( c[0] > max[0] ) max[0] = c[0];
if( c[1] > max[1] ) max[1] = c[1];
if( c[2] > max[2] ) max[2] = c[2];
if( c[0] < min[0] ) min[0] = c[0];
if( c[1] < min[1] ) min[1] = c[1];
if( c[2] < min[2] ) min[2] = c[2];
}
if( max[0] <= min[0] ) {std::cout << "strange X " << min[0] << ":" << max[0] << std::endl; return -1;}
if( max[1] <= min[1] ) {std::cout << "strange Y " << min[1] << ":" << max[1] << std::endl; return -1;}
if( max[2] <= min[2] )
{
//2d mesh
if( m->GetDimensions() == 3 )
{
//offset from z-plane
min[2] -= 0.0001;
max[2] += 0.0001;
}
else
{
min[2] = -0.0001;
max[2] = +0.0001;
}
}
std::cout << "Mesh bounds: " << min[0] << ":" << max[0] << " " << min[1] << ":" << max[1] << " " << min[2] << ":" << max[2] << std::endl;
double lambda = 100;
if( argc > 3 ) lambda = atof(argv[3]);
std::cout << "Lambda is: " << lambda << std::endl;
if( m->HaveTag("PERM") ) m->DeleteTag(m->GetTag("PERM"));
if( m->HaveTag("MATERIAL") ) m->DeleteTag(m->GetTag("MATERIAL"));
</