Commit df09a1b6 authored by Kirill Terekhov's avatar Kirill Terekhov
parents e27f51ed 5571716c
Pipeline #124 failed with stages
in 7 minutes and 10 seconds
# use the official gcc image, based on debian
# can use versions as well, like gcc:5.2
image: gcc
stages:
- build
- test
build_debug:
stage: build
script:
- mkdir build_debug
- cd build_debug
- cmake -DCOMPILE_TESTS=ON -DUSE_OMP=ON -DCMAKE_CXX_FLAGS="-O0 -g" -DCMAKE_C_FLAGS="-O0 -g" ..
- make VERBOSE=1
artifacts:
paths:
- build_debug/
build_opt:
stage: build
script:
- mkdir build_opt
- cd build_opt
- cmake -DCOMPILE_TESTS=ON -DCOMPILE_EXAMPLES=ON -DUSE_OMP=ON -DCMAKE_CXX_FLAGS="-Ofast -march=native" -DCMAKE_C_FLAGS="-Ofast -march=native" ..
- make VERBOSE=1
artifacts:
paths:
- build_opt/
test_debug:
stage: test
script:
- cd build_debug
- ctest --output-on-failure
dependencies:
- build_debug
test_opt:
stage: test
script:
- cd build_opt
- ctest --output-on-failure
dependencies:
- build_opt
......@@ -16,6 +16,7 @@ option(USE_MPI_P2P "Use MPI point to point functionality, may be faster with har
option(USE_MPI_FILE "Use MPI extension to work with files, may save a lot of memory" ON)
option(USE_MPI2 "Use MPI-2 extensions, useful if your MPI library warns you to use new functions" ON)
option(USE_OMP "Compile with OpenMP support (experimental)" OFF)
option(USE_OPENCL "Use OpenCL where possible (experimental)" OFF)
option(USE_MESH "Compile mesh capabilities" ON)
option(USE_SOLVER "Compile solver capabilities" ON)
......@@ -33,7 +34,6 @@ option(USE_SOLVER_MONDRIAAN "Use Mondriaan for matrix reordering" OFF)
option(USE_SOLVER_PETSC "Use PETSc solvers" OFF)
option(USE_SOLVER_TRILINOS "Use Trilinos solvers" OFF)
option(USE_SOLVER_SUPERLU "Use SuperLU solver" OFF)
#option(USE_AUTODIFF_OPENCL "Use OpenCL for automatic differentiation (under work)" OFF)
#option(USE_AUTODIFF_ASMJIT "Use AsmJit for automatic differentiation" OFF)
#option(USE_AUTODIFF_EXPRESSION_TEMPLATES "Use c++ expression templates for automatic differentiation" OFF)
......@@ -206,13 +206,13 @@ if(USE_SOLVER_SUPERLU)
endif()
endif()
if(USE_AUTODIFF_OPENCL)
if(USE_OPENCL)
find_package(OpenCL)
if(OPENCL_FOUND)
include_directories(${OPENCL_INCLUDE_DIRS})
link_directories(${PETSC_LIBRARY_DIRS})
link_directories(${OpenCL_LIBRARY})
else()
set(USE_AUTODIFF_OPENCL OFF CACHE BOOL "Use OpenCL for automatic differentiation" FORCE)
set(USE_OPENCL OFF CACHE BOOL "Use OpenCL where possible (experimental)" FORCE)
message("OpenCL not found")
endif()
endif()
......
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "inmost.h"
using namespace INMOST;
#ifndef M_PI
......@@ -90,7 +90,7 @@ int main(int argc,char ** argv)
{ // currently only non-distributed meshes are supported by Inner_RCM partitioner
ttt = Timer();
Partitioner * p = new Partitioner(m);
p->SetMethod(Partitioner::Inner_RCM,Partitioner::Partition); // Specify the partitioner
p->SetMethod(Partitioner::INNER_KMEANS,Partitioner::Partition); // Specify the partitioner
p->Evaluate(); // Compute the partitioner and store new processor ID in the mesh
delete p;
BARRIER;
......
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "inmost.h"
using namespace INMOST;
#ifndef M_PI
......@@ -125,7 +125,7 @@ int main(int argc,char ** argv)
{ // Compute mesh partitioning
ttt = Timer();
Partitioner p(m); //Create Partitioning object
p.SetMethod(Partitioner::Inner_RCM,repartition ? Partitioner::Repartition : Partitioner::Partition); // Specify the partitioner
p.SetMethod(Partitioner::INNER_KMEANS,repartition ? Partitioner::Repartition : Partitioner::Partition); // Specify the partitioner
p.Evaluate(); // Compute the partitioner and store new processor ID in the mesh
BARRIER
if( m->GetProcessorRank() == 0 ) std::cout << "Evaluate: " << Timer()-ttt << std::endl;
......
......@@ -332,13 +332,15 @@ namespace INMOST
//free created tag
DeleteTag(indicator,FACE|EDGE);
//11. Restore parallel connectivity, global ids
//ResolveModification();
ResolveShared(true);
ResolveModification();
//12. Let the user update their data
//todo: call back function for New() cells
//13. Delete old elements of the mesh
ApplyModification();
//14. Done
EndModification();
//ExchangeData(hanging_nodes,CELL | FACE,0);
//reorder element's data to free up space
ReorderEmpty(CELL|FACE|EDGE|NODE);
//return number of refined cells
......@@ -640,12 +642,14 @@ namespace INMOST
//free created tag
DeleteTag(indicator,FACE|EDGE);
//todo:
//ResolveModification();
ResolveShared(true);
ResolveModification();
//todo:
//let the user update their data
ApplyModification();
//done
EndModification();
//ExchangeData(hanging_nodes,CELL | FACE,0);
//cleanup null links to hanging nodes
for(ElementType etype = FACE; etype <= CELL; etype = NextElementType(etype))
{
......@@ -666,4 +670,4 @@ namespace INMOST
call_counter++;
return ret != 0;
}
}
\ No newline at end of file
}
......@@ -9,6 +9,7 @@ int main(int argc, char ** argv)
if( argc > 1 )
{
AdaptiveMesh m;
m.SetCommunicator(INMOST_MPI_COMM_WORLD);
m.Load(argv[1]);
//m.SetTopologyCheck(NEED_TEST_CLOSURE);
//m.SetTopologyCheck(PROHIBIT_MULTILINE);
......@@ -29,6 +30,8 @@ int main(int argc, char ** argv)
if( it->Coords()[d] < cmin[d] ) cmin[d] = it->Coords()[d];
}
}
m.AggregateMax(cmax,3);
m.AggregateMin(cmin,3);
r = 1;
for(int d = 0; d < 3; ++d)
{
......@@ -47,18 +50,20 @@ int main(int argc, char ** argv)
numref = 0;
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) if( m.GetLevel(it->self()) < max_levels )
{
it->Centroid(xyz);
it->Barycenter(xyz);
//refine a circle
q = 0;
for(int d = 0; d < 3; ++d)
q += (xyz[d]-cnt[d])*(xyz[d]-cnt[d]);
q = sqrt(q);
if( q < r*(k+1) && q > r*k)
//if( q < 0.02 )
{
indicator[it->self()] = 1;
numref++;
}
}
numref = m.Integrate(numref);
if( numref )
{
std::cout << "k " << k << " refcnt " << refcnt << " " << r*k << " < r < " << r*(k+1) << " numref " << numref << " cells " << m.NumberOfCells() << std::endl;
......@@ -89,7 +94,7 @@ int main(int argc, char ** argv)
numref = 0;
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it) if( m.GetLevel(it->self()) > 0 )
{
it->Centroid(xyz);
it->Barycenter(xyz);
//refine a circle
q = 0;
for(int d = 0; d < 3; ++d)
......@@ -101,6 +106,7 @@ int main(int argc, char ** argv)
numref++;
}
}
numref = m.Integrate(numref);
if( numref )
{
std::cout << "k " << k << " crscnt " << refcnt << " " << r*k << " < r < " << r*(k+1) << " numcrs " << numref << " cells " << m.NumberOfCells() << std::endl;
......@@ -131,11 +137,19 @@ int main(int argc, char ** argv)
{
std::stringstream file;
file << "step_" << k << ".vtk";
file << "step_" << k << ".pvtk";
m.Save(file.str());
}
{
TagInteger tag_owner = m.CreateTag("OWN",DATA_INTEGER,CELL,NONE,1);
TagInteger tag_owner0 = m.GetTag("OWNER_PROCESSOR");
TagInteger tag_stat = m.CreateTag("STAT",DATA_INTEGER,CELL,NONE,1);
for(Mesh::iteratorCell it = m.BeginCell(); it != m.EndCell(); ++it)
{
tag_owner[*it] = tag_owner0[*it];
tag_stat[*it] = it->GetStatus();
}
std::stringstream file;
file << "step_" << k << ".pmf";
m.Save(file.str());
......@@ -143,4 +157,6 @@ int main(int argc, char ** argv)
}
}
else std::cout << "Usage: " << argv[0] << " mesh_file [max_levels=2]" << std::endl;
}
\ No newline at end of file
Mesh::Finalize();
}
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "inmost.h"
using namespace INMOST;
#ifndef M_PI
......@@ -92,7 +92,7 @@ int main(int argc,char ** argv)
{ // currently only non-distributed meshes are supported by Inner_RCM partitioner
ttt = Timer();
Partitioner * p = new Partitioner(m);
p->SetMethod(Partitioner::Inner_RCM,Partitioner::Partition); // Specify the partitioner
p->SetMethod(Partitioner::INNER_KMEANS,Partitioner::Partition); // Specify the partitioner
p->Evaluate(); // Compute the partitioner and store new processor ID in the mesh
delete p;
BARRIER
......@@ -327,4 +327,4 @@ int main(int argc,char ** argv)
#endif
Solver::Finalize(); // Finalize solver and close MPI activity
return 0;
}
\ No newline at end of file
}
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "inmost.h"
using namespace INMOST;
#define MESH_SIZE 32
......@@ -227,7 +227,7 @@ Mesh * ParallelGenerator(INMOST_MPI_Comm comm, int ng, int nx, int ny, int nz)
{
CreateCubeElement(m,verts);
}
else if ((i + j) % 2 == 0) // Create two prism cells
else if ((i + j) % 2 == 0 || ng == 6) // Create two prism cells
{
CreateNWPrismElements(m,verts);
}
......@@ -327,4 +327,4 @@ int main(int argc, char *argv[])
delete mesh;
Mesh::Finalize();
return 0;
}
\ No newline at end of file
}
......@@ -16,6 +16,8 @@ add_executable(Move move.cpp)
add_executable(Convert convert.cpp)
add_executable(SameMeshDifference difference_same.cpp)
add_executable(MeshDifference difference_map.cpp)
add_executable(Kmeans kmeans.cpp)
add_executable(Agglomerate agglomerate.cpp)
add_library(FractureLib fracture.cpp fracture.h)
target_link_libraries(FixFaults inmost)
......@@ -185,6 +187,26 @@ if(USE_MPI)
endif(USE_MPI)
install(TARGETS MeshDifference EXPORT inmost-targets RUNTIME DESTINATION bin)
target_link_libraries(Kmeans inmost)
if(USE_MPI)
message("linking Kmeans with MPI")
target_link_libraries(Kmeans ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(Kmeans PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
install(TARGETS Kmeans EXPORT inmost-targets RUNTIME DESTINATION bin)
target_link_libraries(Agglomerate inmost)
if(USE_MPI)
message("linking Agglomerate with MPI")
target_link_libraries(Agglomerate ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(Agglomerate PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
install(TARGETS Agglomerate EXPORT inmost-targets RUNTIME DESTINATION bin)
set_property(TARGET FractureLib PROPERTY PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/fracture.h")
......
#include "inmost.h"
using namespace INMOST;
//todo: want to separate all faces into those that share edges
//see todo: inside text
int main(int argc, char ** argv)
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " mesh [tag=MATERIAL] [mesh_out=grid.vtk]" << std::endl;
return -1;
}
Mesh::Initialize(&argc,&argv);
std::string tag_name = "MATERIAL";
if( argc > 2) tag_name = std::string(argv[2]);
std::string grid_out = "grid.vtk";
if (argc > 3) grid_out = std::string(argv[3]);
Mesh m;
m.SetCommunicator(INMOST_MPI_COMM_WORLD);
m.Load(argv[1]);
if( !m.HaveTag(tag_name) )
{
std::cout << "mesh does not have tag named " << tag_name << std::endl;
exit(-1);
}
TagInteger mat = m.GetTag(tag_name);
std::cout << "Start:" << std::endl;
std::cout << "Cells: " << m.NumberOfCells() << std::endl;
std::cout << "Faces: " << m.NumberOfFaces() << std::endl;
std::cout << "Edges: " << m.NumberOfEdges() << std::endl;
std::map< int,ElementArray<Cell> > mat_cells;
for(int q = 0; q < m.CellLastLocalID(); ++q) if( m.isValidCell(q) )
{
Cell n = m.CellByLocalID(q);
mat_cells[ mat[n] ].push_back(n);
}
//Unite cells
//todo: split cells that are not connected by face
std::cout << "Unite cells" << std::endl;
int nunited = 0;
for(std::map< int,ElementArray<Cell> >::iterator it = mat_cells.begin();
it != mat_cells.end(); ++it)
{
if( it->second.size() > 1 )
{
mat[Cell::UniteCells(it->second,0)] = it->first;
nunited++;
}
}
std::cout << "united: " << nunited << std::endl;
/*
std::cout << "Unite faces" << std::endl;
std::map< std::pair<int,int>, ElementArray<Face> > faces;
nunited = 0;
for(int q = 0; q < m.FaceLastLocalID(); ++q) if( m.isValidFace(q) )
{
Face n = m.FaceByLocalID(q);
std::pair<int,int> f_cells;
int bc = n.BackCell().LocalID();;
int fc = n.FrontCell().isValid() ? n.FrontCell().LocalID() : -1;
f_cells.first = std::min(bc,fc);
f_cells.second = std::max(bc,fc);
faces[f_cells].push_back(n);
}
std::cout << "computed faces" << std::endl;
m.BeginModification();
//todo: split faces that are not connected by edge
for(std::map< std::pair<int,int>, ElementArray<Face> >::iterator it = faces.begin();
it != faces.end(); ++it)
{
if( it->second.size() > 1 )
{
std::cout << it->first.first << "<->" << it->first.second << " faces " << it->second.size() << std::endl;
Face::UniteFaces(it->second,0);
nunited++;
}
}
m.EndModification();
std::cout << "united: " << nunited << std::endl;
*/
std::cout << "Cells: " << m.NumberOfCells() << std::endl;
std::cout << "Faces: " << m.NumberOfFaces() << std::endl;
std::cout << "Edges: " << m.NumberOfEdges() << std::endl;
m.Save(grid_out);
Mesh::Finalize();
return 0;
}
#include <stdio.h>
#include "inmost.h"
#include <stdio.h>
using namespace INMOST;
......@@ -87,4 +87,4 @@ int main(int argc, char ** argv)
}
return 0;
}
\ No newline at end of file
}
#include <stdio.h>
#include "inmost.h"
#include <stdio.h>
using namespace INMOST;
......
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "inmost.h"
using namespace INMOST;
......
#include "inmost.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "inmost.h"
using namespace INMOST;
......
#include <stdio.h>
#include "inmost.h"
#include <stdio.h>
using namespace INMOST;
......@@ -273,4 +273,4 @@ int main(int argc, char ** argv)
}
return 0;
}
\ No newline at end of file
}
#include "inmost.h"
using namespace INMOST;
//todo: want to separate all faces into those that share edges
//see todo: inside text
struct kdtree
{
struct entry
{
double v[3];
int pos;
};
struct compare
{
int comp;
compare(int c) : comp(c) {}
compare(const compare & b) : comp(b.comp) {}
bool operator () (const entry & a, const entry & b) { return a.v[comp] < b.v[comp]; }
};
entry * set;
kdtree * l, * r;
int size;
double split;
kdtree()
{
size = 0;
set = NULL;
l = NULL;
r = NULL;
}
~kdtree()
{
if( l != NULL ) delete l;
if( r != NULL ) delete r;
set = NULL;
size = 0;
}
void resize(int set_size)
{
clear();
size = set_size;
set = new entry[size];
}
void clear()
{
if( set != NULL ) delete [] set;
size = 0;
}
void build_tree(int comp)
{
if( l != NULL ) {delete l; l = NULL;}
if( r != NULL ) {delete r; r = NULL;}
if( size > 1 )
{
std::sort(set,set+size,compare(comp));
int middle = size/2;
l = new kdtree;
l->set = set;
l->size = middle;
r = new kdtree;
r->set = set + middle;
r->size = size - middle;
split = set[middle].v[comp];
l->build_tree((comp+1)%3);
r->build_tree((comp+1)%3);
}
}
void build(double * coords)
{
for(int k = 0; k < size; ++k)
{
set[k].v[0] = coords[k*3+0];
set[k].v[1] = coords[k*3+1];
set[k].v[2] = coords[k*3+2];
set[k].pos = k;
}
build_tree(0);
}
void closest_tree(double p[3], int & pos, double & min_dist, int comp)
{
if( size == 0 )
{
std::cout << "size is " << size << std::endl;
}
else if ( size == 1 )
{
double v[3];
v[0] = (set[0].v[0] - p[0]);
v[1] = (set[0].v[1] - p[1]);
v[2] = (set[0].v[2] - p[2]);
double dist = v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
if (dist < min_dist)
{
min_dist = dist;
pos = set[0].pos;
}
}
else
{
if (p[comp] < split)
{
// search left first
l->closest_tree(p, pos, min_dist, (comp+1)%3);
if (p[comp] + min_dist >= split)
r->closest_tree(p, pos, min_dist, (comp+1)%3);
}
else
{
// search right first
r->closest_tree(p, pos, min_dist, (comp+1)%3);
if (p[comp] - min_dist <= split)
l->closest_tree(p, pos, min_dist, (comp+1)%3);
}
}
}
int closest(double p[3])
{
double min_dist = std::numeric_limits<double>::max();
int ret;
closest_tree(p,ret,min_dist,0);
return ret;
}
};
int main(int argc, char ** argv)
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " mesh clusters [clusters=10] [max_iterations=10] [mesh_out=grid.vtk]" << std::endl;
return -1;
}
Mesh::Initialize(&argc,&argv);
int K = 10;
if( argc > 2 ) K = atoi(argv[2]);
int max_iterations = 10;
if( argc > 3 ) max_iterations = atoi(argv[3]);
if( K == 0 )
std::cout << "Problem with number of clusters argument " << argv[2] << std::endl;
if( max_iterations == 0 )
std::cout << "Problem with max iterations argument " << argv[3] << std::endl;
std::string grid_out = "grid.vtk";
if (argc > 4) grid_out = std::string(argv[4]);
Mesh m;
m.SetCommunicator(INMOST_MPI_COMM_WORLD);
m.Load(argv[1]);
std::cout << "Start:" << std::endl;
std::cout << "Cells: " << m.NumberOfCells() << std::endl;
std::cout << "Faces: " << m.NumberOfFaces() << std::endl;
std::cout << "Edges: " << m.NumberOfEdges() << std::endl;
double tt = Timer();
//There seems to be a problem with the mesh
/*
int fixed = 0;
for (Mesh::iteratorFace f = m.BeginFace(); f != m.EndFace(); ++f)
{
if (f->FixNormalOrientation())
fixed++;
}
std::cout << "Time to fix normals: " << Timer() - tt << std::endl;
std::cout << "Total face normals fixed: " << fixed << std::endl;
*/
int total_points = 0;
#if defined(USE_OMP)
#pragma omp parallel for reduction(+:total_points)
#endif
for(int q = 0; q < m.CellLastLocalID(); ++q) if( m.isValidCell(q) )
{
Cell n = m.CellByLocalID(q);
if( n->GetStatus() != Element::Ghost ) total_points++;
}
std::vector< int > points_node(total_points);
std::vector< double > points_center(total_points*3);
std::vector< int > points_cluster(total_points,-1);
int k = 0;
for(int q = 0; q < m.CellLastLocalID(); ++q) if( m.isValidCell(q) )
{
Cell n = m.CellByLocalID(q);
if( n->GetStatus() != Element::Ghost ) points_node[k++] = n->LocalID();
}
#if defined(USE_OMP)
#pragma omp parallel for
#endif
for(int q = 0; q < total_points; ++q)
{
Cell n = m.CellByLocalID(points_node[q]);