Commit 50076045 authored by Kirill Terekhov's avatar Kirill Terekhov

Some updates

Improvement of algorithm of volume calculation for non-convex cells in
incident_matrix class.

Unfinished reader implementation for grdecl files (incorrect order of
nodes).
parent 7eed046a
...@@ -604,7 +604,7 @@ class incident_matrix ...@@ -604,7 +604,7 @@ class incident_matrix
MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation
for(int k = 1; k < data.size(); ++k) for(int k = 1; k < data.size(); ++k)
data[k]->SetPrivateMarker(mrk); //0-th face orientation is default data[k]->SetPrivateMarker(mrk); //0-th face orientation is default
Node n1,n2; //to retrive edge Node n1,n2, v1,v2; //to retrive edge
bool reverse = false; //reverse orientation in considered face bool reverse = false; //reverse orientation in considered face
std::deque< orient_face > stack; //edge and first node and face for visiting std::deque< orient_face > stack; //edge and first node and face for visiting
//todo: can do faster by retriving edges and going over their nodes //todo: can do faster by retriving edges and going over their nodes
...@@ -614,7 +614,7 @@ class incident_matrix ...@@ -614,7 +614,7 @@ class incident_matrix
{ {
//figure out starting node order //figure out starting node order
if( edges[0]->getBeg() == edges[1]->getBeg() || if( edges[0]->getBeg() == edges[1]->getBeg() ||
edges[0]->getBeg() == edges[1]->getEnd() ) edges[0]->getBeg() == edges[1]->getEnd() )
{ {
n1 = edges[0]->getEnd(); n1 = edges[0]->getEnd();
n2 = edges[0]->getBeg(); n2 = edges[0]->getBeg();
...@@ -638,10 +638,10 @@ class incident_matrix ...@@ -638,10 +638,10 @@ class incident_matrix
//update edge nodes //update edge nodes
n1 = n2; //current end is new begin n1 = n2; //current end is new begin
//find new end //find new end
if( n2 == edges[(j+1)%edges.size()]->getBeg() ) v1 = edges[(j+1)%edges.size()]->getBeg();
n2 = edges[(j+1)%edges.size()]->getEnd(); v2 = edges[(j+1)%edges.size()]->getEnd();
else if( n2 == v1 ) n2 = v2;
n2 = edges[(j+1)%edges.size()]->getBeg(); else n2 = v1;
} }
if( stack.empty() ) break; if( stack.empty() ) break;
//get entry from stack //get entry from stack
...@@ -679,57 +679,34 @@ class incident_matrix ...@@ -679,57 +679,34 @@ class incident_matrix
//update edge nodes //update edge nodes
n1 = n2; //current end is new begin n1 = n2; //current end is new begin
//find new end //find new end
if( n2 == edges[(j+1)%edges.size()]->getBeg() ) v1 = edges[(j+1)%edges.size()]->getBeg();
n2 = edges[(j+1)%edges.size()]->getEnd(); v2 = edges[(j+1)%edges.size()]->getEnd();
else if( n2 == v1 ) n2 = v2;
n2 = edges[(j+1)%edges.size()]->getBeg(); else n2 = v1;
} }
} while(true); } while(true);
for(int k = 0; k < data.size(); ++k) for(int k = 0; k < data.size(); ++k)
data[k].RemPrivateMarker(mrk); data[k].RemPrivateMarker(mrk);
mesh->ReleasePrivateMarker(mrk); mesh->ReleasePrivateMarker(mrk);
Storage::real d; Storage::real cnt[3], nrm[3];
for(typename ElementArray<T>::size_type j = 0; j < data.size(); j++) for(typename ElementArray<T>::size_type j = 0; j < data.size(); j++)
{ {
d = 0; data[j]->Centroid(cnt);
ElementArray<Node> nodes = data[j]->getNodes(); data[j]->getAsFace()->Normal(nrm);
if( !nodes.empty() ) measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(cnt,nrm);
{ //measure += d;
if( data[j]->GetPrivateMarker(rev) )
{
Storage::real_array a = nodes.back().Coords();
for(typename ElementArray<Node>::size_type j = nodes.size()-2; j > 1; j--)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j-1].Coords();
d += __det3v(&a[0],&b[0],&c[0]);
}
}
else
{
Storage::real_array a = nodes[0].Coords();
for(typename ElementArray<Node>::size_type j = 1; j < nodes.size()-1; j++)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j+1].Coords();
d += __det3v(&a[0],&b[0],&c[0]);
}
}
}
//measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*d;
measure += d;
} }
for(int k = 0; k < data.size(); ++k) for(int k = 0; k < data.size(); ++k)
data[k].RemPrivateMarker(rev); data[k].RemPrivateMarker(rev);
mesh->ReleasePrivateMarker(rev); mesh->ReleasePrivateMarker(rev);
measure /= 6.0; measure /= 3.0;
measure = fabs(measure); measure = fabs(measure);
} }
return measure; return measure;
} }
void recursive_find(unsigned node, unsigned length) void recursive_find(unsigned node, unsigned length)
{ {
if( !min_loop.empty() && length > min_loop.size() ) return; //if( !min_loop.empty() && length > min_loop.size() ) return;
bool success = false; bool success = false;
if( do_show_row(node) ) if( do_show_row(node) )
{ {
...@@ -737,20 +714,20 @@ class incident_matrix ...@@ -737,20 +714,20 @@ class incident_matrix
if( success ) if( success )
{ {
if( min_loop.empty() || min_loop.size() >= length ) //if( min_loop.empty() || min_loop.size() >= length )
{ {
temp_loop.resize(length); temp_loop.resize(length);
for(unsigned j = 0; j < insert_order.size(); j++) for(unsigned j = 0; j < insert_order.size(); j++)
temp_loop[j] = head_column[insert_order[j]]; temp_loop[j] = head_column[insert_order[j]];
//Storage::real measure = compute_measure(temp_loop); Storage::real measure = compute_measure(temp_loop);
//if( min_loop.empty() || min_loop_measure >= measure ) if( min_loop.empty() || min_loop_measure >= measure )
{ {
min_loop.swap(temp_loop); min_loop.swap(temp_loop);
//min_loop_measure = measure; min_loop_measure = measure;
//~ if( min_loop.size() == head_column.size() ) // all elements were visited //~ if( min_loop.size() == head_column.size() ) // all elements were visited
//~ { //~ {
//~ unsigned num = 0; //~ unsigned num = 0;
...@@ -920,7 +897,6 @@ public: ...@@ -920,7 +897,6 @@ public:
{ {
ret.clear(); ret.clear();
exit_recurse = false; exit_recurse = false;
min_loop_measure = 1.0e20;
unsigned first = UINT_MAX; unsigned first = UINT_MAX;
do do
{ {
...@@ -933,6 +909,7 @@ public: ...@@ -933,6 +909,7 @@ public:
} }
if( first != UINT_MAX ) if( first != UINT_MAX )
{ {
min_loop_measure = 1.0e20;
recursive_find(first,1); recursive_find(first,1);
if( min_loop.empty() ) if( min_loop.empty() )
visits[first]--; //don't start again from this element visits[first]--; //don't start again from this element
......
...@@ -2005,15 +2005,15 @@ namespace INMOST ...@@ -2005,15 +2005,15 @@ namespace INMOST
/// @param tag tag that represents the data /// @param tag tag that represents the data
/// @see Tag::GetSize /// @see Tag::GetSize
INMOST_DATA_ENUM_TYPE GetDataSize (HandleType h,const Tag & tag) const; //For DATA_BULK return number of bytes, otherwise return the length of array INMOST_DATA_ENUM_TYPE GetDataSize (HandleType h,const Tag & tag) const; //For DATA_BULK return number of bytes, otherwise return the length of array
/// Return the size of the structure in bytes required to represent the data on current element. /// Return the size of the structure in bytes required to represent the data on current element.
/// This is equal to GetDataSize times Tag::GetBytesSize for all the data types, /// This is equal to GetDataSize times Tag::GetBytesSize for all the data types,
/// except for DATA_VARIABLE, that requires a larger structure to accomodate derivatives. /// except for DATA_VARIABLE, that requires a larger structure to accomodate derivatives.
/// @param h handle of element /// @param h handle of element
/// @param tag tag that represents the data /// @param tag tag that represents the data
INMOST_DATA_ENUM_TYPE GetDataCapacity (HandleType h,const Tag & tag) const; INMOST_DATA_ENUM_TYPE GetDataCapacity (HandleType h,const Tag & tag) const;
/// Returns the number of bytes in data used for given type of tag. /// Returns the number of bytes in data used for given type of tag.
/// Trivial for all the types except DATA_VARIABLE. /// Trivial for all the types except DATA_VARIABLE.
INMOST_DATA_ENUM_TYPE GetDataCapacity (const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size, const Tag & tag) const; INMOST_DATA_ENUM_TYPE GetDataCapacity (const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size, const Tag & tag) const;
/// Sets the size of the array for data of variable size. /// Sets the size of the array for data of variable size.
/// If you try to change size of data of constant size then if size is /// If you try to change size of data of constant size then if size is
/// different from current then in debug mode (NDEBUG not set) assertion will fail, /// different from current then in debug mode (NDEBUG not set) assertion will fail,
......
This diff is collapsed.
...@@ -641,152 +641,22 @@ namespace INMOST ...@@ -641,152 +641,22 @@ namespace INMOST
Cell me = Cell(this,e); Cell me = Cell(this,e);
ElementArray<Face> faces = me->getFaces(); ElementArray<Face> faces = me->getFaces();
*ret = 0; *ret = 0;
/*
Storage::real d;
for(unsigned i = 0; i < faces.size(); i++)
{
d = 0;
adjacent<Node> nodes = faces[i].getNodes();
Storage::real_array a = nodes[0].Coords();
for(unsigned j = 1; j < nodes.size()-1; j++)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j+1].Coords();
d += det3v(&a[0],&b[0],&c[0]);
}
*ret += (2*faces[i].FaceOrientedOutside(e->getAsCell())-1)*d;
}
*ret /= 6.0;
*/
if( faces.size() > 3 ) if( faces.size() > 3 )
{ {
Storage::real fcnt[3], fnrm[3];// , area; //can copy orientation-independent algorithm from
//incident_matrix.hpp: incident_matrix::compute_measure
Storage::real fcnt[3], fnrm[3];
for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++) for(ElementArray<Face>::size_type i = 0; i < faces.size(); i++)
{ {
faces[i]->Centroid(fcnt); faces[i]->Centroid(fcnt);
faces[i]->OrientedNormal(me,fnrm); faces[i]->OrientedNormal(me,fnrm);
/*
area = ::sqrt(vec_dot_product(fnrm,fnrm,mdim));
if( area > 0 )
{
fnrm[0] /= area;
fnrm[1] /= area;
fnrm[2] /= area;
*ret += vec_dot_product(fcnt,fnrm,mdim) * area;
}
*/
*ret += vec_dot_product(fcnt,fnrm,mdim); *ret += vec_dot_product(fcnt,fnrm,mdim);
} }
*ret /= 3.0; *ret /= 3.0;
} }
/*
if( *ret < 0 || (*ret) != (*ret) )
{
Storage::real test = 0;
//~ Storage::real fcnt[3], fnrm[3], area;
for(unsigned i = 0; i < faces.size(); i++)
{
if( faces[i].FixNormalOrientation() ) std::cout << faces[i].LocalID() << " normal refixed " << faces[i].nbAdjElements(CELL) << std::endl;
//~ faces[i].Centroid(fcnt);
//~ faces[i].OrientedNormal(e->getAsCell(),fnrm);
//~ area = ::sqrt(vec_dot_product(fnrm,fnrm,mdim));
//~ fnrm[0] /= area;
//~ fnrm[1] /= area;
//~ fnrm[2] /= area;
//~ test += vec_dot_product(fcnt,fnrm,mdim) * area / 3.0;
}
//~ e->Centroid(fcnt);
Storage::real d;
for(unsigned i = 0; i < faces.size(); i++)
{
d = 0;
adjacent<Node> nodes = faces[i].getNodes();
Storage::real_array a = nodes[0].Coords();
for(unsigned j = 1; j < nodes.size()-1; j++)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j+1].Coords();
d += det3v(&a[0],&b[0],&c[0]);
}
test += (2*faces[i].FaceOrientedOutside(e->getAsCell())-1)*d;
}
test /= 6.0;
std::cout << "alg1 " << *ret << " alg2 " << test << " on " << Element::GeometricTypeName(e->GetGeometricType()) << " " << e->GlobalID() << " " << e->LocalID() << std::endl;
//e->Integer(tag_topologyerror) = 1;
}
*/
//~ if( *ret < 0 )
//~ {
//~ std::cout << "negative volume! " << *ret << std::endl;
//~ std::cout << "element " << Element::GeometricTypeName(e->GetGeometricType()) << " faces " << faces.size() << std::endl;
//~ *ret = 0;
//~ for(unsigned i = 0; i < faces.size(); i++)
//~ {
//~ std::cout << "face " << i << "/" << faces.size() << std::endl;
//~ d = 0;
//~ adjacent<Node> nodes = faces[i].getNodes();
//~ Storage::real_array a = nodes[0].Coords();
//~ std::cout << "node 0 " << a[0] << " " << a[1] << " " << a[2] << " id " << nodes[0].LocalID() << std::endl;
//~ for(unsigned j = 1; j < nodes.size()-1; j++)
//~ {
//~ Storage::real_array b = nodes[j].Coords();
//~ std::cout << "node " << j << " " << b[0] << " " << b[1] << " " << b[2] << " id " << nodes[j].LocalID() << std::endl;
//~ Storage::real_array c = nodes[j+1].Coords();
//~ d += det3v(&a[0],&b[0],&c[0]);
//~ }
//~ a = nodes[nodes.size()-1].Coords();
//~ std::cout << "node " << nodes.size()-1 << " " << a[0] << " " << a[1] << " " << a[2] << " id " << nodes[nodes.size()-1].LocalID() << std::endl;
//~ std::cout << "d = " << d << std::endl;
//~ std::cout << "orientation = " << (2*faces[i].FaceOrientedOutside(e->getAsCell())-1) << std::endl;
//~ Storage::real old = *ret, add = (2*faces[i].FaceOrientedOutside(e->getAsCell())-1)*d;
//~ *ret = old + add;
//~ std::cout << old << " + " << add << " = " << *ret << std::endl;
//~ }
//~ std::cout << "result " << *ret/6.0 << std::endl;
//~ std::cout << "trying with fix " << std::endl;
//~ *ret = 0;
//~ for(unsigned i = 0; i < faces.size(); i++)
//~ {
//~ std::cout << "face " << i << "/" << faces.size() << " fixed " << faces[i].FixNormalOrientation() << " cells " << faces[i].nbAdjElements(CELL) << std::endl;
//~ d = 0;
//~ adjacent<Node> nodes = faces[i].getNodes();
//~ Storage::real_array a = nodes[0].Coords();
//~ std::cout << "node 0 " << a[0] << " " << a[1] << " " << a[2] << " id " << nodes[0].LocalID() << std::endl;
//~ for(unsigned j = 1; j < nodes.size()-1; j++)
//~ {
//~ Storage::real_array b = nodes[j].Coords();
//~ std::cout << "node " << j << " " << b[0] << " " << b[1] << " " << b[2] << " id " << nodes[j].LocalID() << std::endl;
//~ Storage::real_array c = nodes[j+1].Coords();
//~ d += det3v(&a[0],&b[0],&c[0]);
//~ }
//~ a = nodes[nodes.size()-1].Coords();
//~ std::cout << "node " << nodes.size()-1 << " " << a[0] << " " << a[1] << " " << a[2] << " id " << nodes[nodes.size()-1].LocalID() << std::endl;
//~ std::cout << "d = " << d << std::endl;
//~ std::cout << "orientation = " << (2*faces[i].FaceOrientedOutside(e->getAsCell())-1) << std::endl;
//~ Storage::real old = *ret, add = (2*faces[i].FaceOrientedOutside(e->getAsCell())-1)*d;
//~ *ret = old + add;
//~ std::cout << old << " + " << add << " = " << *ret << std::endl;
//~ }
//~ std::cout << "result " << *ret/6.0 << std::endl;
//~ }
//~ if( isnan(*ret) || fabs(*ret) < 1e-15 ) throw -1;
break; break;
} }
} }
//~ throw -1;
//~ if( (*ret) != (*ret) || *ret < 0 )
//~ {
//~ std::cout << "bad measure: " << *ret << " for " << ElementTypeName(e->GetElementType()) << " " << Element::GeometricTypeName(e->GetGeometricType()) << " edim " << edim << std::endl;
//~
//~ }
} }
//~ if( isnan(*ret) || fabs(*ret) < 1e-15 ) throw -1; //~ if( isnan(*ret) || fabs(*ret) < 1e-15 ) throw -1;
break; break;
......
...@@ -173,8 +173,8 @@ namespace INMOST ...@@ -173,8 +173,8 @@ namespace INMOST
//mark all faces, so that we can perform adjacency retrival //mark all faces, so that we can perform adjacency retrival
MarkerType mrk = mesh->CreatePrivateMarker(); MarkerType mrk = mesh->CreatePrivateMarker();
MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation
data.SetPrivateMarker(mrk); for(int k = 1; k < data.size(); ++k)
data[0]->RemPrivateMarker(mrk); //0-th face orientation is default data[k]->SetPrivateMarker(mrk); //0-th face orientation is default
Node n1,n2; //to retrive edge Node n1,n2; //to retrive edge
bool reverse = false; //reverse orientation in considered face bool reverse = false; //reverse orientation in considered face
std::deque< orient_face > stack; //edge and first node and face for visiting std::deque< orient_face > stack; //edge and first node and face for visiting
...@@ -258,45 +258,23 @@ namespace INMOST ...@@ -258,45 +258,23 @@ namespace INMOST
} while(true); } while(true);
data.RemPrivateMarker(mrk); data.RemPrivateMarker(mrk);
mesh->ReleasePrivateMarker(mrk); mesh->ReleasePrivateMarker(mrk);
Storage::real v[3], d; Storage::real cnt[3], nrm[3];
for(typename ElementArray<T>::size_type j = 0; j < data.size(); j++) for(typename ElementArray<T>::size_type j = 0; j < data.size(); j++)
{ {
d = 0; data[j]->Centroid(cnt);
ElementArray<Node> nodes = data[j]->getNodes(); data[j]->getAsFace()->Normal(nrm);
if( !nodes.empty() ) measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(cnt,nrm);
{
Storage::real_array a = nodes[0].Coords();
if( data[j]->GetPrivateMarker(rev) )
{
for(typename ElementArray<Node>::size_type j = 1; j < nodes.size()-1; j++)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j+1].Coords();
d += __det3v(&a[0],&b[0],&c[0]);
}
}
else
{
for(typename ElementArray<Node>::size_type j = nodes.size()-2; j > 1; j--)
{
Storage::real_array b = nodes[j].Coords();
Storage::real_array c = nodes[j-1].Coords();
d += __det3v(&a[0],&b[0],&c[0]);
}
}
}
measure += d;
} }
data.RemPrivateMarker(rev); data.RemPrivateMarker(rev);
mesh->ReleasePrivateMarker(rev); mesh->ReleasePrivateMarker(rev);
measure /= 6.0; measure /= 3.0;
measure = fabs(measure); measure = fabs(measure);
} }
return measure; return measure;
} }
void recursive_find(unsigned node, unsigned length) void recursive_find(unsigned node, unsigned length)
{ {
if( !min_loop.empty() && length > min_loop.size() ) return; //if( !min_loop.empty() && length > min_loop.size() ) return;
bool success = false; bool success = false;
if( do_show_row(node) ) if( do_show_row(node) )
{ {
...@@ -304,43 +282,19 @@ namespace INMOST ...@@ -304,43 +282,19 @@ namespace INMOST
if( success ) if( success )
{ {
if( min_loop.empty() || min_loop.size() >= length ) //if( min_loop.empty() || min_loop.size() >= length )
{ {
temp_loop.resize(length); temp_loop.resize(length);
for(unsigned j = 0; j < insert_order.size(); j++) for(unsigned j = 0; j < insert_order.size(); j++)
temp_loop.at(j) = head_column[insert_order[j]]; temp_loop.at(j) = head_column[insert_order[j]];
/* Storage::real measure = compute_measure(temp_loop);
// TODO:
// MUST CORRECTLY COMPUTE VOLUMES HERE FOR CONCAVE POLYGONS/POLYHEDRONS! if( min_loop.empty() || min_loop_measure >= measure )
// this should work instead of min_loop
bool ok = false;
if( temp_loop.size() <= min_loop.size() )
{
Storage::real measure = compute_measure(temp_loop);
if( measure > 0 && measure < min_loop_measure )
{
ok = true;
min_loop_measure = measure;
}
}
else
{
Storage::real measure = compute_measure(temp_loop);
if( measure > 0 )
{
ok = true;
min_loop_measure = measure;
}
}
if( ok )
*/
{ {
min_loop.swap(temp_loop); min_loop.swap(temp_loop);
min_loop_measure = measure;
//~ if( min_loop.size() == head_column.size() ) // all elements were visited //~ if( min_loop.size() == head_column.size() ) // all elements were visited
//~ { //~ {
//~ unsigned num = 0; //~ unsigned num = 0;
...@@ -515,6 +469,7 @@ namespace INMOST ...@@ -515,6 +469,7 @@ namespace INMOST
} }
if( first != UINT_MAX ) if( first != UINT_MAX )
{ {
min_loop_measure = 1.0e+20;
recursive_find(first,1); recursive_find(first,1);
if( min_loop.empty() ) if( min_loop.empty() )
visits[first]--; //don't start again from this element visits[first]--; //don't start again from this element
......
...@@ -54,7 +54,9 @@ ...@@ -54,7 +54,9 @@
41) ( ) HighConn, LowConn , 41) ( ) HighConn, LowConn ,
44) ( ) PackElementsData tag 44) ( ) PackElementsData tag
46) ( ) . , 46) ( ) . ,
19) () ( , )
20) ()
63) () expr
===================================================================================== =====================================================================================
0) , 0) ,
...@@ -66,8 +68,9 @@ ...@@ -66,8 +68,9 @@
18) 18)
19) ( , )
20) 19.) incident_matrix.hpp incident_matrix::compute_measure geometry.cpp Mesh::GetGeometricData
21) /- (kd examples/OldDrawGrid) 21) /- (kd examples/OldDrawGrid)
22) ResolveShared 22) ResolveShared
23) , 23) ,
...@@ -111,7 +114,7 @@ ...@@ -111,7 +114,7 @@
62) DATA_UNKNOWN unknown 62) DATA_UNKNOWN unknown
63) expr
64) Automatizator 64) Automatizator
......
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