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
MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation
for(int k = 1; k < data.size(); ++k)
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
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
......@@ -614,7 +614,7 @@ class incident_matrix
{
//figure out starting node order
if( edges[0]->getBeg() == edges[1]->getBeg() ||
edges[0]->getBeg() == edges[1]->getEnd() )
edges[0]->getBeg() == edges[1]->getEnd() )
{
n1 = edges[0]->getEnd();
n2 = edges[0]->getBeg();
......@@ -638,10 +638,10 @@ class incident_matrix
//update edge nodes
n1 = n2; //current end is new begin
//find new end
if( n2 == edges[(j+1)%edges.size()]->getBeg() )
n2 = edges[(j+1)%edges.size()]->getEnd();
else
n2 = edges[(j+1)%edges.size()]->getBeg();
v1 = edges[(j+1)%edges.size()]->getBeg();
v2 = edges[(j+1)%edges.size()]->getEnd();
if( n2 == v1 ) n2 = v2;
else n2 = v1;
}
if( stack.empty() ) break;
//get entry from stack
......@@ -679,57 +679,34 @@ class incident_matrix
//update edge nodes
n1 = n2; //current end is new begin
//find new end
if( n2 == edges[(j+1)%edges.size()]->getBeg() )
n2 = edges[(j+1)%edges.size()]->getEnd();
else
n2 = edges[(j+1)%edges.size()]->getBeg();
v1 = edges[(j+1)%edges.size()]->getBeg();
v2 = edges[(j+1)%edges.size()]->getEnd();
if( n2 == v1 ) n2 = v2;
else n2 = v1;
}
} while(true);
for(int k = 0; k < data.size(); ++k)
data[k].RemPrivateMarker(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++)
{
d = 0;
ElementArray<Node> nodes = data[j]->getNodes();
if( !nodes.empty() )
{
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;
data[j]->Centroid(cnt);
data[j]->getAsFace()->Normal(nrm);
measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(cnt,nrm);
//measure += d;
}
for(int k = 0; k < data.size(); ++k)
data[k].RemPrivateMarker(rev);
mesh->ReleasePrivateMarker(rev);
measure /= 6.0;
measure /= 3.0;
measure = fabs(measure);
}
return measure;
}
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;
if( do_show_row(node) )
{
......@@ -737,20 +714,20 @@ class incident_matrix
if( success )
{
if( min_loop.empty() || min_loop.size() >= length )
//if( min_loop.empty() || min_loop.size() >= length )
{
temp_loop.resize(length);
for(unsigned j = 0; j < insert_order.size(); 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_measure = measure;
min_loop_measure = measure;
//~ if( min_loop.size() == head_column.size() ) // all elements were visited
//~ {
//~ unsigned num = 0;
......@@ -920,7 +897,6 @@ public:
{
ret.clear();
exit_recurse = false;
min_loop_measure = 1.0e20;
unsigned first = UINT_MAX;
do
{
......@@ -933,6 +909,7 @@ public:
}
if( first != UINT_MAX )
{
min_loop_measure = 1.0e20;
recursive_find(first,1);
if( min_loop.empty() )
visits[first]--; //don't start again from this element
......
......@@ -2005,15 +2005,15 @@ namespace INMOST
/// @param tag tag that represents the data
/// @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
/// 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,
/// except for DATA_VARIABLE, that requires a larger structure to accomodate derivatives.
/// @param h handle of element
/// @param tag tag that represents the data
INMOST_DATA_ENUM_TYPE GetDataCapacity (HandleType h,const Tag & tag) const;
/// Returns the number of bytes in data used for given type of tag.
/// 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;
/// 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,
/// except for DATA_VARIABLE, that requires a larger structure to accomodate derivatives.
/// @param h handle of element
/// @param tag tag that represents the data
INMOST_DATA_ENUM_TYPE GetDataCapacity (HandleType h,const Tag & tag) const;
/// Returns the number of bytes in data used for given type of tag.
/// 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;
/// 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
/// different from current then in debug mode (NDEBUG not set) assertion will fail,
......
This diff is collapsed.
......@@ -641,152 +641,22 @@ namespace INMOST
Cell me = Cell(this,e);
ElementArray<Face> faces = me->getFaces();
*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 )
{
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++)
{
faces[i]->Centroid(fcnt);
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 /= 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;
}
}
//~ 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;
break;
......
......@@ -173,8 +173,8 @@ namespace INMOST
//mark all faces, so that we can perform adjacency retrival
MarkerType mrk = mesh->CreatePrivateMarker();
MarkerType rev = mesh->CreatePrivateMarker(); //reverse orientation
data.SetPrivateMarker(mrk);
data[0]->RemPrivateMarker(mrk); //0-th face orientation is default
for(int k = 1; k < data.size(); ++k)
data[k]->SetPrivateMarker(mrk); //0-th face orientation is default
Node n1,n2; //to retrive edge
bool reverse = false; //reverse orientation in considered face
std::deque< orient_face > stack; //edge and first node and face for visiting
......@@ -258,45 +258,23 @@ namespace INMOST
} while(true);
data.RemPrivateMarker(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++)
{
d = 0;
ElementArray<Node> nodes = data[j]->getNodes();
if( !nodes.empty() )
{
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[j]->Centroid(cnt);
data[j]->getAsFace()->Normal(nrm);
measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(cnt,nrm);
}
data.RemPrivateMarker(rev);
mesh->ReleasePrivateMarker(rev);
measure /= 6.0;
measure /= 3.0;
measure = fabs(measure);
}
return measure;
}
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;
if( do_show_row(node) )
{
......@@ -304,43 +282,19 @@ namespace INMOST
if( success )
{
if( min_loop.empty() || min_loop.size() >= length )
//if( min_loop.empty() || min_loop.size() >= length )
{
temp_loop.resize(length);
for(unsigned j = 0; j < insert_order.size(); j++)
temp_loop.at(j) = head_column[insert_order[j]];
/*
// TODO:
// MUST CORRECTLY COMPUTE VOLUMES HERE FOR CONCAVE POLYGONS/POLYHEDRONS!
// 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 )
*/
Storage::real measure = compute_measure(temp_loop);
if( min_loop.empty() || min_loop_measure >= measure )
{
min_loop.swap(temp_loop);
min_loop_measure = measure;
//~ if( min_loop.size() == head_column.size() ) // all elements were visited
//~ {
//~ unsigned num = 0;
......@@ -515,6 +469,7 @@ namespace INMOST
}
if( first != UINT_MAX )
{
min_loop_measure = 1.0e+20;
recursive_find(first,1);
if( min_loop.empty() )
visits[first]--; //don't start again from this element
......
......@@ -54,7 +54,9 @@
41) ( ) HighConn, LowConn ,
44) ( ) PackElementsData tag
46) ( ) . ,
19) () ( , )
20) ()
63) () expr
=====================================================================================
0) ,
......@@ -66,8 +68,9 @@
18)
19) ( , )
20)
19.) incident_matrix.hpp incident_matrix::compute_measure geometry.cpp Mesh::GetGeometricData
21) /- (kd examples/OldDrawGrid)
22) ResolveShared
23) ,
......@@ -111,7 +114,7 @@
62) DATA_UNKNOWN unknown
63) expr
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