![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include "iMesh.h"
#include "iMeshP.h"
#include "MBiMesh.hpp"
#include "moab/Core.hpp"
#include "moab/Range.hpp"
#include "moab/Intx2MeshOnSphere.hpp"
#include "moab/ReadUtilIface.hpp"
#include "moab/ParallelComm.hpp"
#include "MBTagConventions.hpp"
#include "moab/ParallelMergeMesh.hpp"
#include "moab/IntxUtils.hpp"
#include <sstream>
#include <mpi.h>
Go to the source code of this file.
Defines | |
#define | NC 3 |
Functions | |
void | initialize_area_and_tracer (iMesh_Instance instance, iBase_EntitySetHandle imesh_euler_set, double *area_vals, int *ierr) |
void | update_tracer_test (iMesh_Instance instance, iBase_EntitySetHandle imesh_euler_set, iBase_EntitySetHandle imesh_output_set, int numTracers, double *tracer_vals, int *ierr) |
void | update_tracer (iMesh_Instance instance, iBase_EntitySetHandle imesh_euler_set, int *ierr) |
ErrorCode | create_coarse_mesh (Interface *mb, ParallelComm *pcomm, EntityHandle coarseSet, double *coords, int *corners, int nc, int nelem, EntityHandle &start_vert, int &totalNumVertices, int &numCornerVertices, std::vector< double * > &coordv) |
ErrorCode | fill_coord_on_edges (Interface *mb, std::vector< double * > &coordv, double *coords, Range &edges, EntityHandle start_v, Range &coarseQuads, int nc, int numCornerVertices, Tag &fineVertOnEdgeTag) |
ErrorCode | create_fine_mesh (Interface *mb, ParallelComm *pcomm, EntityHandle coarseSet, EntityHandle fine_set, double *coords, int nc, int nelem, EntityHandle start_vert, int numCornerVertices, std::vector< double * > &coordv) |
void | create_mesh (iMesh_Instance instance, iBase_EntitySetHandle *imesh_euler_set, iBase_EntitySetHandle *imesh_departure_set, iBase_EntitySetHandle *imesh_intx_set, double *coords, int *corners, int nc, int nelem, MPI_Fint comm, int *ierr) |
ErrorCode | set_departure_points_position (Interface *mb, EntityHandle lagrSet, double *dep_coords, double radius2) |
void | intersection_at_level (iMesh_Instance instance, iBase_EntitySetHandle fine_set, iBase_EntitySetHandle lagr_set, iBase_EntitySetHandle intx_set, double *dep_coords, double radius2, int *ierr) |
void | cleanup_after_intersection (iMesh_Instance instance, iBase_EntitySetHandle fine_set, iBase_EntitySetHandle lagr_set, iBase_EntitySetHandle intx_set, int *ierr) |
void | cleanup_after_simulation (int *ierr) |
Variables | |
static double | radius = 1. |
static double | gtol = 1.e-9 |
static bool | debug = false |
static int * | mapping_to_coords = NULL |
static int | numVertices = 0 |
static Intx2MeshOnSphere * | pworker = NULL |
#define NC 3 |
Definition at line 49 of file wrap_intx.cpp.
Referenced by create_fine_mesh(), and fill_coord_on_edges().
void cleanup_after_intersection | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle | fine_set, | ||
iBase_EntitySetHandle | lagr_set, | ||
iBase_EntitySetHandle | intx_set, | ||
int * | ierr | ||
) |
Definition at line 938 of file wrap_intx.cpp.
References moab::Interface::clear_meshset(), moab::Interface::delete_entities(), ErrorCode, ERRORV, moab::Interface::get_connectivity(), moab::Interface::get_entities_by_dimension(), MOABI, and moab::subtract().
{
*ierr = 1;
Interface* mb = MOABI;
// delete elements
// delete now the polygons and the elements of out_set
// also, all verts that are not in euler set or lagr_set
Range allVerts;
ErrorCode rval = mb->get_entities_by_dimension( 0, 0, allVerts );
ERRORV( rval, "can't get all vertices" );
Range allElems;
rval = mb->get_entities_by_dimension( 0, 2, allElems );
ERRORV( rval, "can't get all elems" );
Range polys; // first euler polys
rval = mb->get_entities_by_dimension( (EntityHandle)fine_set, 2, polys );
ERRORV( rval, "can't get all polys from fine set" );
// add to polys range the lagr polys
rval = mb->get_entities_by_dimension( (EntityHandle)lagr_set, 2,
polys ); // do not delete lagr set either, with its vertices
ERRORV( rval, "can't get all polys from lagr set" );
// add to the connecVerts range all verts, from all initial polys
Range vertsToStay;
rval = mb->get_connectivity( polys, vertsToStay );
ERRORV( rval, "get verts that stay" );
Range todeleteVerts = subtract( allVerts, vertsToStay );
Range todeleteElem = subtract( allElems, polys ); // this is coarse mesh too (if still here)
// empty the out mesh set
EntityHandle out_set = (EntityHandle)intx_set;
rval = mb->clear_meshset( &out_set, 1 );
ERRORV( rval, "clear mesh set" );
rval = mb->delete_entities( todeleteElem );
ERRORV( rval, "delete intx elements" );
rval = mb->delete_entities( todeleteVerts );
ERRORV( rval, "failed to delete intx vertices" );
*ierr = 0;
return;
}
void cleanup_after_simulation | ( | int * | ierr | ) |
Definition at line 988 of file wrap_intx.cpp.
References mapping_to_coords, and numVertices.
{
delete[] mapping_to_coords;
numVertices = 0;
*ierr = 0;
return;
}
ErrorCode create_coarse_mesh | ( | Interface * | mb, |
ParallelComm * | pcomm, | ||
EntityHandle | coarseSet, | ||
double * | coords, | ||
int * | corners, | ||
int | nc, | ||
int | nelem, | ||
EntityHandle & | start_vert, | ||
int & | totalNumVertices, | ||
int & | numCornerVertices, | ||
std::vector< double * > & | coordv | ||
) |
Definition at line 222 of file wrap_intx.cpp.
References moab::Interface::add_entities(), ErrorCode, ERRORR, moab::Interface::get_adjacencies(), moab::ReadUtilIface::get_element_connect(), moab::ReadUtilIface::get_node_coords(), moab::Interface::globalId_tag(), MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBQUAD, PARALLEL_PARTITION_TAG_NAME, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::Interface::query_interface(), moab::ParallelComm::resolve_shared_ents(), moab::Range::size(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::Interface::UNION, and moab::Interface::write_file().
Referenced by create_mesh().
{
int rank = pcomm->proc_config().proc_rank();
Tag tagid; // global id at corners
ErrorCode rval;
tagid = mb->globalId_tag();
int dum_id = -1;
Tag partitionTag;
mb->tag_get_handle( PARALLEL_PARTITION_TAG_NAME, 1, MB_TYPE_INTEGER, partitionTag, MB_TAG_SPARSE | MB_TAG_CREAT,
&dum_id );
// there are nelem*4 corners, and 3*(nc2+1)*(nc2+1)*nelem coordinates
// create first a coarse mesh,
int size_corners = 4 * nelem;
// int size_coords=3*(nc+1)*(nc+1)*nelem;
// order first the corners array, and eliminate duplicates
std::vector< int > corn1( size_corners );
std::copy( corners, corners + size_corners, corn1.begin() );
std::sort( corn1.begin(), corn1.end() );
corn1.erase( std::unique( corn1.begin(), corn1.end() ), corn1.end() );
numCornerVertices = (int)corn1.size();
// these corners are actually dofs in spectral mesh, so they will vary from 0 to
// np*np*nel_global (at most) they are shared on edges, corners of spectral elements, so number
// of dofs is lower than this estimate still, the number of coarse vertices is close to number
// of cells + 2
std::map< int, int > index_map;
for( size_t i = 0; i < corn1.size(); i++ )
index_map[corn1[i]] = i;
// estimate for the vertices that will get created, from euler formula
// v-e+f = 2 for whole sphere
// for one task (distributed) v-e+f = 1, for one connected region
// if multiple connex regions (out of HFSC distribution from homme), v-e+f = k, k is number of
// connectivity regs so in any case, e = v+f -k, where k is at least 1 (1, 2, 3, etc) so in any
// case number of coarse edges is at most e_max = v+f-1
// this will give an estimate for the number of "fine" vertices
int e_max = nelem + numCornerVertices - 1;
// total number of extra vertices will be
int numVertsOnEdges = ( nc - 1 ) * e_max;
int numExtraVerts = numVertsOnEdges + ( nc - 1 ) * ( nc - 1 ) * nelem; // internal fine vertices
totalNumVertices = numCornerVertices + numExtraVerts; // this could be overestimated, because we are not sure
// about the number of edges
// used to determine the if the nodes are matching at corners of elements
std::vector< int > index_used( numCornerVertices, 0 );
ReadUtilIface* read_iface;
rval = mb->query_interface( read_iface );ERRORR( rval, "can't get query intf " );
EntityHandle start_elem, *connect;
// create verts, num is 2(nquads+1) because they're in a 1d row; will initialize coords in loop
// over quads later
rval = read_iface->get_node_coords( 3, totalNumVertices, 0, start_vert, coordv );ERRORR( rval, "can't get node coords " );
// fill it up
int stride = ( nc + 1 ) * ( nc + 1 ); // 16, for nc ==3
// int order_in_coord[] = {0, 3, 15, 12}; // for nc=3
/*
* first j, then i, so this is the order of the points in coords array, now:
*
* nc(nc+1), ... (nc+1)*(nc+1)-1
*
* 2(nc+1),
* nc+1, nc+2, 2*(nc+1)-1
* 0, 1 , 2, ..........., nc
*/
int order_in_coord[] = { 0, nc, ( nc + 1 ) * ( nc + 1 ) - 1, nc * ( nc + 1 ) };
for( int i = 0; i < size_corners; i++ )
{
int id = corners[i];
int index = index_map[id];
int j = i % 4;
int ind_coord = i / 4;
ind_coord = ( ind_coord * stride + order_in_coord[j] ) * 3;
if( index_used[index] )
{
if( fabs( coordv[0][index] - coords[ind_coord] ) > 0.000001 )
std::cout << " id:" << corners[i] << " i:" << i << " j:" << j << " " << coordv[0][index] << " "
<< coords[ind_coord] << "\n";
continue;
}
coordv[0][index] = coords[ind_coord];
coordv[1][index] = coords[ind_coord + 1];
coordv[2][index] = coords[ind_coord + 2];
index_used[index] = 1;
EntityHandle vertexh = start_vert + index;
rval = mb->tag_set_data( tagid, &vertexh, 1, (void*)&id );ERRORR( rval, "can't set tag id on vertex " );
}
// create quads; one quad for each spectral element; later, we will create fine quads
rval = read_iface->get_element_connect( nelem, 4, MBQUAD, 0, start_elem, connect );ERRORR( rval, "can't create elements " );
for( int i = 0; i < nelem; i++ )
{
for( int j = 0; j < 4; j++ )
{
int index_v = index_map[corners[i * 4 + j]];
connect[i * 4 + j] = start_vert + index_v;
}
}
Range quads( start_elem, start_elem + nelem - 1 );
mb->add_entities( coarseSet, quads );
// create all edges adjacent to quads
Range coarseEdges;
rval = mb->get_adjacencies( quads, 1, true, coarseEdges, Interface::UNION );ERRORR( rval, "can't create edges " );
mb->add_entities( coarseSet, coarseEdges );
// see how much we overestimated the number e_max
std::cout << " on rank " << rank << " e_max is " << e_max << " actual number of edges: " << coarseEdges.size()
<< "\n";
rval = pcomm->resolve_shared_ents( coarseSet, 2, 1 ); // resolve vertices and edges
ERRORR( rval, "can't resolve shared vertices and edges " );
mb->tag_set_data( partitionTag, &coarseSet, 1, &rank );
/* // do we have any edges?
Range edges;
mb->get_entities_by_dimension(0, 1, edges);
if (rank == 0)
std::cout << " number of edges after resolve share ents:" << edges.size()
<< "\n";*/
rval = mb->write_file( "coarse.h5m", 0, "PARALLEL=WRITE_PART", &coarseSet, 1 );ERRORR( rval, "can't write in parallel coarse mesh" );
// coarse mesh, from corners
return rval;
}
ErrorCode create_fine_mesh | ( | Interface * | mb, |
ParallelComm * | pcomm, | ||
EntityHandle | coarseSet, | ||
EntityHandle | fine_set, | ||
double * | coords, | ||
int | nc, | ||
int | nelem, | ||
EntityHandle | start_vert, | ||
int | numCornerVertices, | ||
std::vector< double * > & | coordv | ||
) |
Definition at line 473 of file wrap_intx.cpp.
References moab::Interface::add_entities(), moab::ParallelComm::assign_global_ids(), entities, ErrorCode, ERRORR, fill_coord_on_edges(), moab::ParallelComm::filter_pstatus(), moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::ReadUtilIface::get_element_connect(), moab::Interface::get_entities_by_dimension(), moab::Range::index(), mapping_to_coords, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_SPARSE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBQUAD, moab::ParallelMergeMesh::merge(), NC, numVertices, PARALLEL_PARTITION_TAG_NAME, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), PSTATUS_NOT, PSTATUS_NOT_OWNED, moab::Interface::query_interface(), moab::side_number(), moab::Interface::side_number(), moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::ReadUtilIface::update_adjacencies(), moab::Interface::write_file(), and moab::Interface::write_mesh().
Referenced by create_mesh().
{
int rank = pcomm->proc_config().proc_rank();
int stride = ( nc + 1 ) * ( nc + 1 ); // 16, for nc ==3
// there are stride*3 coordinates for each coarse quad, representing the fine mesh
Tag fineVertTag;
// will store the first refined vertex on an edge in a entity handle tag
EntityHandle def = 0;
ErrorCode rval =
mb->tag_get_handle( "__firstvertex", 1, MB_TYPE_HANDLE, fineVertTag, MB_TAG_DENSE | MB_TAG_CREAT, &def );ERRORR( rval, "can't get tag on first vertex" );
Range coarseQuads;
Range edges;
rval = mb->get_entities_by_dimension( coarseSet, 2, coarseQuads );ERRORR( rval, "can't get coarse quads " );
rval = mb->get_entities_by_dimension( coarseSet, 1, edges );ERRORR( rval, "can't get coarse edges " );
Range verts;
rval = mb->get_connectivity( coarseQuads, verts );ERRORR( rval, "can't get coarse vertices " );
/*std::cout <<" local coarse mesh on rank " << rank << " "<< coarseQuads.size() << " quads, "
<< edges.size() << " edges, " << verts.size() << " vertices.\n";*/
int dum_id = -1;
Tag partitionTag;
mb->tag_get_handle( PARALLEL_PARTITION_TAG_NAME, 1, MB_TYPE_INTEGER, partitionTag, MB_TAG_SPARSE | MB_TAG_CREAT,
&dum_id );
// fine mesh, with all coordinates
// std::vector coordv2;
ReadUtilIface* read_iface;
rval = mb->query_interface( read_iface );ERRORR( rval, "can't get query intf " );
;
// create verts, (nc+1)*(nc+1)*nelem - verts.size()
//
/* int numVertsOnEdges = (nc-1)*(int)edges.size();
int numExtraVerts = numVertsOnEdges + (nc-1)*(nc-1)*nelem; // internal fine vertices
rval = read_iface->get_node_coords(3, numExtraVerts, 0,
start_vert, coordv2);*/
// ERRORR(rval, "can't get coords fine mesh");
// fill coordinates for vertices on the edges, then vertices in the interior of coarse quads
// we know that all quads are in order, their index corresponds to index in coords array
rval =
fill_coord_on_edges( mb, coordv, coords, edges, start_vert, coarseQuads, nc, numCornerVertices, fineVertTag );ERRORR( rval, "can't fill edges vertex coords on fine mesh" );
EntityHandle start_elem, *connect;
rval = read_iface->get_element_connect( nelem * nc * nc, 4, MBQUAD, 0, start_elem, connect );ERRORR( rval, "can't create elements fine mesh" );
int iv = ( nc - 1 ) * edges.size() + numCornerVertices; // iv is in the coordv array indices
start_vert = start_vert + numCornerVertices + ( nc - 1 ) * edges.size();
/* // add a child to the mesh set, with the ordered vertices, as they come out in the list of
coordinates EntityHandle vertSet; rval = mb->create_meshset(MESHSET_ORDERED, vertSet);ERRORR(rval, "can't create
vertex set ");
rval = mb->add_parent_child(fine_set, vertSet);ERRORR(rval, "can't create parent child relation between fine set
and vertSet ");*/
std::vector< EntityHandle > vertList;
vertList.reserve( nelem * ( nc + 1 ) * ( nc + 1 ) ); // will have a list of vertices, in order
// now fill coordinates on interior nodes; also mark the start for each interior vertex
// in a coarse quad
for( int ie = 0; ie < nelem; ie++ )
{
// just fill coordinates for an array of (nc-1)*(nc-1) vertices
EntityHandle firstVert = start_vert + ( nc - 1 ) * ( nc - 1 ) * ie;
EntityHandle eh = coarseQuads[ie];
rval = mb->tag_set_data( fineVertTag, &eh, 1, &firstVert );ERRORR( rval, "can't set refined vertex tag" );
int index_coords = stride * ie;
for( int j = 1; j <= ( nc - 1 ); j++ )
{
for( int i = 1; i <= ( nc - 1 ); i++ )
{
int indx2 = 3 * ( index_coords + ( nc + 1 ) * j + i );
coordv[0][iv] = coords[indx2];
coordv[1][iv] = coords[indx2 + 1];
coordv[2][iv] = coords[indx2 + 2];
iv++;
}
}
}
Range quads3( start_elem, start_elem + nelem * nc * nc - 1 );
int ic = 0;
for( int ie = 0; ie < nelem; ie++ )
{
// just fill coordinates for an array of (nc-1)*(nc-1) vertices
EntityHandle arr2[NC + 1][NC + 1]; //
/*
* (nc,0) (nc,nc)
*
*
* (1,0) (1,nc)
* (0,0) (0,1) (0,nc)
*/
EntityHandle coarseQ = coarseQuads[ie];
const EntityHandle* conn4 = NULL;
int nnodes = 0;
rval = mb->get_connectivity( coarseQ, conn4, nnodes );ERRORR( rval, "can't get conn of coarse quad" );
if( nnodes != 4 ) return MB_FAILURE;
arr2[0][0] = conn4[0];
arr2[nc][0] = conn4[1];
arr2[nc][nc] = conn4[2];
arr2[0][nc] = conn4[3];
// get the coarse edges
std::vector< EntityHandle > aedges;
rval = mb->get_adjacencies( &coarseQ, 1, 1, false, aedges );ERRORR( rval, "can't get adje edges of coarse quad" );
assert( (int)aedges.size() == 4 );
for( int k = 0; k < 4; k++ )
{
EntityHandle edh = aedges[k];
/*
edges_index[0][j-1] = j; // for nc = 3: 1, 2
edges_index[1][j-1] = (j+1)*(nc+1) - 1; // 7, 11
edges_index[2][j-1] = (nc+1)*(nc+1) - j - 1; // 14, 13
edges_index[3][j-1] = (nc-j) * (nc+1) ; // 8, 4
*/
int sense = 0, side_number = -1, offset = -1;
rval = mb->side_number( coarseQ, edh, side_number, sense, offset );ERRORR( rval, "can't get side number" );
EntityHandle firstV; // first vertex on edge, if edge oriented positively
rval = mb->tag_get_data( fineVertTag, &edh, 1, &firstV );ERRORR( rval, "can't get first vertex tag on edge" );
if( sense > 0 )
{
if( 0 == side_number )
{
for( int i = 1; i <= nc - 1; i++ )
arr2[i][0] = firstV + i - 1;
}
else if( 1 == side_number )
{
for( int j = 1; j <= nc - 1; j++ )
arr2[nc][j] = firstV + j - 1;
}
else if( 2 == side_number )
{
for( int i = nc - 1; i >= 1; i-- )
arr2[i][nc] = firstV + nc - 1 - i;
}
else if( 3 == side_number )
{
for( int j = nc - 1; j >= 1; j-- )
arr2[0][j] = firstV + nc - 1 - j;
}
}
else // if (sense<0)
{
if( 0 == side_number )
{
for( int i = 1; i <= nc - 1; i++ )
arr2[i][0] = firstV + nc - 1 - i;
}
else if( 1 == side_number )
{
for( int j = 1; j <= nc - 1; j++ )
arr2[nc][j] = firstV + nc - 1 - j;
}
else if( 2 == side_number )
{
for( int i = nc - 1; i >= 1; i-- )
arr2[i][nc] = firstV + i - 1;
}
else if( 3 == side_number )
{
for( int j = nc - 1; j >= 1; j-- )
arr2[0][j] = firstV + j - 1;
}
}
}
// fill the interior points matrix
EntityHandle firstV; // first vertex on interior of coarse quad
rval = mb->tag_get_data( fineVertTag, &coarseQ, 1, &firstV );ERRORR( rval, "can't get first vertex tag on coarse tag" );
int inc = 0;
for( int j = 1; j <= nc - 1; j++ )
{
for( int i = 1; i <= nc - 1; i++ )
{
arr2[i][j] = firstV + inc;
inc++;
}
}
// fill now the matrix of quads; vertices are from 0 to (nc+1)*(nc+1)-1
for( int j1 = 0; j1 < nc; j1++ )
{
for( int i1 = 0; i1 < nc; i1++ )
{
connect[ic++] = arr2[i1][j1]; // first one
connect[ic++] = arr2[i1 + 1][j1]; //
connect[ic++] = arr2[i1 + 1][j1 + 1]; // opp diagonal
connect[ic++] = arr2[i1][j1 + 1]; //
}
}
for( int j1 = 0; j1 <= nc; j1++ )
{
for( int i1 = 0; i1 <= nc; i1++ )
{
vertList.push_back( arr2[i1][j1] );
}
}
}
/*
rval = mb->add_entities(vertSet, &vertList[0], (int)vertList.size());ERRORR(rval,"can't add to the vert set the
list of ordered vertices");*/
mb->add_entities( fine_set, quads3 );
// notify MOAB of the new elements
rval = read_iface->update_adjacencies( start_elem, nelem * nc * nc, 4, connect );ERRORR( rval, "can't update adjacencies on fine quads" );
rval = mb->tag_set_data( partitionTag, &fine_set, 1, &rank );ERRORR( rval, "can't set partition tag on fine set" );
/*
// delete the coarse mesh, except vertices
mb->delete_entities(coarseQuads);
mb->delete_entities(edges);
*/
// the vertices on the boundary edges of the partition need to be shared and resolved
ParallelMergeMesh pmerge( pcomm, 0.0001 );
rval = pmerge.merge();ERRORR( rval, "can't resolve vertices on interior of boundary edges " );
rval = mb->get_connectivity( quads3, verts );ERRORR( rval, "can't get vertices " );
Range owned_verts = verts;
rval = pcomm->filter_pstatus( owned_verts, PSTATUS_NOT_OWNED, PSTATUS_NOT );ERRORR( rval, "can't filter for owned vertices only" );
Range entities[4];
entities[0] = owned_verts;
entities[2] = quads3;
// assign new ids only for owned entities
// will eliminate gaps in global id space for vertices
rval = pcomm->assign_global_ids( entities, 2, 1, true, false );ERRORR( rval, "can't assign global ids for vertices " );
/*ErrorCode ParallelComm::assign_global_ids( Range entities[],
const int dimension,
const int start_id,
const bool parallel,
const bool owned_only) */
std::stringstream fff;
fff << "fine0" << pcomm->proc_config().proc_rank() << ".h5m";
mb->write_mesh( fff.str().c_str(), &fine_set, 1 );
rval = mb->write_file( "fine.h5m", 0, "PARALLEL=WRITE_PART", &fine_set, 1 );ERRORR( rval, "can't write set 3, fine " );
// we need to keep a mapping index, from the coords array to the vertex handles
// so, for a given vertex entity handle, at what index in the coords array the vertex
// coordinates are?
// in the coords array, vertices are repeated 2 times if they are interior to a coarse edge, and
// repeated 3 or 4 times if they are a corner vertex in a coarse quad
numVertices = (int)verts.size();
mapping_to_coords = new int[numVertices];
for( int k = 0; k < numVertices; k++ )
mapping_to_coords[k] = -1; // it means it was not located yet in vertList
// vertList is parallel to the coords and dep_coords array
// now loop over vertsList, and see where
// vertList has nelem * (nc+1)*(nc+1) vertices; loop over them, and see where are they located
for( int kk = 0; kk < (int)vertList.size(); kk++ )
{
EntityHandle v = vertList[kk];
int index = verts.index( v );
if( -1 == index )
{
std::cout << " can't locate vertex " << v << " in vertex Range \n";
return MB_FAILURE;
}
if( mapping_to_coords[index] == -1 ) // it means the vertex v was not yet encountered in the vertList
{
mapping_to_coords[index] = kk;
}
}
// check that every mapping has an index different from -1
for( int k = 0; k < numVertices; k++ )
{
if( mapping_to_coords[k] == -1 )
{
{
std::cout << " vertex at index " << k << " in vertex Range " << verts[k] << " is not mapped \n";
return MB_FAILURE; //
}
}
}
return rval;
}
void create_mesh | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle * | imesh_euler_set, | ||
iBase_EntitySetHandle * | imesh_departure_set, | ||
iBase_EntitySetHandle * | imesh_intx_set, | ||
double * | coords, | ||
int * | corners, | ||
int | nc, | ||
int | nelem, | ||
MPI_Fint | comm, | ||
int * | ierr | ||
) |
Definition at line 779 of file wrap_intx.cpp.
References create_coarse_mesh(), create_fine_mesh(), moab::Interface::create_meshset(), ErrorCode, ERRORV, gtol, MESHSET_SET, MOABI, pworker, and moab::Intx2Mesh::set_box_error().
Referenced by main(), PushParMeshIntoMoab(), run_test(), test_getEntArrAdj_conn(), test_getEntArrAdj_down(), test_getEntArrAdj_invalid_size(), test_getEntArrAdj_none(), test_getEntArrAdj_up(), and test_getEntArrAdj_vertex().
{
/* double * coords=(double*) icoords;
int * corners = (int*) icorners;*/
*ierr = 1;
Interface* mb = MOABI;
MPI_Comm mpicomm = MPI_Comm_f2c( comm );
// instantiate parallel comm now or not?
ParallelComm* pcomm = new ParallelComm( mb, mpicomm );
EntityHandle coarseSet;
ErrorCode rval = mb->create_meshset( MESHSET_SET, coarseSet );
ERRORV( rval, "can't create coarse set " );
EntityHandle start_vert;
int totalNumVertices;
int numCornerVertices;
std::vector< double* > coordv;
rval = create_coarse_mesh( mb, pcomm, coarseSet, coords, corners, nc, nelem, start_vert, totalNumVertices,
numCornerVertices, coordv );
ERRORV( rval, "can't create coarse set " );
EntityHandle fine_set;
rval = mb->create_meshset( MESHSET_SET, fine_set );
ERRORV( rval, "can't create fine set " );
rval = create_fine_mesh( mb, pcomm, coarseSet, fine_set, coords, nc, nelem, start_vert, numCornerVertices, coordv );
ERRORV( rval, "can't create fine mesh set " );
*imesh_departure_set = (iBase_EntitySetHandle)fine_set;
EntityHandle euler_set;
rval = mb->create_meshset( MESHSET_SET, euler_set );
ERRORV( rval, "can't create moab euler set " );
*imesh_euler_set = (iBase_EntitySetHandle)euler_set;
// call in Intx utils
// it will copy the second set from the first set
rval = deep_copy_set_with_quads( mb, fine_set, euler_set );
ERRORV( rval, "can't populate lagrange set " );
EntityHandle intx_set;
rval = mb->create_meshset( MESHSET_SET, intx_set );
ERRORV( rval, "can't create output set " );
*imesh_intx_set = (iBase_EntitySetHandle)intx_set;
pworker = new Intx2MeshOnSphere( mb );
pworker->set_box_error( 100 * gtol );
Range local_verts;
rval = pworker->build_processor_euler_boxes( euler_set,
local_verts ); // output also the local_verts
ERRORV( rval, "can't compute euler boxes " );
pworker->SetErrorTolerance( gtol );
*ierr = 0;
return;
}
ErrorCode fill_coord_on_edges | ( | Interface * | mb, |
std::vector< double * > & | coordv, | ||
double * | coords, | ||
Range & | edges, | ||
EntityHandle | start_v, | ||
Range & | coarseQuads, | ||
int | nc, | ||
int | numCornerVertices, | ||
Tag & | fineVertOnEdgeTag | ||
) |
Definition at line 373 of file wrap_intx.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, ERRORR, moab::Interface::get_adjacencies(), moab::Range::index(), MB_SUCCESS, NC, moab::side_number(), moab::Interface::side_number(), and moab::Interface::tag_set_data().
Referenced by create_fine_mesh().
{
ErrorCode rval = MB_SUCCESS;
double* coordv2[3];
for( int k = 0; k < 3; k++ )
coordv2[k] = coordv[k] + numCornerVertices; // they will start later
assert( NC == nc );
int edges_index[4][NC - 1]; // indices in the coords array for vertices, oriented positively
/*
* first j, then i, so this is the order of the points in coords array, now:
*
* nc(nc+1), ... (nc+1)*(nc+1)-1
*
* 2(nc+1),
* nc+1, nc+2, 2*(nc+1)-1
* 0, 1 , 2, ..........., nc
*/
// for first edge, oriented positive, the coords indices (*3) are 1, 2, (nc-1)
// second edge 2*(nc+1)-1, 3*(nc+1) -1, ...,
// nc*(nc+1)-1 third edge: (nc+1) * (nc+1) -2,
// ..., nc*(nc+1) +1 fourth edge: (nc-1)*(nc+1),
// ..., (nc+1)
for( int j = 1; j <= nc - 1; j++ )
{
edges_index[0][j - 1] = j; // for nc = 3: 1, 2
edges_index[1][j - 1] = ( j + 1 ) * ( nc + 1 ) - 1; // 7, 11
edges_index[2][j - 1] = ( nc + 1 ) * ( nc + 1 ) - j - 1; // 14, 13
edges_index[3][j - 1] = ( nc - j ) * ( nc + 1 ); // 8, 4
}
// int num_quads=(int)coarseQuads.size();
int stride = ( nc + 1 ) * ( nc + 1 );
int indexv = 0;
for( Range::iterator eit = edges.begin(); eit != edges.end(); ++eit )
{
EntityHandle edge = *eit;
std::vector< EntityHandle > faces;
rval = mb->get_adjacencies( &edge, 1, 2, false, faces );ERRORR( rval, "can't get adjacent faces." );
if( faces.size() < 1 ) return MB_FAILURE;
int sense = 0, side_number = -1, offset = -1;
EntityHandle quad = faces[0]; // just consider first quad
rval = mb->side_number( quad, edge, side_number, sense, offset );ERRORR( rval, "can't get side number" );
int indexq = coarseQuads.index( quad );
if( indexq == -1 ) return MB_FAILURE;
EntityHandle firstRefinedV = start_v + numCornerVertices + indexv;
rval = mb->tag_set_data( fineVertOnEdgeTag, &edge, 1, &firstRefinedV );ERRORR( rval, "can't set refined vertex tag" );
// copy the right coordinates from the coords array to coordv2 array
double* start_quad = &coords[3 * stride * indexq];
if( sense > 0 )
{
for( int k = 1; k <= nc - 1; k++ )
{
int index_in_quad = edges_index[side_number][k - 1] * 3;
coordv2[0][indexv] = start_quad[index_in_quad];
coordv2[1][indexv] = start_quad[index_in_quad + 1];
coordv2[2][indexv] = start_quad[index_in_quad + 2];
indexv++;
}
}
else
{
// sense < 0, so we will traverse the edge in inverse sense
for( int k = 1; k <= nc - 1; k++ )
{
int index_in_quad = edges_index[side_number][nc - 1 - k] * 3;
coordv2[0][indexv] = start_quad[index_in_quad];
coordv2[1][indexv] = start_quad[index_in_quad + 1];
coordv2[2][indexv] = start_quad[index_in_quad + 2];
indexv++;
}
}
}
return rval;
}
void initialize_area_and_tracer | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle | imesh_euler_set, | ||
double * | area_vals, | ||
int * | ierr | ||
) |
Definition at line 69 of file wrap_intx.cpp.
References ErrorCode, ERRORV, moab::Interface::get_entities_by_type(), mb, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MBQUAD, MOABI, moab::Range::size(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().
{
EntityHandle eul_set = (EntityHandle)imesh_euler_set;
moab::Interface* mb = MOABI;
*ierr = 1;
ErrorCode rval;
Range eulQuads;
rval = mb->get_entities_by_type( eul_set, MBQUAD, eulQuads );
ERRORV( rval, "can't get eulerian quads" );
// area of the euler element is fixed, store it; it is used to recompute the averages at each
// time step
Tag tagArea = 0;
std::string tag_name4( "Area" );
rval = mb->tag_get_handle( tag_name4.c_str(), 1, MB_TYPE_DOUBLE, tagArea, MB_TAG_DENSE | MB_TAG_CREAT );
ERRORV( rval, "can't get area tag" );
std::cout << " num quads = " << eulQuads.size() << "\n";
ERRORV( rval, "can't set area for each quad" );
rval = mb->tag_set_data( tagArea, eulQuads, &area_vals[0] );
*ierr = 0;
return;
}
void intersection_at_level | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle | fine_set, | ||
iBase_EntitySetHandle | lagr_set, | ||
iBase_EntitySetHandle | intx_set, | ||
double * | dep_coords, | ||
double | radius2, | ||
int * | ierr | ||
) |
Definition at line 880 of file wrap_intx.cpp.
References moab::Intx2Mesh::create_departure_mesh_3rd_alg(), moab::debug, ErrorCode, ERRORV, moab::ParallelComm::get_pcomm(), moab::Intx2Mesh::intersect_meshes(), MOABI, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), pworker, radius, set_departure_points_position(), and moab::Interface::write_mesh().
{
*ierr = 1;
Interface* mb = MOABI;
// MPI_Comm mpicomm = MPI_Comm_f2c(comm);
// instantiate parallel comm now or not?
EntityHandle lagrMeshSet = (EntityHandle)lagr_set;
ParallelComm* pcomm = ParallelComm::get_pcomm( mb, 0 );
if( NULL == pcomm ) return; // error is 1
// set the departure tag on the fine mesh vertices
ErrorCode rval = set_departure_points_position( mb, lagrMeshSet, dep_coords, radius2 );
ERRORV( rval, "can't set departure tag" );
if( debug )
{
std::stringstream fff;
fff << "lagr0" << pcomm->proc_config().proc_rank() << ".vtk";
rval = mb->write_mesh( fff.str().c_str(), &lagrMeshSet, 1 );
ERRORV( rval, "can't write covering set " );
}
// it should be done earlier
pworker->SetRadius( radius );
EntityHandle covering_set;
rval = pworker->create_departure_mesh_3rd_alg( lagrMeshSet, covering_set );
ERRORV( rval, "can't compute covering set " );
if( debug )
{
std::stringstream fff;
fff << "cover" << pcomm->proc_config().proc_rank() << ".vtk";
rval = mb->write_mesh( fff.str().c_str(), &covering_set, 1 );
ERRORV( rval, "can't write covering set " );
}
EntityHandle intxSet = (EntityHandle)intx_set;
rval = pworker->intersect_meshes( covering_set, (EntityHandle)fine_set, intxSet );
ERRORV( rval, "can't intersect " );
if( debug )
{
std::stringstream fff;
fff << "intx0" << pcomm->proc_config().proc_rank() << ".vtk";
rval = mb->write_mesh( fff.str().c_str(), &intxSet, 1 );
ERRORV( rval, "can't write covering set " );
}
return;
}
ErrorCode set_departure_points_position | ( | Interface * | mb, |
EntityHandle | lagrSet, | ||
double * | dep_coords, | ||
double | radius2 | ||
) |
Definition at line 847 of file wrap_intx.cpp.
References moab::CartVect::array(), ErrorCode, ERRORR, moab::Interface::get_connectivity(), moab::Interface::get_entities_by_type(), mapping_to_coords, MB_SUCCESS, MBQUAD, numVertices, moab::Interface::set_coords(), and moab::Range::size().
Referenced by intersection_at_level().
{
// the departure quads are created in the same order as the fine quads
// for each coarse element, there are nc*nc fine quads
// their vertices are in order
Range lagr_quads;
ErrorCode rval = mb->get_entities_by_type( lagrSet, MBQUAD, lagr_quads );ERRORR( rval, "can't get lagrange quads" );
// get all vertices from lagr_quads
Range lVerts;
rval = mb->get_connectivity( lagr_quads, lVerts );ERRORR( rval, "can't get lagrangian vertices (departure)" );
// they are parallel to the verts Array, they must have the same number of vertices
assert( numVertices == (int)lVerts.size() );
for( int i = 0; i < numVertices; i++ )
{
EntityHandle v = lVerts[i];
int index = mapping_to_coords[i];
assert( -1 != index );
SphereCoords sph;
sph.R = radius2;
sph.lat = dep_coords[2 * index];
sph.lon = dep_coords[2 * index + 1];
CartVect depPoint = spherical_to_cart( sph );
rval = mb->set_coords( &v, 1, (double*)depPoint.array() );ERRORR( rval, "can't set position of vertex" );
}
return MB_SUCCESS;
}
void update_tracer | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle | imesh_euler_set, | ||
int * | ierr | ||
) |
Definition at line 150 of file wrap_intx.cpp.
Referenced by advection(), and main().
{
using namespace moab;
const double radius = 1.;
const double gtol = 1.e-9;
const bool debug = false;
Range ents;
moab::Interface* mb = MOABI;
*ierr = 1;
EntityHandle euler_set = (EntityHandle)imesh_euler_set;
Intx2MeshOnSphere worker( mb );
worker.SetRadius( radius );
worker.SetErrorTolerance( gtol );
EntityHandle covering_lagr_set;
ErrorCode rval = mb->create_meshset( MESHSET_SET, covering_lagr_set );
ERRORV( rval, "can't create covering set " );
// we need to update the correlation tag and remote tuples
rval = worker.create_departure_mesh_2nd_alg( euler_set, covering_lagr_set );
ERRORV( rval, "can't populate covering set " );
if( debug )
{
rval = mb->write_file( "lagr.h5m", 0, 0, &covering_lagr_set, 1 );
ERRORV( rval, "can't write covering set " );
}
//
rval = enforce_convexity( mb, covering_lagr_set );
ERRORV( rval, "can't write covering set " );
EntityHandle outputSet;
rval = mb->create_meshset( MESHSET_SET, outputSet );
ERRORV( rval, "can't create output set " );
rval = worker.intersect_meshes( covering_lagr_set, euler_set, outputSet );
ERRORV( rval, "can't intersect " );
if( debug )
{
rval = mb->write_file( "output.vtk", 0, 0, &outputSet, 1 );
ERRORV( rval, "can't write covering set " );
}
// tagElem is the average computed at each element, from nodal values
Tag tagElem = 0;
std::string tag_name2( "TracerAverage" );
rval = mb->tag_get_handle( tag_name2.c_str(), 1, MB_TYPE_DOUBLE, tagElem, MB_TAG_DENSE | MB_TAG_CREAT );
ERRORV( rval, "can't get tracer tag " );
// area of the euler element is fixed, store it; it is used to recompute the averages at each
// time step
Tag tagArea = 0;
std::string tag_name4( "Area" );
rval = mb->tag_get_handle( tag_name4.c_str(), 1, MB_TYPE_DOUBLE, tagArea, MB_TAG_DENSE | MB_TAG_CREAT );
ERRORV( rval, "can't get area tag" );
rval = worker.update_tracer_data( outputSet, tagElem, tagArea );
ERRORV( rval, "can't update tracer " );
// everything can be deleted now from intx data; polygons, etc.
*ierr = 0;
return;
}
void update_tracer_test | ( | iMesh_Instance | instance, |
iBase_EntitySetHandle | imesh_euler_set, | ||
iBase_EntitySetHandle | imesh_output_set, | ||
int | numTracers, | ||
double * | tracer_vals, | ||
int * | ierr | ||
) |
Definition at line 102 of file wrap_intx.cpp.
References ErrorCode, ERRORV, moab::Interface::get_entities_by_type(), mb, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MBQUAD, MOABI, pworker, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Intx2MeshOnSphere::update_tracer_data().
{
EntityHandle eul_set = (EntityHandle)imesh_euler_set;
EntityHandle output_set = (EntityHandle)imesh_output_set;
moab::Interface* mb = MOABI;
*ierr = 1;
ErrorCode rval;
Range eulQuads;
rval = mb->get_entities_by_type( eul_set, MBQUAD, eulQuads );
ERRORV( rval, "can't get eulerian quads" );
// tagElem is the average computed at each element, from nodal values
Tag tagElem = 0;
std::string tag_name2( "TracerAverage" );
rval = mb->tag_get_handle( tag_name2.c_str(), numTracers, MB_TYPE_DOUBLE, tagElem, MB_TAG_DENSE | MB_TAG_CREAT );
ERRORV( rval, "can't get tracer tag " );
// area of the euler element is fixed, store it; it is used to recompute the averages at each
// time step
Tag tagArea = 0;
std::string tag_name4( "Area" );
rval = mb->tag_get_handle( tag_name4.c_str(), 1, MB_TYPE_DOUBLE, tagArea, MB_TAG_DENSE | MB_TAG_CREAT );
ERRORV( rval, "can't get area tag" );
std::cout << " num quads = " << eulQuads.size() << "\n";
rval = mb->tag_set_data( tagElem, eulQuads, &tracer_vals[0] );
ERRORV( rval, "can't set tracer data" );
rval = pworker->update_tracer_data( output_set, tagElem, tagArea );
ERRORV( rval, "can't update tracer " );
rval = mb->tag_get_data( tagElem, eulQuads, &tracer_vals[0] );
ERRORV( rval, "can't get tracer data" );
*ierr = 0;
return;
}
bool debug = false [static] |
Definition at line 28 of file wrap_intx.cpp.
double gtol = 1.e-9 [static] |
Definition at line 27 of file wrap_intx.cpp.
Referenced by create_mesh(), main(), and update_tracer().
int* mapping_to_coords = NULL [static] |
Definition at line 41 of file wrap_intx.cpp.
Referenced by cleanup_after_simulation(), create_fine_mesh(), and set_departure_points_position().
int numVertices = 0 [static] |
Definition at line 42 of file wrap_intx.cpp.
Referenced by cleanup_after_simulation(), create_fine_mesh(), and set_departure_points_position().
Intx2MeshOnSphere* pworker = NULL [static] |
Definition at line 45 of file wrap_intx.cpp.
Referenced by create_mesh(), intersection_at_level(), and update_tracer_test().
double radius = 1. [static] |
Definition at line 26 of file wrap_intx.cpp.
Referenced by add_field_value(), compute_tracer_case1(), get_departure_grid(), moab::Coupler::initialize_tree(), intersection_at_level(), main(), manufacture_lagrange_mesh_on_sphere(), moab::IntxRllCssphere::set_radius(), moab::Intx2MeshOnSphere::set_radius_destination_mesh(), moab::Intx2MeshOnSphere::set_radius_source_mesh(), moab::OrientedBoxTreeTool::sphere_intersect_triangles(), update_tracer(), and moab::Intx2MeshOnSphere::update_tracer_data().