@@ -62,7 +62,8 @@ Mesh::Mesh() : MeshDB(), FieldReg(), CommReg(),
6262 sghost (NULL ),
6363 committed (false),
6464 is_split (false),
65- has_orig_info (false),
65+ has_orig_elem_nodes (false),
66+ has_orig_elem_area (false),
6667 origElemConnCount (-1 ),
6768 ind (-1 ), side (-1 ),
6869 orig_comm (MPI_COMM_NULL )
@@ -2294,5 +2295,177 @@ void Mesh::resolve_cspec_delete_owners(UInt obj_type) {
22942295 orig_comm = new_comm ;
22952296 }
22962297
2298+ // Records the set of original nodes used for this element
2299+ // Note that this copies the input vector, so the same vector can be used repreatedly
2300+ // TODO: eventually the mesh should just be created using these
2301+ void Mesh ::setOrigElemNodes (UInt elem_id , std ::vector < MeshObj * > & nodes ) {
2302+
2303+ // Only record >4 sided, because the others can be retrieved from the mesh
2304+ if (nodes .size () > 4 ) {
2305+
2306+ // Add new vector of size 0
2307+ auto emplace_out = orig_id_to_conn .emplace (elem_id ,0 );
2308+
2309+ // If it wasn't added, then throw an error
2310+ if (!emplace_out .second ) Throw () << "elem with id=" ,elem_id ," could not be added because of an error (e.g. it is a duplicate of a previous id)." ;
2311+
2312+ // Get reference to new vector
2313+ std ::vector < MeshObj * > & conn_vec = emplace_out .first -> second ;
2314+
2315+ // Set to input vector
2316+ conn_vec = nodes ;
2317+ }
2318+ }
2319+
2320+
2321+ // Gets the original element node count (even if the mesh is split)
2322+ int Mesh ::getOrigElemNodesCount (MeshObj * elem ) {
2323+
2324+ // Error if split and we haven't recorded original elem conn.
2325+ if (is_split && !has_orig_elem_nodes ) Throw () << "Original element connection information has not been set in this Mesh." ;
2326+
2327+ // Get information depending on split status
2328+ if (is_split ) {
2329+
2330+ // Look for element id in map
2331+ auto oitc = orig_id_to_conn .find (elem -> get_id ());
2332+
2333+ // If it's not there use the usual method
2334+ if (oitc == orig_id_to_conn .end ()) {
2335+
2336+ // Get topology of elem
2337+ const ESMCI ::MeshObjTopo * topo = ESMCI ::GetMeshObjTopo (* elem );
2338+
2339+ // Return the number of nodes
2340+ return topo -> num_nodes ;
2341+
2342+ } else { // If it is get info from vec
2343+
2344+ // Get reference to conn vector
2345+ std ::vector < MeshObj * > & conn_vec = oitc -> second ;
2346+
2347+ // Return size
2348+ return conn_vec .size ();
2349+ }
2350+
2351+ } else {
2352+ // Get topology of elem
2353+ const ESMCI ::MeshObjTopo * topo = ESMCI ::GetMeshObjTopo (* elem );
2354+
2355+ // Return the number of nodes
2356+ return topo -> num_nodes ;
2357+ }
2358+
2359+ }
2360+
2361+
2362+ // Copies the nodes attached to the original element into a vector
2363+ // The nodes are put into the vector in the order that they were originally specified (e.g. first node is first).
2364+ void Mesh ::getOrigElemNodes (MeshObj * elem , std ::vector < MeshObj * > & nodes ) {
2365+
2366+ // Clear input vector
2367+ nodes .clear ();
2368+
2369+ // Error if split and we haven't recorded original elem conn.
2370+ if (is_split && !has_orig_elem_nodes ) Throw () << "Original element connection information has not been set in this Mesh." ;
2371+
2372+ // Get information depending on split status
2373+ if (is_split ) {
2374+
2375+ // Look for element id in map
2376+ auto oitc = orig_id_to_conn .find (elem -> get_id ());
2377+
2378+ // If it's not there use the usual method
2379+ if (oitc == orig_id_to_conn .end ()) {
2380+
2381+ // Get topology of elem
2382+ const ESMCI ::MeshObjTopo * topo = ESMCI ::GetMeshObjTopo (* elem );
2383+
2384+ // Reserve space
2385+ nodes .reserve (topo -> num_nodes );
2386+
2387+ // Loop getting the indices of the nodes surrouding elem
2388+ for (int n = 0 ; n < topo -> num_nodes ; n ++ ){
2389+ MeshObj * node = elem -> Relations [n ].obj ;
2390+ nodes .push_back (node );
2391+ }
2392+
2393+ } else { // If it is get info from vec
2394+
2395+ // Get reference to conn vector
2396+ std ::vector < MeshObj * > & conn_vec = oitc -> second ;
2397+
2398+ // Set return vector
2399+ nodes = conn_vec ;
2400+ }
2401+
2402+ } else {
2403+
2404+ // Get topology of elem
2405+ const ESMCI ::MeshObjTopo * topo = ESMCI ::GetMeshObjTopo (* elem );
2406+
2407+ // Reserve space
2408+ nodes .reserve (topo -> num_nodes );
2409+
2410+ // Loop getting the indices of the nodes surrouding elem
2411+ for (int n = 0 ; n < topo -> num_nodes ; n ++ ){
2412+ MeshObj * node = elem -> Relations [n ].obj ;
2413+ nodes .push_back (node );
2414+ }
2415+ }
2416+ }
2417+
2418+ // Records the original area for the element
2419+ void Mesh ::setOrigElemArea (UInt elem_id , double area ) {
2420+
2421+ // Add new entry with area
2422+ auto emplace_out = orig_id_to_area .emplace (elem_id , area );
2423+
2424+ // If it wasn't added, then throw an error
2425+ if (!emplace_out .second ) Throw () << "elem with id=" ,elem_id ," could not be added because of an error (e.g. it is a duplicate of a previous id)." ;
2426+
2427+ }
2428+
2429+ // Gets the original element area (even if the mesh is split)
2430+ double Mesh ::getOrigElemArea (MeshObj * elem ) {
2431+
2432+ // Get element area field
2433+ MEField < > * elem_area = GetField ("elem_area" );
2434+
2435+ // Error if elements don't have areas
2436+ if (!elem_area ) Throw () << "Element area information has not been set in this Mesh." ;
2437+
2438+ // Error if split and we haven't recorded original elem area
2439+ if (is_split && !has_orig_elem_area ) Throw () << "Original element area information has not been set in this Mesh." ;
2440+
2441+ // Get information depending on split status
2442+ if (is_split ) {
2443+
2444+ // Look for element id in map
2445+ auto oita = orig_id_to_area .find (elem -> get_id ());
2446+
2447+ // If it's not there use the usual method
2448+ if (oita == orig_id_to_area .end ()) {
2449+
2450+ // Return the element's area
2451+ return elem_area -> data (* elem );
2452+
2453+ } else { // If it is get info from map
2454+
2455+ // Return area from map
2456+ return oita -> second ;
2457+ }
2458+
2459+ } else {
2460+
2461+ // Return the element's area
2462+ return elem_area -> data (* elem );
2463+ }
2464+
2465+ }
2466+
2467+
2468+
2469+
22972470
22982471} // namespace
0 commit comments