//---------------------------------------------------------------------------- // // Random fracture criterion function. // bool RandomCriterion::computeFractureCriterion(stk_classic::mesh::Entity& entity, double p) { // Fracture only defined on the boundary of the elements stk_classic::mesh::EntityRank rank = entity.entity_rank(); assert(rank == num_dim_ - 1); stk_classic::mesh::PairIterRelation neighbor_elems = entity.relations(element_rank_); // Need an element on each side if(neighbor_elems.size() != 2) return false; bool is_open = false; // All we need to do is generate a number between 0 and 1 double random = 0.5 + 0.5 * Teuchos::ScalarTraits<double>::random(); if(random < p) { is_open = true; } return is_open; }
void TestLocalRefiner:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } // iSubDimOrd } // ineed_ent }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> tri_tuple_type; static vector<tri_tuple_type> elems(6); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //stk_classic::mesh::Part & active = mesh->ActivePart(); //stk_classic::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; //add_parts.push_back( &active ); //FIXME //add_parts.push_back( const_cast<mesh::Part*>( eMesh.getPart(m_toTopoPartName) )); add_parts = m_toParts; /** \node[above] at (p4.side 1){2}; \node[left] at (p4.side 2){3}; \node[below] at (p4.side 3){0}; \node[right] at (p4.side 4){1}; */ double tmp_x[3]; for (int iedge = 0; iedge < 4; iedge++) { double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), tmp_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 << " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } elems[0] = tri_tuple_type(VERT_N(0), EDGE_N(0), EDGE_N(3)); elems[1] = tri_tuple_type(VERT_N(1), EDGE_N(1), EDGE_N(0)); elems[2] = tri_tuple_type(EDGE_N(0), EDGE_N(1), EDGE_N(3)); elems[3] = tri_tuple_type(VERT_N(2), EDGE_N(2), EDGE_N(1)); elems[4] = tri_tuple_type(VERT_N(3), EDGE_N(3), EDGE_N(2)); elems[5] = tri_tuple_type(EDGE_N(2), EDGE_N(3), EDGE_N(1)); // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); stk_classic::mesh::Entity& newElement = *(*element_pool); if (proc_rank_field) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> tri_tuple_type; static vector<tri_tuple_type> elems(4); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //stk_classic::mesh::Part & active = mesh->ActivePart(); //stk_classic::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; add_parts = m_toParts; //std::cout << "P["<< m_eMesh.get_rank() << "] add_parts = " << add_parts << std::endl; stk_classic::mesh::EntityRank my_rank = m_primaryEntityRank; nodeRegistry.makeCentroidCoords(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); nodeRegistry.addToExistingParts(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); nodeRegistry.interpolateFields(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); #define CENTROID_N NN(m_primaryEntityRank, 0) elems[0] = tri_tuple_type(VERT_N(0), VERT_N(1), CENTROID_N); elems[1] = tri_tuple_type(VERT_N(1), VERT_N(2), CENTROID_N); elems[2] = tri_tuple_type(VERT_N(2), VERT_N(3), CENTROID_N); elems[3] = tri_tuple_type(VERT_N(3), VERT_N(0), CENTROID_N); #undef CENTROID_N // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM /** \node[above] at (p4.side 1){2}; \node[left] at (p4.side 2){3}; \node[below] at (p4.side 3){0}; \node[right] at (p4.side 4){1}; */ #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk_classic::mesh::Entity& newElement = *(*element_pool); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 3 " << proc_rank_field << std::endl; if (proc_rank_field && element.entity_rank() == m_eMesh.element_rank()) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); fdata[0] = double(newElement.owner_rank()); } //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 4 " << std::endl; change_entity_parts(eMesh, element, newElement); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 5 " << std::endl; { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 6 " << std::endl; eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 7 " << std::endl; set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> line_tuple_type; static vector<line_tuple_type> elems(2); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; add_parts = m_toParts; double coord_x[3]; for (int iedge = 0; iedge < 1; iedge++) { //double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); //double * mp = midPoint(FACE_COORD(iedge,0), FACE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); double * mp = midPoint(VERT_COORD(0), VERT_COORD(1), eMesh.get_spatial_dim(), coord_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } // FIXME nodeRegistry.makeCentroidCoords(*const_cast<stk_classic::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.addToExistingParts(*const_cast<stk_classic::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.interpolateFields(*const_cast<stk_classic::mesh::Entity *>(&element), m_primaryEntityRank, 0u); Elem::CellTopology elem_celltopo = Elem::getCellTopology< FromTopology >(); const Elem::RefinementTopology* ref_topo_p = Elem::getRefinementTopology(elem_celltopo); const Elem::RefinementTopology& ref_topo = *ref_topo_p; #ifndef NDEBUG unsigned num_child = ref_topo.num_child(); VERIFY_OP(num_child, == , 2, "createNewElements num_child problem"); bool homogeneous_child = ref_topo.homogeneous_child(); VERIFY_OP(homogeneous_child, ==, true, "createNewElements homogeneous_child"); #endif // new_sub_entity_nodes[i][j] //const UInt * const * child_nodes() const { //const UInt * child_node_0 = ref_topo.child_node(0); typedef Elem::StdMeshObjTopologies::RefTopoX RefTopoX; RefTopoX& l2 = Elem::StdMeshObjTopologies::RefinementTopologyExtra< FromTopology > ::refinement_topology; #define CENTROID_N NN(m_primaryEntityRank,0) for (unsigned iChild = 0; iChild < 2; iChild++) { unsigned EN[2]; for (unsigned jNode = 0; jNode < 2; jNode++) { unsigned childNodeIdx = ref_topo.child_node(iChild)[jNode]; #ifndef NDEBUG unsigned childNodeIdxCheck = l2[childNodeIdx].ordinal_of_node; VERIFY_OP(childNodeIdx, ==, childNodeIdxCheck, "childNodeIdxCheck"); #endif unsigned inode=0; if (l2[childNodeIdx].rank_of_subcell == 0) inode = VERT_N(l2[childNodeIdx].ordinal_of_subcell); else if (l2[childNodeIdx].rank_of_subcell == 1) inode = EDGE_N(l2[childNodeIdx].ordinal_of_subcell); // else if (l2[childNodeIdx].rank_of_subcell == 2) // inode = CENTROID_N; EN[jNode] = inode; } elems[iChild] = line_tuple_type(EN[0], EN[1]); } #undef CENTROID_N // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk_classic::mesh::Entity& newElement = *(*element_pool); #if 0 if (proc_rank_field && proc_rank_field->rank() == m_eMesh.edge_rank()) //&& m_eMesh.get_spatial_dim()==1) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } #endif stk_classic::mesh::FieldBase * proc_rank_field_edge = m_eMesh.get_field("proc_rank_edge"); if (proc_rank_field_edge) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field_edge) , newElement ); fdata[0] = double(newElement.owner_rank()); //fdata[0] = 1234.56; if (0) std::cout << "P[" << m_eMesh.get_rank() << "] tmp set proc_rank_field_edge to value = " << newElement.owner_rank() << " for side element = " << newElement.identifier() << std::endl; } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void TestLocalRefinerTri2:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } // see how many edges are already marked int num_marked=0; if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) ++num_marked; } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) if (needed_entity_rank == m_eMesh.edge_rank()) { stk_classic::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk_classic::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk_classic::mesh::field_data( *coordField , node0 ); double * const coord1 = stk_classic::mesh::field_data( *coordField , node1 ); // only refine diagonals of the split quads if (m_diagonals) { if ( std::abs(coord0[0]-coord1[0]) > 1.e-3 && std::abs(coord0[1]-coord1[1]) > 1.e-3 ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } else { if ( std::abs(coord0[0]-coord1[0]) < 1.e-3 && std::abs(coord0[1]-coord1[1]) > 1.e-3 ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } } } // iSubDimOrd } // ineed_ent }
void TestLocalRefinerTet_N_3_1:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { //static int n_seq = 400; const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } // see how many edges are already marked int num_marked=0; if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) ++num_marked; } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) if (needed_entity_rank == m_eMesh.edge_rank()) { #if 0 stk_classic::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk_classic::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk_classic::mesh::field_data( *coordField , node0 ); double * const coord1 = stk_classic::mesh::field_data( *coordField , node1 ); // vertical line position const double vx = 0.21; // horizontal line position const double vy = 1.21; // choose to refine or not if ( ( std::fabs(coord0[0]-coord1[0]) > 1.e-3 && ( (coord0[0] < vx && vx < coord1[0]) || (coord1[0] < vx && vx < coord0[0]) ) ) || ( std::fabs(coord0[1]-coord1[1]) > 1.e-3 && ( (coord0[1] < vy && vy < coord1[1]) || (coord1[1] < vy && vy < coord0[1]) ) ) ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } #endif // mark only the first element if ( ((1 << iSubDimOrd) & m_edge_mark_bitcode ) && 1 == element.identifier() ) { if (1) { std::cout << "tmp TestLocalRefinerTet_N_3_1 element.identifier() = " << element.identifier() << " edge_mark_bitcode = " << m_edge_mark_bitcode << " iSubDimOrd= " << iSubDimOrd << std::endl; } (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } } // iSubDimOrd } // ineed_ent }
bool helperSubDim(const stk_classic::mesh::Entity& child_element, stk_classic::mesh::FieldBase *field, const mesh::BulkData& bulkData) { EXCEPTWATCH; const CellTopologyData * const child_cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(child_element); CellTopology child_cell_topo(child_cell_topo_data); int child_cell_dimension = child_cell_topo.getDimension(); int meta_dimension = mesh::fem::FEMMetaData::get_meta_data(mesh::fem::FEMMetaData::get(bulkData)).get_spatial_dimension(); // for now, only allow face (or edge) VERIFY_OP_ON(child_cell_dimension, ==, meta_dimension - 1, "Dimensions don't match"); VectorFieldType& coord_field = *(mesh::fem::FEMMetaData::get(bulkData)).get_field<VectorFieldType>("coordinates"); // FIXME for fields not on a Node unsigned nDOF = m_nDOFs; unsigned nCells = PerceptMesh::size1(child_element); m_count_elems += nCells; typedef IntrepidManager IM; unsigned cubDegree = m_cubDegree; const stk_classic::mesh::PairIterRelation parent_elements = child_element.relations(child_element.entity_rank() + 1); VERIFY_OP_ON(parent_elements.size(), ==, 1, "cant find parent"); const stk_classic::mesh::Entity& element = *parent_elements[0].entity(); unsigned i_face = parent_elements[0].identifier(); const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); int cell_dimension = cell_topo.getDimension(); VERIFY_OP_ON(cell_dimension, ==, meta_dimension , "Dimensions don't match"); IM im(Elements_Tag(nCells), cell_topo, cubDegree); IM imChild(Elements_Tag(nCells), child_cell_topo, cubDegree); unsigned numCubPoints_child = imChild.m_cub->getNumPoints(); im.m_Cub_Points_Tag = Cub_Points_Tag(numCubPoints_child); if (0) { std::cout << "numCubPoints_child= " << numCubPoints_child << " parent rank= " << element.entity_rank() << " parent topo= " << cell_topo.getName() << std::endl; } // FIXME im.m_DOFs_Tag.num = m_nDOFs; // FIXME // _c suffix is for the child (face) element IM::Jacobian J (im); IM::FaceNormal fn (im); //IM::JacobianDet dJ (im); IM::CubaturePoints xi (im); IM::CubaturePoints xi_c (imChild); IM::CellWorkSet cn (im); IM::CubatureWeights wt (im); IM::CubatureWeights wt_c (imChild); IM::PhysicalCoords pc (im); IM::IntegrandValues iv (im); IM::IntegrandValuesDOF ivD (im); IM::Integral Io (im); IM::Bases Nb (im); IM::WeightedMeasure wXfn (im); IM::FieldValues fv (im); imChild.m_cub->getCubature(xi_c, wt_c); unsigned spaceDim = im.m_Spatial_Dim_Tag.num; PerceptMesh::fillCellNodes(element, &coord_field, cn, spaceDim); // get parent cell integration points // Map Gauss points on quad to reference face: paramGaussPoints -> refGaussPoints Intrepid::CellTools<double>::mapToReferenceSubcell(xi, xi_c, 2, i_face, cell_topo); // FIXME magic // get jacobian J(xi, cn, cell_topo); //dJ(J); //shards::ArrayVector<double, shards::NaturalOrder, Elements_Tag, Cub_Points_Tag > fn_Norm; // FIXME //fn(J, i_face, cell_topo); MDArray J_mda; J.copyTo(J_mda); MDArray fn_mda(im.m_Elements_Tag.num, numCubPoints_child, spaceDim); Intrepid::CellTools<double>::getPhysicalFaceNormals(fn_mda, J_mda, i_face, cell_topo); /// get norm of fn for (int icell = 0; icell < im.m_Elements_Tag.num; icell++) { for (int ipt = 0; ipt < (int)numCubPoints_child; ipt++) { double sum = 0.0; for (int i = 0; i < (int)spaceDim; i++) { sum += square(fn_mda(icell, ipt, i)); } wXfn(icell, ipt) = std::sqrt(sum) * wt_c(ipt); } } if (0) { using namespace shards; //std::cout << "dJ= \n" << dJ << std::endl; std::cout << "wXfn= \n" << wXfn << std::endl; std::cout << "xi= \n" << xi << std::endl; std::cout << "wt= \n" << wt << std::endl; std::cout << "cn= \n" << cn << std::endl; Util::setDoPause(true); Util::pause(true); } // get physical coordinates at integration points pc(cn, xi); // get bases #if 1 // FIXME MDArray xi_mda; xi.copyTo(xi_mda); Nb(element, xi_mda); #else Nb(element, xi); #endif // apply integrand (right now we have MDArray hard-coded... FIXME - templatize on its type) // it should look like this (one instead of multiple lines): #if 0 m_integrand(pc, v); #else MDArray pc_mda; pc.copyTo(pc_mda); std::vector<int> ivDims; ivD.dimensions( ivDims); /// NOTE: m_integrand requires the ranks of in/out MDArrays to be such that out_rank >= in_rank /// Thus, we use IntegrandValuesDOF with [DOF] = 1, and then copy the result to IntegrandValues /// which does not have the additional rightmost DOF index (Intrepid doesn't have the concept of /// DOF's, it works on scalars only for the integration routines, or at least that's how I understand /// it currently. // create an array that stk_classic::percept::Function will like to hold the results ivDims[ivDims.size()-1] = m_nDOFs; MDArray iv_mda ( Teuchos::Array<int>(ivDims.begin(), ivDims.end())); if (m_turboOpt == TURBO_ELEMENT || m_turboOpt == TURBO_BUCKET) { m_integrand(pc_mda, iv_mda, element, xi_mda); } else { m_integrand(pc_mda, iv_mda); } // now, copy from the results to an array that Intrepid::integrate will like #endif for (unsigned iDof = 0; iDof < nDOF; iDof++) { iv.copyFrom(im, iv_mda, iDof); // get the integral if (m_accumulation_type == ACCUMULATE_SUM) { Io(iv, wXfn, Intrepid::COMP_BLAS); } //optional design: // // Io(integrand(pc_mda, v), wXdJ(w, dJ(J(xi, c, cell_topo)), Intrepid::COMP_BLAS); for (unsigned iCell = 0; iCell < nCells; iCell++) { // if (Util::getFlag(0)) // { // std::cout << "tmp Io(iCell)= " << Io(iCell) << std::endl; // Util::pause(true, "Io(iCell)"); // } if (m_accumulation_type == ACCUMULATE_SUM) { m_accumulation_buffer[iDof] += Io(iCell); } else if (m_accumulation_type == ACCUMULATE_MAX) { double valIo = 0.0; for (int ivpts = 0; ivpts < iv.dimension(1); ivpts++) { valIo = std::max(valIo, iv((int)iCell, ivpts)); } //std::cout << "m_accumulation_buffer[iDof] = " << m_accumulation_buffer[iDof] << " valIO= " << valIo << std::endl; m_accumulation_buffer[iDof] = std::max(m_accumulation_buffer[iDof], valIo); } } } return false; }