Commit 6a0126bc by Kirill Terekhov

Fixes and updates

Replace algorithms for computation of barycenter, volume, area, normal.
Unit test for algorithms. Separate algorithm for computation of
orientation of faces.

Swap algorithm for variables for a faster matrix inversion algorithm.
Minor optimization for Matrix::Solve, more general templates for
multiplication.

Add a grid tool to split non-planar faces.
parent f23b08df
......@@ -6,6 +6,7 @@ add_executable(UniteFaces unite_faces.cpp)
add_executable(Dual dual.cpp)
add_executable(Slice slice.cpp)
add_executable(SliceFunc slice_func.cpp)
add_executable(SplitNonplanar split_nonplanar.cpp)
target_link_libraries(FixFaults inmost)
if(USE_MPI)
......@@ -71,6 +72,15 @@ endif(USE_MPI)
install(TARGETS SliceFunc EXPORT inmost-targets RUNTIME DESTINATION bin)
target_link_libraries(SplitNonplanar inmost)
if(USE_MPI)
message("linking SplitNonplanar with MPI")
target_link_libraries(SplitNonplanar ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(SplitNonplanar PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
install(TARGETS SplitNonplanar EXPORT inmost-targets RUNTIME DESTINATION bin)
......@@ -19,7 +19,7 @@ int main(int argc, char ** argv)
Mesh::GeomParam table;
table[ORIENTATION] = FACE;
table[CENTROID] = FACE | CELL;
table[BARYCENTER] = FACE | CELL | EDGE;
A.PrepareGeometricData(table);
......@@ -28,13 +28,13 @@ int main(int argc, char ** argv)
for(Mesh::iteratorCell it = A.BeginCell(); it != A.EndCell(); ++it)
{
real cnt[3];
it->Centroid(cnt);
it->Barycenter(cnt);
it->RemoteReference(cell2node) = RemoteHandleType(&B,B.CreateNode(cnt).GetHandle());
}
for(Mesh::iteratorFace it = A.BeginFace(); it != A.EndFace(); ++it) if( it->Boundary() )
{
real cnt[3];
it->Centroid(cnt);
it->Barycenter(cnt);
it->RemoteReference(cell2node) = RemoteHandleType(&B,B.CreateNode(cnt).GetHandle());
}
//add corner nodes
......@@ -54,7 +54,7 @@ int main(int argc, char ** argv)
{
corners++;
it->SetMarker(corner);
it->Centroid(cnt);
it->Barycenter(cnt);
it->RemoteReference(cell2node) = RemoteHandleType(&B,B.CreateNode(cnt).GetHandle());
}
}
......@@ -66,7 +66,7 @@ int main(int argc, char ** argv)
{
corners++;
it->SetMarker(corner);
it->Centroid(cnt);
it->Barycenter(cnt);
it->RemoteReference(cell2node) = RemoteHandleType(&B,B.CreateNode(cnt).GetHandle());
}
else if( ncorners == 2 )
......@@ -75,9 +75,9 @@ int main(int argc, char ** argv)
Node n1 = edges[0]->getBeg() == it->self() ? edges[0]->getEnd() : edges[0]->getBeg();
Node n2 = edges[1]->getBeg() == it->self() ? edges[1]->getEnd() : edges[1]->getBeg();
real cnt1[3], cnt2[3], r1[3],r2[3], l, dot;
it->Centroid(cnt);
n1->Centroid(cnt1);
n2->Centroid(cnt2);
it->Barycenter(cnt);
n1->Barycenter(cnt1);
n2->Barycenter(cnt2);
r1[0] = cnt[0] - cnt1[0];
r1[1] = cnt[1] - cnt1[1];
r1[2] = cnt[2] - cnt1[2];
......@@ -98,7 +98,7 @@ int main(int argc, char ** argv)
{
corners++;
it->SetMarker(corner);
it->Centroid(cnt);
it->Barycenter(cnt);
it->RemoteReference(cell2node) = RemoteHandleType(&B,B.CreateNode(cnt).GetHandle());
}
}
......
......@@ -1483,6 +1483,7 @@ namespace INMOST
return *this;
}
template<typename Var>
template<typename typeB>
Matrix<typename Promote<Var,typeB>::type>
......@@ -1503,6 +1504,43 @@ namespace INMOST
return ret;
}
/*
template<typename Var>
template<typename typeB>
Matrix<typename Promote<Var, typeB>::type>
AbstractMatrix<Var>::operator*(const AbstractMatrix<typeB> & other) const
{
const enumerator b = 32;
assert(Cols() == other.Rows());
Matrix<typename Promote<Var, typeB>::type> ret(Rows(), other.Cols()); //check RVO
for (enumerator i0 = 0; i0 < Rows(); i0+=b) //loop rows
{
for (enumerator j0 = 0; j0 < other.Cols(); j0 += b) //loop columns
{
enumerator i0e = std::min(i0+b,Rows());
enumerator j0e = std::min(j0+b,other.Cols());
for (enumerator i = i0; i < i0e; ++i)
for(enumerator j = j0; j < j0e; ++j)
ret(i,j) = 0.0;
for (enumerator k0 = 0; k0 < Cols(); k0+=b)
{
enumerator k0e = std::min(k0+b,Cols());
for (enumerator i = i0; i < i0e; ++i)
{
for (enumerator k = k0; k < k0e; ++k)
{
for(enumerator j = j0; j < j0e; ++j)
assign(ret(i, j),ret(i, j)+(*this)(i, k)*other(k, j));
}
}
}
}
}
return ret;
}
*/
template<typename Var>
template<typename typeB>
AbstractMatrix<Var> &
......@@ -1594,6 +1632,15 @@ namespace INMOST
{
// for A^T B
assert(Rows() == B.Rows());
/*
if( Rows() != Cols() )
{
Matrix<Var> At = this->Transpose(); //m by n matrix
return (At*(*this)).Solve(At*B,print_fail);
}
Matrix<typeB> AtB = B; //m by l matrix
Matrix<Var> AtA = (*this); //m by m matrix
*/
Matrix<Var> At = this->Transpose(); //m by n matrix
Matrix<typename Promote<Var,typeB>::type> AtB = At*B; //m by l matrix
Matrix<Var> AtA = At*(*this); //m by m matrix
......@@ -1603,66 +1650,75 @@ namespace INMOST
enumerator * order = new enumerator [m];
std::pair<Matrix<typename Promote<Var,typeB>::type>,bool>
ret = std::make_pair(Matrix<typename Promote<Var,typeB>::type>(m,l),true);
Var max, temp;
typename Promote<Var,typeB>::type tempb;
//Var temp;
INMOST_DATA_REAL_TYPE max,v;
//typeB tempb;
for(enumerator i = 0; i < m; ++i) order[i] = i;
for(enumerator i = 0; i < m; i++)
{
enumerator maxk = i, maxq = i, temp2;
max = fabs(AtA(maxk,maxq));
enumerator maxk = i, maxq = i;//, temp2;
max = fabs(get_value(AtA(maxk,maxq)));
//Find best pivot
for(enumerator k = i; k < m; k++) // over rows
if( max < 1.0e-8 )
{
for(enumerator q = i; q < m; q++) // over columns
for(enumerator k = i; k < m; k++) // over rows
{
if( fabs(AtA(k,q)) > max )
for(enumerator q = i; q < m; q++) // over columns
{
max = fabs(AtA(k,q));
maxk = k;
maxq = q;
v = fabs(get_value(AtA(k,q)));
if( v > max )
{
max = v;
maxk = k;
maxq = q;
}
}
}
}
//Exchange rows
if( maxk != i )
{
for(enumerator q = 0; q < m; q++) // over columns of A
{
temp = AtA(maxk,q);
AtA(maxk,q) = AtA(i,q);
AtA(i,q) = temp;
}
//exchange rhs
for(enumerator q = 0; q < l; q++) // over columns of B
{
tempb = AtB(maxk,q);
AtB(maxk,q) = AtB(i,q);
AtB(i,q) = tempb;
}
}
//Exchange columns
if( maxq != i )
{
for(enumerator k = 0; k < m; k++) //over rows
//Exchange rows
if( maxk != i )
{
temp = AtA(k,maxq);
AtA(k,maxq) = AtA(k,i);
AtA(k,i) = temp;
for(enumerator q = 0; q < m; q++) // over columns of A
{
std::swap(AtA(maxk,q),AtA(i,q));
//temp = AtA(maxk,q);
//AtA(maxk,q) = AtA(i,q);
//AtA(i,q) = temp;
}
//exchange rhs
for(enumerator q = 0; q < l; q++) // over columns of B
{
std::swap(AtB(maxk,q),AtB(i,q));
//tempb = AtB(maxk,q);
//AtB(maxk,q) = AtB(i,q);
//AtB(i,q) = tempb;
}
}
//remember order in sol
//Exchange columns
if( maxq != i )
{
temp2 = order[maxq];
order[maxq] = order[i];
order[i] = temp2;
for(enumerator k = 0; k < m; k++) //over rows
{
std::swap(AtA(k,maxq),AtA(k,i));
//temp = AtA(k,maxq);
//AtA(k,maxq) = AtA(k,i);
//AtA(k,i) = temp;
}
//remember order in sol
{
std::swap(order[maxq],order[i]);
//temp2 = order[maxq];
//order[maxq] = order[i];
//order[i] = temp2;
}
}
}
//Check small entry
if( fabs(AtA(i,i)) < 1.0e-54 )
if( fabs(get_value(AtA(i,i))) < 1.0e-54 )
{
bool ok = true;
for(enumerator k = 0; k < l; k++) // over columns of B
{
if( fabs(AtB(i,k)/1.0e-54) > 1 )
if( fabs(get_value(AtB(i,k))/1.0e-54) > 1 )
{
ok = false;
break;
......@@ -1815,8 +1871,8 @@ namespace INMOST
/// @param coef Constant coefficient multiplying matrix.
/// @param other Matrix to be multiplied.
/// @return Matrix, each entry multiplied by a constant.
template<typename typeB,typename storageB>
INMOST::Matrix<typename INMOST::Promote<INMOST_DATA_REAL_TYPE,typeB>::type> operator *(INMOST_DATA_REAL_TYPE coef, const INMOST::Matrix<typeB,storageB> & other)
template<typename typeB>
INMOST::Matrix<typename INMOST::Promote<INMOST_DATA_REAL_TYPE,typeB>::type> operator *(INMOST_DATA_REAL_TYPE coef, const INMOST::AbstractMatrix<typeB> & other)
{return other*coef;}
#if defined(USE_AUTODIFF)
/// Multiplication of matrix by a variable from left.
......@@ -1824,8 +1880,8 @@ INMOST::Matrix<typename INMOST::Promote<INMOST_DATA_REAL_TYPE,typeB>::type> oper
/// @param coef Variable coefficient multiplying matrix.
/// @param other Matrix to be multiplied.
/// @return Matrix, each entry multiplied by a variable.
template<typename typeB,typename storageB>
INMOST::Matrix<typename INMOST::Promote<INMOST::variable,typeB>::type> operator *(const INMOST::variable & coef, const INMOST::Matrix<typeB,storageB> & other)
template<typename typeB>
INMOST::Matrix<typename INMOST::Promote<INMOST::variable,typeB>::type> operator *(const INMOST::variable & coef, const INMOST::AbstractMatrix<typeB> & other)
{return other*coef;}
/// Multiplication of matrix by a variable with first and
/// second order derivatives from left.
......@@ -1833,8 +1889,8 @@ INMOST::Matrix<typename INMOST::Promote<INMOST::variable,typeB>::type> operator
/// @param coef Variable coefficient multiplying matrix.
/// @param other Matrix to be multiplied.
/// @return Matrix, each entry multiplied by a variable.
template<typename typeB,typename storageB>
INMOST::Matrix<typename INMOST::Promote<INMOST::hessian_variable,typeB>::type> operator *(const INMOST::hessian_variable & coef, const INMOST::Matrix<typeB,storageB> & other)
template<typename typeB>
INMOST::Matrix<typename INMOST::Promote<INMOST::hessian_variable,typeB>::type> operator *(const INMOST::hessian_variable & coef, const INMOST::AbstractMatrix<typeB> & other)
{return other*coef;}
#endif
......
......@@ -339,6 +339,11 @@ namespace INMOST
std::cout << value << std::endl;
entries.Print();
}
void swap(multivar_expression & b)
{
std::swap(value,b.value);
entries.Swap(b.entries);
}
friend class multivar_expression_reference;
};
......@@ -351,6 +356,12 @@ namespace INMOST
Sparse::Row entries;
Sparse::HessianRow hessian_entries;
public:
void swap(hessian_multivar_expression & b)
{
std::swap(value,b.value);
entries.Swap(b.entries);
hessian_entries.Swap(b.hessian_entries);
}
/// Sets zero value and no first or second order variations.
hessian_multivar_expression() :value(0) {}
/// Sets value and no first or second order variations.
......@@ -1869,7 +1880,10 @@ template<class A> __INLINE INMOST_DATA_REAL_TY
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void assign(INMOST::var_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, const INMOST::var_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, const INMOST::multivar_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::var_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val.GetValue();}
......@@ -1943,6 +1957,9 @@ template<class A> __INLINE INMOST::function_expression<
#else //USE_AUTODIFF
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, INMOST_DATA_INTEGER_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_INTEGER_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_REAL_INTEGER_TYPE & Arg, INMOST_DATA_INTEGER_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void set_value(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE INMOST_DATA_REAL_TYPE get_value(INMOST_DATA_REAL_TYPE Arg) {return Arg;}
......
......@@ -3097,6 +3097,10 @@ namespace INMOST
// types for BARYCENTER: EDGE | FACE | CELL
// types for NORMAL: FACE | CELL (may precompute normal for cells in 2d case)
// types for ORIENTATION: FACE
/// Marks face with the orientation direction by marker.
/// If marker is set then face is reversed.
/// Then all faces are oriented either inside or outside of the cell.
void FacesOrientation(ElementArray<Face> & faces, MarkerType rev);
void PrepareGeometricData(GeomParam table);
void RemoveGeometricData(GeomParam table);
bool HaveGeometricData (GeometricData type, ElementType mask) const {return remember[type][ElementNum(mask)-1];} // requests to only one geometric and element type allowed
......
......@@ -586,15 +586,15 @@ namespace INMOST
{
if (dir == "X-" || dir == "I-")
return 0;
else if (dir == "X" || dir == "I" || dir == "X+" || dir == "I+")
else if (dir == "X" || dir == "I" || dir == "X+" || dir == "I+" || dir == "X " || dir == "I ")
return 1;
else if (dir == "Y-" || dir == "J-")
return 2;
else if (dir == "Y" || dir == "J" || dir == "Y+" || dir == "J+")
else if (dir == "Y" || dir == "J" || dir == "Y+" || dir == "J+" || dir == "Y " || dir == "J ")
return 3;
else if (dir == "Z-" || dir == "K-")
return 4;
else if (dir == "Z" || dir == "K" || dir == "Z+" || dir == "K+")
else if (dir == "Z" || dir == "K" || dir == "Z+" || dir == "K+" || dir == "Z " || dir == "K ")
return 5;
return -1;
}
......@@ -2614,7 +2614,7 @@ namespace INMOST
if (fault_cur.dir == -1)
{
if (verbosity > 0)
std::cout << "Unknown direction for fault " << fault_cur.name << " " << rec << std::endl;
std::cout << "Unknown direction for fault " << fault_cur.name << " " << rec << " (size:" <<strlen(rec)<<")"<< std::endl;
}
else
faults.push_back(fault_cur);
......@@ -4583,6 +4583,13 @@ namespace INMOST
tagsoil = CreateTag("SOIL", DATA_REAL, CELL, NONE, 1);
}
if (verbosity > 0) std::cout << std::endl;
if (verbosity > 0)
{
if(project_perm )
std::cout << "Permeability is projected onto axis" << std::endl;
else
std::cout << "Permeability is original" << std::endl;
}
#if defined(USE_OMP)
#pragma omp parallel
#endif
......
if(USE_MESH)
add_subdirectory(geom_test000)
endif(USE_MESH)
if(USE_AUTODIFF)
add_subdirectory(autodiff_test000)
add_subdirectory(autodiff_test001)
......@@ -18,4 +22,6 @@ add_subdirectory(pmesh_test001)
endif()
endif()
add_subdirectory(xml_reader_test000)
project(geom_test000)
set(SOURCE main.cpp)
add_executable(geom_test000 ${SOURCE})
target_link_libraries(geom_test000 inmost)
if(USE_MPI)
message("linking geom_test000 with MPI")
target_link_libraries(geom_test000 ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(geom_test000 PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
add_test(NAME geom_test000_dual4 COMMAND $<TARGET_FILE:geom_test000> ${CMAKE_CURRENT_SOURCE_DIR}/d4.pmf)
add_test(NAME geom_test000_cube4 COMMAND $<TARGET_FILE:geom_test000> ${CMAKE_CURRENT_SOURCE_DIR}/c4.pmf)
add_test(NAME geom_test000_tetra4 COMMAND $<TARGET_FILE:geom_test000> ${CMAKE_CURRENT_SOURCE_DIR}/t4.pmf)
add_test(NAME geom_test000_dual4_split COMMAND $<TARGET_FILE:geom_test000> ${CMAKE_CURRENT_SOURCE_DIR}/d4sp.pmf)
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